/*
* Transform - jQuery Plugin
*
* 
* Copyright (c) - author: Gabriel Tavares de Souza
*
* Version: 1.2.0 (18/10/2010)
* Requires: jQuery v1.3+
*/
/* TODO: preLoad css background { hover/focus/pressed/disabled/checked } */
/* TODO: Test transformExternalKeyPressed */
/* TODO: Optimize transformExternalKeyPressed */
/* Publiabril - Special Modify | ($input.attr('id') == 'captcha') */

(function($) {	
	$.fn.transform = function(method) {
		var opts = (methods[method]) ? ($.extend({}, $.fn.transform.defaults, Array.prototype.slice.call( arguments, 1 ))) : ($.extend({}, $.fn.transform.defaults, method));
		
		$(document).unbind('mousedown.transform').unbind('keydown.transform').bind('mousedown.transform', methods.transformExternalClick).bind('keydown.transform', methods.transformExternalKeyPressed);

		/* TODO: IE6 Enter Pressed Bug -> transformExternalKeyPressed */
		if($.browser.msie && ($.browser.version < 7)){ $(document).unbind('keydown.transform'); }
		
		if (methods[method]) {
			return methods[ method ].apply($(this), [opts]);
		} else if ( typeof method === 'object' || ! method ) {
			return $(this).each(function() {
				var $this = $(this);
				var o = [$.metadata ? $.extend({}, opts, $(this).metadata()) : opts];

				if($this.is('label')){
					methods.transformLabel.apply($this);
				} else if($this.is('input:text, input:password')){
					methods.transformInputText.apply($this);
				} else if($this.is('textarea')){
					methods.transformTextArea.apply($this);
				} else if($this.is('input:submit, input:button, input:reset')){
					//methods.transformInputButton.apply($this);
				} else if($this.is('select')){
					methods.transformSelect.apply($this);
				} else if($this.is('input:checkbox')){
					methods.transformInputCheckbox.apply($this);
				} else if($this.is('input:radio')){
					methods.transformInputRadio.apply($this);
				} else {
					/* Transform All */
					methods.transformLabel.apply($('label', $this), o);
					methods.transformInputText.apply($('input:text, input:password', $this), o);
					methods.transformTextArea.apply($('textarea', $this), o);
					//methods.transformInputButton.apply($('input:submit, input:button, input:reset', $this), o);
					methods.transformSelect.apply($('select', $this), o);
					methods.transformInputCheckbox.apply($('input:checkbox', $this), o);
					methods.transformInputRadio.apply($('input:radio', $this), o);
				}

				$this.unbind('reset.transform').bind('reset.transform',function(){
					methods.transformReset.apply($this, o);
				});
			});	
		} else {
			$.error( 'Method ' +  method + ' does not exist on jQuery.transform' );
		}
	};
	
	/* TODO: Apply Settings */
	$.fn.transform.defaults = {
		skin : 'default',
		compare : true,
		preLoad : false
	};
		
	var methods = {
		transformLabel : function(options) {
			return $(this).each(function(){
				var $label = $(this);

				if((!$label.is('label')) || ($label.hasClass('transform'))){ return; }

				$label.addClass('transform');

				/* Hover */
				$label.hover(function(){
					$label.addClass('labelHover');
				}, function(){
					$label.removeClass('labelHover');
				});

				/* Click IE Fix */
				if($.browser.msie){
					$label.click(function(){
						$('input[id="' + $label.attr('for') + '"]')[0].click();
					});
				}
			});
		},
		transformInputText : function(options) {
			return $(this).each(function(){
				var $input = $(this);
				var _left	= '<div class="inputTextLeft"></div>';
				var _right	= '<div class="inputTextRight"></div>';
				var _clear	= '<div class="inputClear"></div>';

				if((!$input.is('input:text, input:password')) || ($input.parent().parent().hasClass('transform')) || ($input.attr('id') == 'captcha')){ return; }

				/* Safari Fix */
				if($.browser.webkit){ $input.addClass('inputTextSafari'); }

				var $transform = $input.wrap('<div class="transform"><div class="inputTextCenter"></div></div>').parent().parent().prepend(_left).append(_right, _clear);
				$transform.width($('.inputTextLeft', $transform).outerWidth() + $('.inputTextCenter', $transform).outerWidth() + $('.inputTextRight', $transform).outerWidth());

				/* Disabled */
				if($('.inputTextCenter input', $transform).is(':disabled')){
					$('.inputTextLeft, .inputTextCenter, .inputTextRight', $transform).addClass('inputTextDisabled');
				}

				/* Hover */
				$transform.hover(function() {
					if(!$('.inputTextLeft, .inputTextCenter, .inputTextRight', $transform).hasClass('inputTextFocus') && !$('.inputTextLeft, .inputTextCenter, .inputTextRight', $transform).hasClass('inputTextDisabled')) {
						$('.inputTextLeft, .inputTextCenter, .inputTextRight', $transform).addClass('inputTextHover');
					}
				},function() {
					$('.inputTextLeft, .inputTextCenter, .inputTextRight', $transform).removeClass('inputTextHover');					
				});

				/* Input Focus / Blur */
				$('.inputTextCenter input', $transform).focus(function() {
					$('.inputTextLeft, .inputTextCenter, .inputTextRight', $transform).removeClass('inputTextHover').addClass('inputTextFocus');
				}).blur(function() {
					$('.inputTextLeft, .inputTextCenter, .inputTextRight', $transform).removeClass('inputTextFocus');
				});
			});
		},
		transformTextArea : function(options) { 
			return $(this).each(function() {
				/* TODO: transform for TextArea */
			});
		},
		transformInputButton : function(options) {
			return $(this).each(function() {
				var $input = $(this);
				var _left	= '<div class="inputButtonLeft"></div>';
				var _right	= '<div class="inputButtonRight"></div>';
				var _clear	= '<div class="inputClear"></div>';

				if((!$input.is('input:submit, input:button, input:reset')) || ($input.parent().parent().hasClass('transform'))) { return; }

				var $transform = $input.wrap('<div class="transform"><div class="inputButtonCenter">' + $input.val() + '</div></div>').parent().parent().prepend(_left).append(_right, _clear);
				$transform.width($('.inputButtonLeft', $transform).outerWidth() + $('.inputButtonCenter', $transform).outerWidth() + $('.inputButtonRight', $transform).outerWidth() + 2);

				/* Disabled */
				if($('.inputButtonCenter input', $transform).is(':disabled')) {
					$('.inputButtonLeft, .inputButtonCenter, .inputButtonRight', $transform).addClass('inputButtonDisabled');
				}

				/* Hover */
				$transform.hover(function() {
					if(!$('.inputButtonLeft, .inputButtonCenter, .inputButtonRight', $transform).hasClass('inputButtonPressed') && !$('.inputButtonLeft, .inputButtonCenter, .inputButtonRight', $transform).hasClass('inputButtonDisabled')) {
						$('.inputButtonLeft, .inputButtonCenter, .inputButtonRight', $transform).addClass('inputButtonHover');
					}
				},function() {
					$('.inputButtonLeft, .inputButtonCenter, .inputButtonRight', $transform).removeClass('inputButtonHover');
				});

				/* Pressed / Click */
				$transform.mousedown(function() {
					if($('.inputButtonCenter input', $transform).is(':disabled')) { return; }
					$('.inputButtonLeft, .inputButtonCenter, .inputButtonRight', $transform).addClass('inputButtonPressed');
				}).mouseup(function() {
					$('.inputButtonLeft, .inputButtonCenter, .inputButtonRight', $transform).removeClass('inputButtonPressed');
				}).mouseout(function() {
					$('.inputButtonLeft, .inputButtonCenter, .inputButtonRight', $transform).removeClass('inputButtonPressed');
				}).click(function() {
					$('.inputButtonCenter input', $transform)[0].click();
				});
			});
		},
		transformSelect : function(options) {
			return $($(this).get().reverse()).each(function(index) {
				var $select = $(this);
				var _left	= '<div class="selectLeft"></div>';
				var _right	= '<div class="selectRight"></div>';
				var _clear	= '<div class="selectClear"></div>';
				var _options = $('<ul class="selectOptions"></ul>');
				var _equal = true;

				if((!$select.is('select')) || ($select.attr('multiple')) || ($select.parent().parent().hasClass('transform'))) { return; }

				var $transform = $select.wrap('<div class="transform"><div class="selectCenter" style="width:' + $select.outerWidth() + 'px;"></div></div>').parent().parent().prepend(_left).append(_right, _clear, _options);
				$transform.width($('.selectLeft', $transform).outerWidth() + $('.selectCenter', $transform).outerWidth() + $('.selectRight', $transform).outerWidth()).css({zIndex: Math.abs(index + 10) });

				$('option', $('.selectCenter select', $transform)).each(function() {
					$(_options).append('<li class="selectOption'+ ($(this).is(':disabled') ? ' selectOptionDisabled' : '') + (($(this).html() == $('option:selected', $('.selectCenter select', $transform)).html()) ? ' selectOptionSelected' : '') + '">' + $(this).html() + '</li>');
				});

				/* Disabled */
				if($('.selectCenter select', $transform).is(':disabled')) {
					$('.selectLeft, .selectCenter, .selectRight', $transform).addClass('selectDisabled');
				}

				/* Selected */
				$('.selectCenter',$transform).prepend('<div class="selectSelected">' + (($('option:selected', $('.selectCenter select', $transform)).is('option')) ? ($('option:selected', $('.selectCenter select', $transform)).html()) : '') + '</div>');

				/* Option Width */
				$('.selectOption', $transform).width($transform.outerWidth() - parseInt($('.selectOption', $transform).css('padding-left')) - parseInt($('.selectOption', $transform).css('padding-right')));

				/* Options Height (mozilla fix : height + 1) */
				$('.selectOptions', $transform).show().height(((($('.selectOption', $transform).size() < 5) ? $('.selectOption', $transform).size() : 5) * $('.selectOption', $transform).outerHeight()) + ($.browser.mozilla ? 1 : 0)).hide();

				/* Hover */
				$('.selectOption', $transform).hover(function() {
					if(!$(this).hasClass('selectOptionFocus') && !$(this).hasClass('selectOptionDisabled')) {
						$(this).addClass('selectOptionHover');
					}
				},function() {
					$(this).removeClass('selectOptionHover');
				});

				/* Option Click */
				$('.selectOption', $('.selectOptions', $transform)).click(function() {
					var _this = $(this);
					if($(_this).hasClass('selectOptionDisabled')) { return; }
					$('option', $('.selectCenter select', $transform)).each(function(i) {
						if($(this).html() == _this.html()) {
							$('.selectOption', $transform).removeClass('selectOptionSelected');
							_this.addClass('selectOptionSelected');
							$('.selectCenter select', $transform).get(0).selectedIndex = i;
						}
					});
					$('.selectSelected', $transform).html($(this).html());
				});

				/* Click */
				$transform.click(function() {
					if($('.selectCenter select', $transform).is(':disabled')) { return; }

					/* Compare : Select <> selectOptions */
					if(options.compare){

						if($('option', $('.selectCenter select', $transform)).size() != $($('.selectOption', $('.selectOptions', $transform))).size()) {
							$('.selectCenter select', $transform).trigger('transform.selectUpdate').click();
							return _equal = false;
						} else {
							$('option', $('.selectCenter select', $transform)).each(function() {
								if($(this).html() != $($('.selectOption', $('.selectOptions', $transform))[$(this).index()]).html()) {
									$('.selectCenter select', $transform).trigger('transform.selectUpdate').click();
									return _equal = false;
								}
							});
						}
					}
					if(!$('.selectOptions', $transform).hasClass('show') && _equal) {
						$('.selectOptions').hide().removeClass('show');
						$('.selectLeft, .selectCenter, .selectRight').removeClass('show');
					}
					$('.selectOption', $transform).removeClass('selectOptionSelected').eq($('.selectCenter select', $transform).get(0).selectedIndex).addClass('selectOptionSelected');
					
					$('.selectOptions', $transform).slideToggle('fast', function(){
						/* selectOptionSelected : selectOptions scoll middle */
						$('.selectOptions:visible', $transform).animate({ scrollTop:(($('.selectOptionSelected',$('.selectOptions:visible', $transform)).index()-2) * $('.selectOptionSelected',$('.selectOptions:visible', $transform)).outerHeight()) }, 'fast');
					}).toggleClass('show');
				});

				/* Bind Update Event */
				$('.selectCenter select', $transform).unbind('transform.selectUpdate').bind('transform.selectUpdate', function(){
					methods.transformSelectUpdate.apply($('.selectCenter select', $transform), [options]);
				});
			});
		},
		transformInputCheckbox : function(options) {
			return $(this).each(function() {
				var $input = $(this);
				var $label = $input.prev().is('label') ? ($input.prev().addClass('leftLabel')) : ($input.next().is('label') ? ($input.next().addClass('rightLabel')) : $input);
				var _clear = '<div class="inputClear"></div>';

				if((!$input.is('input:checkbox')) || ($input.parent().parent().hasClass('transform'))) { return; }

				var $transform = $input.wrap('<div class="transform"><div class="inputCheckbox"></div></div>').parent().parent();
				/* Label Cluster */
				if($transform.prev().is('label') || $transform.next().is('label')) { 
					if($transform.prev().is('label')) {
						$label.prependTo($transform);
					} else if ($transform.next().is('label')) {
						$label.appendTo($transform);
					}
				}			
				/* Break Line (mozilla fix : width + 1) */
				$transform.css('float','left').width($transform.outerWidth() + (($label.is('label') && $.browser.mozilla) ? 1 : 0)).css('float','').append(_clear);

				/* Disabled ? Checked ? */
				if($('input',$('.inputCheckbox', $transform)).is(':disabled')) {
					$('.inputCheckbox', $transform).addClass('inputCheckboxDisabled');
				} else if($('input',$('.inputCheckbox', $transform)).is(':checked')) {
					$('.inputCheckbox', $transform).addClass('inputCheckboxChecked');
				}

				/* Hover */
				$transform.hover(function() {
					if(!$('.inputCheckbox', $transform).hasClass('inputCheckboxFocus') && !$('.inputCheckbox', $transform).hasClass('inputCheckboxDisabled')) {
						$('.inputCheckbox', $transform).addClass('inputCheckboxHover');
					}
				},function() {
					$('.inputCheckbox', $transform).removeClass('inputCheckboxHover');
				});

				/* Real Click */
				$('input', $('.inputCheckbox', $transform)).click(function() {
					if($('input',$('.inputCheckbox', $transform)).is(':disabled')) { return; }

					$('.inputCheckbox', $transform).toggleClass('inputCheckboxChecked');

					/* IE First Change Fix */
					if($.browser.msie && !$('input', $('.inputCheckbox', $transform)).hasClass('inputCheckboxMsieFirstChange')) {
						$('input', $('.inputCheckbox', $transform)).trigger('change').addClass('inputCheckboxMsieFirstChange');
					}
				});

				/* Click */
				$('.inputCheckbox', $transform).click(function(event) {
					if($(event.target).hasClass('inputCheckbox')) {
						$('input', $('.inputCheckbox', $transform))[0].click();
					}
				});	
			});
		},
		transformInputRadio : function(options) {
			return $(this).each(function() {
				var $input = $(this);
				var $label = $input.prev().is('label') ? ($input.prev().addClass('leftLabel')) : ($input.next().is('label') ? ($input.next().addClass('rightLabel')) : $input);
				var _clear = '<div class="inputClear"></div>';

				if((!$input.is('input:radio')) || ($input.parent().parent().hasClass('transform'))) { return; }

				var $transform = $input.wrap('<div class="transform"><div class="inputRadio"></div></div>').parent().parent();
				/* Label Cluster */
				if($transform.prev().is('label') || $transform.next().is('label')) { 
					if($transform.prev().is('label')) {
						$label.prependTo($transform);
					} else if ($transform.next().is('label')) {
						$label.appendTo($transform);
					}
				}			
				/* Break Line (mozilla fix : width + 1) */
				$transform.css('float','left').width($transform.outerWidth() + (($label.is('label') && $.browser.mozilla) ? 1 : 0)).css('float','').append(_clear);

				/* Disabled ? Checked ?*/
				if($('input', $('.inputRadio', $transform)).is(':disabled')) {
					$('.inputRadio', $transform).addClass('inputRadioDisabled');
				} else if($('input', $('.inputRadio', $transform)).is(':checked')) {
					$('.inputRadio input[name="' + $('input', $('.inputRadio', $transform)).attr('name')+'"]').removeAttr('checked').parent().removeClass('inputRadioChecked');
					$('input', $('.inputRadio', $transform).addClass('inputRadioChecked')).attr('checked','checked');
				}

				/* Hover */
				$transform.hover(function() {
					if(!$('.inputRadio', $transform).hasClass('inputRadioFocus') && !$('.inputRadio', $transform).hasClass('inputRadioDisabled')) {
						$('.inputRadio', $transform).addClass('inputRadioHover');
					}
				},function() {
					$('.inputRadio', $transform).removeClass('inputRadioHover');					
				});

				/* Real Click */
				$('input', $('.inputRadio', $transform)).click(function() {
					if($('input', $('.inputRadio', $transform)).is(':disabled')) { return; }

					/* IE onChange Change */
					if($.browser.msie) {
						if(!$('.inputRadio', $transform).hasClass('inputRadioChecked')) {
							$('input', $('.inputRadio', $transform)).trigger('change');
						}
					}

					/* Uncheck Radio Group */
					$('.inputRadio input[name="' + $('input', $('.inputRadio', $transform)).attr('name')+'"]').parent().removeClass('inputRadioChecked');

					/* Check Clicked Radio */
					$('.inputRadio', $transform).addClass('inputRadioChecked');
				});

				/* Click */
				$('.inputRadio', $transform).click(function(event) {
					if($(event.target).hasClass('inputRadio')) {
						$('input',$('.inputRadio', $transform))[0].click();
					}
				});
			});
		},
		transformReset : function(options) {
			var $this = $(this);
			
			window.setTimeout(function() {
				$('select', $this).each(function() {
					$('option:selected', $(this)).each(function() {
						var $option = $(this);
						var $transform = $(this).parents('.transform');
						/* Selected */
						$('.selectSelected', $transform).html($option.html());
						$('.selectOption.selectOptionSelected', $('.selectOptions', $transform)).removeClass('selectOptionSelected');
						$('.selectOption', $('.selectOptions', $transform)).eq($option.index()).addClass('selectOptionSelected');
					});
				});
				$('input:checkbox', $this).each(function() {
					var $input = $(this);
					/* Disabled ? Checked ? */
					$input.is(':disabled') ? ($input.parent('.inputCheckbox').addClass('inputCheckboxDisabled')) : (($input.is(':checked')) ? ($input.parent('.inputCheckbox').addClass('inputCheckboxChecked')) : ($input.parent('.inputCheckbox').removeClass('inputCheckboxChecked')));
				});
				$('input:radio', $this).each(function() {
					var $input = $(this);
					/* Disabled ? Checked ? */
					$input.is(':disabled') ? ($input.parent('.inputRadio').addClass('inputRadioDisabled')) : (($input.is(':checked')) ? ($input.parent('.inputRadio').addClass('inputRadioChecked')) : ($input.parent('.inputRadio').removeClass('inputRadioChecked')));
				});
			}, 10);
		},
		transformExternalClick : function(event) {
			if ($(event.target).parents('.transform').length === 0) {
				/* transformSelect : Click Off */
				$('.selectOptions:visible').slideToggle('fast').toggleClass('show');
			}
		},
		transformExternalKeyPressed : function(event) {
			switch(event.keyCode){
				case 27: /* Escape */
					if($('.selectOptions:visible').size() == 1){
						var $transform = $('.selectOptions:visible').parents('.transform');
						$('.selectOption', $transform).removeClass('selectOptionSelected').eq($('.selectCenter select', $transform).get(0).selectedIndex).addClass('selectOptionSelected');
						$('.selectOptions:visible').slideToggle('fast').toggleClass('show');
					}
				break;
				case 40: /* Down */
					if($('.selectOptions:visible').size() == 1){
						if($('.selectOptionSelected','.selectOptions:visible').next().hasClass('selectOption')){
							$('.selectOptionSelected','.selectOptions:visible').removeClass('selectOptionSelected').next().addClass('selectOptionSelected');
							if($('.selectOptionSelected','.selectOptions:visible').position().top > $('.selectOptions:visible').height() || $('.selectOptionSelected','.selectOptions:visible').position().top <= $('.selectOptions:visible').height()){
								/* TODO: Fix Firefox Scroll selectOptionSelected height Bug */
								$('.selectOptions:visible').animate({ scrollTop:(($('.selectOptionSelected','.selectOptions:visible').index()-2) * $('.selectOptionSelected','.selectOptions:visible').outerHeight()) }, 'fast');
							}
						}
						return false;
					}
					return;
				break;
				case 38: /* Up */
					if($('.selectOptions:visible').size() == 1){
						if($('.selectOptionSelected','.selectOptions:visible').prev().hasClass('selectOption')){
							$('.selectOptionSelected','.selectOptions:visible').removeClass('selectOptionSelected').prev().addClass('selectOptionSelected');
							if($('.selectOptionSelected','.selectOptions:visible').position().top < ($('.selectOptionSelected','.selectOptions:visible').outerHeight()*2) || $('.selectOptionSelected','.selectOptions:visible').position().top >= $('.selectOptions:visible').height()){
								/* TODO: Fix Firefox Scroll selectOptionSelected height Bug */
								$('.selectOptions:visible').animate({ scrollTop:(($('.selectOptionSelected','.selectOptions:visible').index()-2) * $('.selectOptionSelected','.selectOptions:visible').outerHeight()) }, 'fast');
							}
						}
						return false;
					}
					return;
				break;
				case 13: /* Enter */
					if($('.selectOptions:visible').size() == 1){
						$('.selectOptionSelected','.selectOptions:visible').click();
						return false;
					}
					return;
				break;
				default:
					return;
				break;
			}
		},
		transformSelectUpdate : function(options) {
			return $(this).each(function() {
				var $select = $(this);

				if((!$select.is('select')) || ($select.attr('multiple')) || (!$select.parent().parent().hasClass('transform'))) { return; }

				var $transform = $select.parent().parent();

				methods.transformSelect.apply($('.selectCenter select', $transform).insertBefore($transform), [options]).parents('.transform');
				$transform.remove();
			});
		},
		selectUpdate : function() {
			var $select = $(this);
			if(($select.is('select')) || !($select.attr('multiple'))){
				return $select.trigger('transform.selectUpdate');
			} else {
				$.error( 'Method transform.selectUpdate does not work with ' + $select[0].nodeName + ' tag' );
			}
		}
	};
})(jQuery);
