/*
 *
 * jqTransform
 * by mathieu vilaplana mvilaplana@dfc-e.com
 * Designer ghyslain armand garmand@dfc-e.com
 * modified by thomas.jakobi@partout.info
 *
 * Version 1.0 25.09.08
 * Version 1.1 06.08.09
 * Version 1.2 12.04.10
 *
 * Add event click on Checkbox and Radio
 * Auto calculate the size of a select element
 * Can now, disabled the elements
 * Correct bug in ff if click on select (overflow=hidden)
 * No need any more preloading !!
 *
 ******************************************** */

(function($) {
	var defaultOptions = {
		preloadImg : false
	};

	/***************************
	 Labels
	 ***************************/
	var jqTransformGetLabel = function(objfield) {
		var selfForm = $(objfield.get(0).form);
		var oLabel = objfield.next();
		if(!oLabel.is('label')) {
			oLabel = objfield.prev();
			if(oLabel.is('label')) {
				var inputname = objfield.attr('id');
				if(inputname) {
					oLabel = selfForm.find('label[for="' + inputname + '"]');
				}
			}
		}
		if(oLabel.is('label')) {
			return oLabel.css('cursor', 'pointer');
		}
		return false;
	};
	/* Hide all open selects */
	var jqTransformHideSelect = function(oTarget) {
		var ulVisible = $('.jqTransformSelectWrapper ul:visible');
		ulVisible.each(function() {
			var oSelect = $(this).parents(".jqTransformSelectWrapper:first").find("select").get(0);
			// do not hide if click on the label object associated to the select
			if(!(oTarget && oSelect.oLabel && oSelect.oLabel.get(0) == oTarget.get(0))) {
				$(this).hide();
			}
		});
	};
	/* Check for an external click */
	var jqTransformCheckExternalClick = function(event) {
		if($(event.target).parents('.jqTransformSelectWrapper').length === 0) {
			jqTransformHideSelect($(event.target));
		}
	};
	/* Apply document listener */
	var jqTransformAddDocumentListener = function() {
		$(document).mousedown(jqTransformCheckExternalClick);
	};
	/* Add a new handler for the reset action */
	var jqTransformReset = function(f) {
		var sel;
		$('.jqTransformSelectWrapper select', f).each(function() {
			sel = (this.selectedIndex < 0) ? 0 : this.selectedIndex;
			$('ul', $(this).parent()).each(function() {
				$('a:eq(' + sel + ')', this).click();
			});
		});
		$('a.jqTransformCheckbox, a.jqTransformRadio', f).removeClass('jqTransformChecked');
		$('input:checkbox, input:radio', f).each(function() {
			if(this.checked) {
				$('a', $(this).parent()).addClass('jqTransformChecked');
			}
		});
	};
	/***************************
	 Buttons
	 ***************************/
	$.fn.jqTransInputButton = function() {
		return this.each(function() {
			var button = $(this);
			var newButton = $('<div class="jqTransformButtonWrapper"><button id="' + this.id + '" name="' + this.name + '" type="' + this.type + '" class="' + this.className + ' jqTransformButton">' + $(this).attr('value') + '</button>').css('width', button.outerWidth()).hover(function() {
				newButton.addClass('jqTransformButton-hover');
			}, function() {
				newButton.removeClass('jqTransformButton-hover')
			}).mousedown(function() {
				newButton.addClass('jqTransformButton-click')
			}).mouseup(function() {
				newButton.removeClass('jqTransformButton-click')
			});
			newButton.find('button').css('width', button.outerWidth());
			$(this).replaceWith(newButton);
		});
	};
	$.fn.jqTransButton = function() {
		return this.each(function() {
			var button = $(this);
			var newButton = $('<div class="jqTransformButtonWrapper"><button id="' + this.id + '" name="' + this.name + '" type="' + this.type + '" class="' + this.className + ' jqTransformButton" value="' + $(this).attr('value') + '">' + $(this).html() + '</button>').css('width', button.outerWidth()).hover(function() {
				newButton.addClass('jqTransformButton-hover');
			}, function() {
				newButton.removeClass('jqTransformButton-hover')
			}).mousedown(function() {
				newButton.addClass('jqTransformButton-click')
			}).mouseup(function() {
				newButton.removeClass('jqTransformButton-click')
			});
			newButton.find('button').css('width', button.outerWidth());
			$(this).replaceWith(newButton);
		});
	};
	/***************************
	 Text Fields
	 ***************************/
	$.fn.jqTransInputText = function() {
		return this.each(function() {
			var input = $(this);
			var width = input.outerWidth();
			var required = input.hasClass('required') ? 'required' : '';
			var id = input.attr('id');
			var readonly = (input.attr("readonly") == true) ? 'readonly' : '';

			if(input.hasClass('jqtranformdone') || !input.is('input')) {
				return;
			}
			input.addClass('jqtranformdone').removeAttr('id');

			var oLabel = jqTransformGetLabel($(this));
			oLabel && oLabel.bind('click', function() {
				input.focus();
			});
			input.addClass("jqTransformInput").wrap('<div class="jqTransformInputWrapper"><div></div></div>');
			var wrapper = input.parent().css('width', width).parent().css('width', width);
			input.focus(function() {
				wrapper.addClass("jqTransformInputWrapper-focus");
			}).blur(function() {
				wrapper.removeClass("jqTransformInputWrapper-focus");
			}).hover(function() {
				wrapper.addClass("jqTransformInputWrapper-hover");
			}, function() {
				wrapper.removeClass("jqTransformInputWrapper-hover");
			});
			this.wrapper = wrapper.addClass(required).addClass(readonly).attr('id', id);

		});
	};
	/***************************
	 Check Boxes
	 ***************************/
	$.fn.jqTransCheckBox = function() {
		return this.each(function() {
			if($(this).hasClass('jqTransformHidden')) {
				return;
			}

			var input = $(this);
			var inputSelf = this;

			//set the click on the label
			var oLabel = jqTransformGetLabel(input);
			oLabel && oLabel.click(function() {
				aLink.trigger('click');
			});
			var aLink = $('<a href="#" class="jqTransformCheckbox"></a>');
			//wrap and add the link
			input.addClass('jqTransformHidden').wrap('<span class="jqTransformCheckboxWrapper"></span>').parent().prepend(aLink);
			//on change, change the class of the link
			input.change(function() {this.checked && aLink.addClass('jqTransformChecked') || aLink.removeClass('jqTransformChecked');
				return true;
			});
			var wrapper = input.parent();
			wrapper.hover(function() {
				wrapper.addClass("jqTransformCheckboxWrapper-hover");
			}, function() {
				wrapper.removeClass("jqTransformCheckboxWrapper-hover");
			});
			// Click Handler, trigger the click and change event on the input
			aLink.click(function() {
				//do nothing if the original input is disabled
				if(input.attr('disabled')) {
					return false;
				}
				//trigger the envents on the input object
				input.trigger('click').trigger("change");
				return false;
			});
			// set the default state
			this.checked && aLink.addClass('jqTransformChecked');
		});
	};
	/***************************
	 Radio Buttons
	 ***************************/
	$.fn.jqTransRadio = function() {
		return this.each(function() {
			if($(this).hasClass('jqTransformHidden')) {
				return;
			}

			var input = $(this);
			var inputSelf = this;
			oLabel = jqTransformGetLabel(input);
			oLabel && oLabel.click(function() {
				aLink.trigger('click');
			});
			var aLink = $('<a href="#" class="jqTransformRadio" rel="' + this.name + '"></a>');
			input.addClass('jqTransformHidden').wrap('<span class="jqTransformRadioWrapper"></span>').parent().prepend(aLink);

			input.change(function() {inputSelf.checked && aLink.addClass('jqTransformChecked') || aLink.removeClass('jqTransformChecked');
				return true;
			});
			var wrapper = input.parent();
			wrapper.hover(function() {
				wrapper.addClass("jqTransformRadioWrapper-hover");
			}, function() {
				wrapper.removeClass("jqTransformRadioWrapper-hover");
			});
			// Click Handler
			aLink.click(function() {
				if(input.attr('disabled')) {
					return false;
				}
				input.trigger('click').trigger('change');

				// uncheck all others of same name input radio elements
				$('input[name="' + input.attr('name') + '"]', inputSelf.form).not(input).each(function() {$(this).attr('type') == 'radio' && $(this).trigger('change');
				});
				return false;
			});
			// set the default state
			inputSelf.checked && aLink.addClass('jqTransformChecked');
		});
	};
	/***************************
	 TextArea
	 ***************************/
	$.fn.jqTransTextarea = function() {
		return this.each(function() {
			var textarea = $(this);
			var width = textarea.outerWidth();
			var height = textarea.outerHeight();
			var id = textarea.attr('id');
			var required = textarea.hasClass('required') ? 'required' : '';

			if(textarea.hasClass('jqtransformdone')) {
				return;
			}
			textarea.addClass('jqtransformdone');
			oLabel = jqTransformGetLabel(textarea);
			oLabel && oLabel.click(function() {
				textarea.focus();
			});
			var strDiv = '<div class="jqTransformTextarea"><div class="jqTransformTextarea-tr"><div class="jqTransformTextarea-tl"></div></div>';
			strDiv += '<div class="jqTransformTextarea-r"><div class="jqTransformTextarea-l"></div></div>';
			strDiv += '<div class="jqTransformTextarea-br"><div class="jqTransformTextarea-bl"></div></div></div>';

			var oDiv = $(strDiv).attr('id', 'jqTransform' + id).insertAfter(textarea).hover(function() {!oDiv.hasClass('jqTransformTextarea-focus') && oDiv.addClass('jqTransformTextarea-hover');
			}, function() {
				oDiv.removeClass('jqTransformTextarea-hover');
			});
			textarea.focus(function() {
				oDiv.removeClass('jqTransformTextarea-hover').addClass('jqTransformTextarea-focus');
			}).blur(function() {
				oDiv.removeClass('jqTransformTextarea-focus');
			}).appendTo($('.jqTransformTextarea-r', oDiv));
			this.oDiv = oDiv;

			var tlWidth = $('.jqTransformTextarea-tl', oDiv).width();
			var tlHeight = $('.jqTransformTextarea-tl', oDiv).height();

			$('.jqTransformTextarea-tr', oDiv).css('width', width - tlWidth);
			$('.jqTransformTextarea-br', oDiv).css('width', width - tlWidth);
			$('.jqTransformTextarea-l', oDiv).css('height', height - tlHeight);
			$('.jqTransformTextarea-r', oDiv).css('height', height - tlHeight).css('width', width - tlWidth);
			$('.jqtransformdone', oDiv).css('width', textarea.innerWidth() - (tlWidth * 2));
			$('.jqTransformTextarea', oDiv).addClass(required);

			if($.browser.safari) {
				$('.jqtransformdone', oDiv).addClass('jqTransformSafariTextarea').css('height', height - tlHeight);
			}
		});
	};
	/***************************
	 Select
	 ***************************/
	$.fn.jqTransSelect = function() {
		return this.each(function(index) {
			var select = $(this);
			var required = select.hasClass('required') ? 'required' : '';

			if(select.hasClass('jqTransformHidden')) {
				return;
			}
			if(select.attr('multiple')) {
				return;
			}

			var oLabel = jqTransformGetLabel(select);

			/* First thing we do is Wrap it */
			var $wrapper = select.addClass('jqTransformHidden').wrap('<div class="jqTransformSelectWrapper"></div>').parent().css({
				zIndex : 10 - index
			});

			/* Now add the html for the select */
			$wrapper.prepend('<div><span></span><a href="#" class="jqTransformSelectOpen"></a></div><ul></ul>');
			var $ul = $('ul', $wrapper).css('width', select.outerWidth()).hide();
			/* Now we add the options */
			$('option', this).each(function(i) {
				var oLi = $('<li><a href="#" index="' + i + '">' + $(this).html() + '</a></li>');
				$ul.append(oLi);
			});
			/* Add click handler to the a */
			$ul.find('a').click(function() {
				$('a.selected', $wrapper).removeClass('selected');
				$(this).addClass('selected');
				/* Fire the onchange event */
				if(select[0].selectedIndex != $(this).attr('index') && select[0].onchange) {
					select[0].selectedIndex = $(this).attr('index');
					select[0].onchange();
				}
				select[0].selectedIndex = $(this).attr('index');
				$('span:eq(0)', $wrapper).html($(this).html());
				$ul.hide();
				return false;
			});
			/* Set the default */
			$('a:eq(' + this.selectedIndex + ')', $ul).click();
			$('span:first', $wrapper).click(function() {
				$("a.jqTransformSelectOpen", $wrapper).trigger('click');
			});
			oLabel && oLabel.click(function() {
				$("a.jqTransformSelectOpen", $wrapper).trigger('click');
			});
			this.oLabel = oLabel;

			/* Apply the click handler to the Open */
			var oLinkOpen = $('a.jqTransformSelectOpen', $wrapper).click(function() {
				//Check if box is already open to still allow toggle, but close all other selects
				if($ul.css('display') == 'none') {
					jqTransformHideSelect();
				}
				if(select.attr('disabled')) {
					return false;
				}
				$ul.slideToggle('fast', function() {
					var offSet = ($('a.selected', $ul).offset().top - $ul.offset().top);
					$ul.animate({
						scrollTop : offSet
					});
				}).parent().toggleClass("jqTransformSelectWrapper-focus");
				return false;
			});
			// Set the new width
			var iSelectWidth = select.outerWidth();
			var oSpan = $('span:first', $wrapper);
			var newWidth = (iSelectWidth > oSpan.innerWidth()) ? iSelectWidth : $wrapper.width();
			$wrapper.css('width', newWidth);
			$ul.css('width', newWidth - 2);
			oSpan.css({
				width : iSelectWidth
			});

			// Calculate the height if necessary, less elements that the default height
			// Show the ul to calculate the block, if ul is not displayed li height value is 0
			$ul.css({
				display : 'block',
				visibility : 'hidden'
			});
			var iSelectHeight = ($('li', $ul).length) * ($('li:first', $ul).height());
			(iSelectHeight < $ul.height()) && $ul.css({
				height : iSelectHeight,
				overflow : 'hidden'
			});
			$ul.css({
				display : 'none',
				visibility : 'visible'
			});

			$wrapper.addClass(required).hover(function() {
				$wrapper.addClass("jqTransformSelectWrapper-hover");
			}, function() {
				$wrapper.removeClass("jqTransformSelectWrapper-hover");
			});
		});
	};
	/***************************
	 Transform Form
	 ***************************/
	$.fn.jqTransform = function(options) {
		var opt = $.extend({}, defaultOptions, options);

		/* each form */
		return this.each(function() {
			var selfForm = $(this);
			if(selfForm.hasClass('jqtransformdone')) {
				return;
			}
			selfForm.addClass('jqtransformdone');

			$('input:submit, input:reset, input[type="button"]', this).jqTransInputButton();
			$('input:text, input:password', this).jqTransInputText();
			$('input:checkbox', this).jqTransCheckBox();
			$('input:radio', this).jqTransRadio();
			$('textarea', this).jqTransTextarea();
			$('button', this).jqTransButton();

			if($('select', this).jqTransSelect().length > 0) {
				jqTransformAddDocumentListener();
			}
			selfForm.bind('reset', function() {
				var action = function() {
					jqTransformReset(this);
				};
				window.setTimeout(action, 10);
			});
		});
	};
})(jQuery);

