
// ----------------------------------------------------------------------------------------------------
// COMPOSITION DES FORMULAIRES : @author michael.piera - Idianet - version 1.1
// ----------------------------------------------------------------------------------------------------

(function($){
	// -----------------------------------------------------------------------------------
	// Composer les formulaires
	// -----------------------------------------------------------------------------------			  
	$.fn.formComposer = function() {
		$.focused = null;
		$(this).not(':hidden').not('.noFormComposer').each(function() {
            // id de l'input
			var inputId 	= $(this).attr('id');
			// type de l'input
            var inputType 	= $(this).attr('type');
            if (!inputType) var inputType = $(this).get(0).nodeName.toLowerCase();
			if (inputType == 'select-one') inputType = 'select';
				// si l'input est déjà traité
				if ($('#'+inputType+'_'+inputId).length !=0) return;			
				// si l'input n'a pas d'identifiant
				if (!inputId) { inputId = 'id_'+Number(new Date()); $(this).attr('id', inputId); }
			// sélecteurs
			var inputName 	= $(this).attr('name');
            var isDisabled 	= $(this).is(':disabled');
            var inputSize 	= $(this).attr('size');			
			var inputClass	= $.prefix+'input-'+inputType;
			var labelClass	= $.prefix+'label-'+inputType;	
			$(this).wrap($('<span />').addClass(inputClass).attr('id',inputType+'_'+inputId)).wrap('<span />').wrap('<span />');
            var inputBase	= $('#'+inputId);			
			var inputSpan	= $('#'+inputType+'_'+inputId);			
            var label		= $('label[for='+inputId+']');
			label.addClass(labelClass);

			// -----------------------------------------------------------------------------------
			// scroller sur textarea (A OPTIMISER)
			function FitToContent(id, maxHeight) {
				var text = id && id.style ? id : document.getElementById(id);
				if (!text) return;
				var adjustedHeight = text.clientHeight;
				if (!maxHeight || maxHeight > adjustedHeight) {
					adjustedHeight = Math.max(text.scrollHeight, adjustedHeight);
					if (maxHeight)							adjustedHeight = Math.min(maxHeight, adjustedHeight);
					if (adjustedHeight > text.clientHeight)	text.style.height = adjustedHeight + "px";
				}
			}
			if (inputType=='textarea') {
				$(this).keyup(function() {
					FitToContent(this, document.documentElement.clientHeight);
					$('#'+$(this).attr('id')+'-scroller').scrollComposer({ scrollToPos : 'stable' });
				});							
				$('#'+$(this).attr('id')+'-scroller').scrollComposer({ scrollToPos : 'stable' });							
			}
			// -----------------------------------------------------------------------------------
			
			// text -----------------------
			if (inputType == 'text') {
				$(this).placeholder();
				// si la largeur de l'input est renseignée
				if (inputSize) $(this).css('width',(inputSize*5)+'px');				
			}
			
			// select one -----------------
			if (inputType == 'select') 
				$(this).selectOneComposer({ 
					inputSpan : inputSpan,
					label 	  : label
				});			
			
			// event span -----------------
			inputSpan
			.bind('mouseover', function() {
				$(this).formClassComposer({ 
					eventClass	: 'hover', 
					realInput	: inputId, 
					action		: 'add' 
				});
			})
			.bind('mouseout', function() {
				$(this).formClassComposer({ 
					eventClass	: 'hover',
					realInput	: inputId, 
					action		: 'remove' 
				});
			})
			.bind('click', function(event) {
				if (inputType == 'submit' && event.target != inputBase[0]) {
					return;						
				} else {
					if (event.target != inputBase[0])
						inputBase.trigger('focus').trigger('click');				
					if (inputType == 'checkbox' || inputType == 'radio') {
						if (inputBase.is(':checked'))  
							$(this).formClassComposer({
								eventClass	: 'checked',
								realInput	: inputId,
								action		: 'add'
							});
						else
							$(this).formClassComposer({ 
								eventClass	: 'checked',
								realInput	: inputId,
								action		: 'remove'
							});					
					}
				}
			});
			
			// event input -----------------
			inputBase
			.bind('click', function() {
				if (inputType == 'radio' && isDisabled === false) {
					 $('input[name='+inputName+']:not(:disabled)').each(function() {
						id = $(this).attr('id');
						$('#'+inputType+'_'+id).formClassComposer({
							eventClass	:'checked',
							realInput	: id,
							action		: 'remove'
						});													 
					});
				}			
			})
			.bind('focus', function() {
				$.focused = $(this);
				inputSpan.formClassComposer({ 
					eventClass	: 'focus',
					realInput	: inputId,
					action		: 'add'					
				});	
				// Focus sur la cellule de groupe					
				$(this).parents('.grp').addClass('grp-focus');
			})
			.bind('blur', function() {
				inputSpan.formClassComposer({ 
					eventClass	: 'focus',
					realInput	: inputId,
					action		: 'remove'					
				});
				// Blur sur la cellule de groupe			
				$('.grp').removeClass('grp-focus');	
			});	
			
			// event label -----------------
			label
			.bind('mouseover', function() {
				$('#'+inputType+'_'+$(this).attr('for')).formClassComposer({
					eventClass	: 'hover',
					realInput	: inputId,
					action		: 'add'		
				});
			})
			.bind('mouseout', function() {
				$('#'+inputType+'_'+$(this).attr('for')).formClassComposer({
					eventClass	: 'hover',
					realInput	: inputId,
					action		: 'remove'		
				});
			});
			
			// init statu -----------------
			if ($(this).is(':disabled')) 
				inputSpan.formClassComposer({ 
					realInput	: inputId 
				});		
			if ($(this).is(':checked'))	 
				inputSpan.formClassComposer({ 
					eventClass	: 'checked', 
					realInput	: inputId,
					action		: 'add'					
				});		
		});
	};
	// -----------------------------------------------------------------------------------
	// Composer les classes d'événement des formulaires
	// -----------------------------------------------------------------------------------		
	$.fn.formClassComposer = function(params) {
		var params = $.extend({
			eventClass	: '',
			action 		: 'add',	
			realInput	: $(this).attr('id')
		}, params);
		// init
		var isChecked 	= '';
		var isHover 	= '';
		var isFocus 	= '';
		var isDisabled 	=  $('#'+params.realInput).is(':disabled');		
		var eventClass	= '';		
		var elemClass	= $(this).attr('class').split(" ");
		var baseClass 	= elemClass[0];			
		// si l'objet ne contient pas de classe d'événement
		if (elemClass.length == 1) {
			if (isDisabled) 					eventClass = ' '+baseClass+'-disabled';
			else if (params.action != 'remove') eventClass = ' '+baseClass+'-'+params.eventClass;
			else 								eventClass = '';			
		} else {
			var statuClass	= elemClass[1].split("-");
			if ($.inArray('checked',statuClass) > -1  || params.eventClass == 'checked' )  isChecked  = '-checked';
			if ($.inArray('hover',statuClass) > -1    || params.eventClass == 'hover' )	   isHover	  = '-hover';
			if ($.inArray('focus',statuClass) > -1    || params.eventClass == 'focus' )	   isFocus	  = '-focus';				
			// si action == remove
			if (params.action == 'remove' && params.eventClass == 'checked') isChecked	= '';
			if (params.action == 'remove' && params.eventClass == 'hover') 	 isHover	= '';
			if (params.action == 'remove' && params.eventClass == 'focus') 	 isFocus	= '';			
			// si disabled
			if (isDisabled) eventClass = baseClass+isChecked+'-disabled';
			else			eventClass = baseClass+isChecked+isHover+isFocus;
			// vérification qu'un événement est encore demandé		
			if (eventClass == baseClass) eventClass ='';
			else 						 eventClass = ' '+eventClass;
		} 
		// attribution de la nouvelle classe
		$(this).attr('class',baseClass+eventClass);
		// Mise à jour de la classe du label
		var label	= $('label[for='+params.realInput+']');
		baseClass 	= baseClass.replace('input','label');
		eventClass 	= eventClass.replace('input','label');		
		label.attr('class',baseClass+eventClass);
	};
	// -----------------------------------------------------------------------------------
	// Gestion de l'attribut "Placeholder" pour XHTML 1.0
	// -----------------------------------------------------------------------------------	
	$.fn.placeholder = function(options) {
		var showPlaceholder = function(input, placeholder) {
			return input
			.val(placeholder)
			.addClass('placeholder')
			.data('hasPlaceholder', true);
		};
		var clearPlaceholder = function(input, placeholder) {
			if(input.data('hasPlaceholder')) {
				return input
				.val('')
				.removeClass('placeholder')
				.data('hasPlaceholder', false);
			};
		};
		return this.each(function(){					  
			var input 		= $(this);
			var placeholder = input.attr('alt');
			var label		= $('label[for='+input.attr('id')+']');
			if (placeholder) {
				// for password
				if (input.attr('type') == 'password') {
					setTimeout( function() { 
						if(input.val() == "") label.addClass('simPlaceholder');
					}, 100);
					input.bind('focusin', function(){
						label.removeClass('simPlaceholder');
					});
					input.bind('focusout', function(){
						if(input.val() == "") {
							label.addClass('simPlaceholder');
						} else {
							label.removeClass('simPlaceholder');
						}
					});
				// for other
				} else {			
					if(input.val() == '' || input.val() == placeholder) {
						showPlaceholder(input, placeholder);
					}
					input.bind('focus keydown paste', function(){
						clearPlaceholder(input, placeholder);
					});
					input.bind('blur', function(){
						if(input.val() == "") {
							showPlaceholder(input, input.attr('alt'));
						}
					});
					input.parents('form').first().submit(function(){
						clearPlaceholder(input, placeholder);
						return true;
					});
				}
			}
		});
	};
	// -----------------------------------------------------------------------------------
	// Composer les listes de sélection unique
	// -----------------------------------------------------------------------------------		
	jQuery.fn.selectOneComposer = function(params) {
		
		var selectOne			= $(this);
		selectOne.id			= selectOne.attr('id');
		selectOne.inputSpan		= params.inputSpan;	
		selectOne.label			= params.label;
		selectOne.isOpen		= null;
		selectOne.currIndex		= 0;
		selectOne.numPerList	= 10;
		
		// creation du bouton d'affichage de la liste de sélection
		selectOne.selectButton = $('<span class="'+$.prefix+'select-button">'+$(':selected',selectOne).text()+'</span>').insertAfter(selectOne);		
		selectOne.selectButton.css('width', selectOne.width()+'px');
		
		// événements associés au bouton d'affichage
		selectOne.inputSpan.bind('mousedown', function() { 
			blurOlder(selectOne);
			selectOne.focus();
			return false;		
		}).bind('click', function() { 
			displaySelect(selectOne);
			return false;			
		});
		
		// événements associés au <label>
		selectOne.label.bind('mousedown', function() {
			blurOlder(selectOne);
			selectOne.focus();
			return false;			
		}).bind('click', function() { 
			displaySelect(selectOne);
			return false;			
		});		
		
		// événements associés au <select>
		selectOne
		.bind('keyup', function(event) {
			var code 		= (event.keyCode ? event.keyCode : event.which);					   
			var evalReturn 	= false;								   
			switch (code) {
				case $.ui.keyCode.ENTER	:
					if (selectOne.isOpen)	closeSelect(selectOne);
					else					evalReturn = true;
					break;				
				case $.ui.keyCode.SPACE :
					if (selectOne.isOpen)	closeSelect(selectOne);
					else					displaySelect(selectOne);
					break;
				case $.ui.keyCode.UP 	:
				case $.ui.keyCode.LEFT 	:
					$(this).trigger('change');
					if (selectOne.isOpen) moveScroll(selectOne, 'up');					
					break;
				case $.ui.keyCode.DOWN	:
				case $.ui.keyCode.RIGHT	:					
					$(this).trigger('change');
					if (selectOne.isOpen) moveScroll(selectOne, 'down');					
					break;	
				default	:
					$(this).trigger('change');				
					break;	
			}								   
			return evalReturn;
		}).bind('keydown', function(event) {
			var code 		= (event.keyCode ? event.keyCode : event.which);					   							   
			switch (code) {
				case $.ui.keyCode.TAB	:
					if (selectOne.isOpen)	closeSelect(selectOne); 
					break;	
				default	:			
					break;	
			}
		}).bind('change', function() {
			$(selectOne.selectButton).text($('option:selected',selectOne).text());
			if (selectOne.isOpen) { 
				$('li', selectOne.selectList).removeClass('selected'); 				  
				$('li:not(.group):eq('+$(this).attr('selectedIndex')+')', selectOne.selectList).addClass('selected');
			}			
			return false;
		});

		// Affichage de la liste de sélection
		var displaySelect = function(selectOne) {
			
			var selectOption = [];
			
			// si la liste est désactivée ou si elle existe en tant que simulacre de liste
			if ($(selectOne).is(':disabled') || $('#select-list_'+selectOne.id).length != 0) return;			
			// sinon on créer la liste
			selectOne.selectBox 		= $('<div class="'+$.prefix+'select-box" id="select-list_'+selectOne.id+'"/>').appendTo('body');
			selectOne.selectBoxContent 	= $('<div class="'+$.prefix+'select-box-content"/>').appendTo(selectOne.selectBox);		
			
			// position de la liste (référent : window)
			//var evalTop 				= (selectOne.inputSpan.position().top + selectOne.inputSpan.height() + 2);		
			//selectOne.selectBox.css({ width : (selectOne.inputSpan.width()+2), top : evalTop, left : selectOne.inputSpan.position().left });

			selectOne.selectBox.css({ width : (selectOne.inputSpan.width()), zIndex:1000000 });
			selectOne.selectBox.position({
				of: selectOne.inputSpan,
				my: 'left top',
				at: 'left bottom'
			});

			selectOne.selectList = $('<ul></ul>').appendTo(selectOne.selectBoxContent);			
			
			selectOne.find('option').each(function(){
				selectOption.push({
					value			: $(this).attr('value'),
					text			: $(this).text(),
					selected		: $(this).attr('selected'),
					disabled		: $(this).attr('disabled'),
					classes			: $(this).attr('class'),
					optGroup		: $(this).parent('optgroup')
				});
			});
			
			// Génération de la liste <ul>
			for(var i in selectOption){
				if (selectOption[i].selected) selectOption[i].classes = (selectOption[i].classes ? selectOption[i].classes+' selected' : 'selected');
				if (selectOption[i].disabled) selectOption[i].classes = (selectOption[i].classes ? selectOption[i].classes+' disabled' : 'disabled');
				var thisLi = $('<li><span>'+selectOption[i].text+'</span></li>')
					.data('index',i)
					.addClass(selectOption[i].classes)
					.attr('id', selectOne.id+'-item-'+i)
					.data('optionClasses', selectOption[i].classes || '')
					.bind('mousedown', function() {
						$('option:eq('+$(this).data('index')+')', selectOne).attr('selected', 'selected').trigger('change');					
						closeSelect(selectOne);
						return false;
					})				
					.bind('mouseover', function() {
						$('li', selectOne.selectList).removeClass('hover'); 
						$(this).addClass('hover');					
					})
					.bind('mouseout', function() {
						$(this).removeClass('hover'); 
					});
				// si <optgroup>
				if (selectOption[i].optGroup.size()) {
					var optGroupLabel = selectOption[i].optGroup.attr('label');			
					var optGroupId = selectOne.id+'-'+selectOption[i].optGroup.index();
					if (selectOne.selectList.find('#'+optGroupId).size()) {
						selectOne.selectList.find('#'+optGroupId+' ul:last').append(thisLi);						
					} else {					
						$('<li class="group" id="'+optGroupId+'"><span class="group-lib">'+optGroupLabel+'</span><ul></ul></li>')
						.appendTo(selectOne.selectList)
						.find('ul')
						.append(thisLi);					
					}
				} else {
					thisLi.appendTo(selectOne.selectList);
				}
			}
			// initialisation de la liste
			initSelect(selectOne);			
		},
		
		initSelect = function(selectOne) {
			var maxHeight	= parseInt($('li:not(.group):first', selectOne.selectList).outerHeight()*selectOne.numPerList || 0, 10);
			var gotoSelect	= parseInt($('li.selected', selectOne.selectList).position().top-2 || 0, 10);
			selectOne.currIndex	= $('li').index($('li.selected', selectOne.selectList));
			selectOne.isOpen = true;
			$(document).bind('mousedown.selectOne', function() {
				if (selectOne.isOpen) { closeSelect(selectOne); }
			});
			selectOne.selectBoxContent.scrollComposer({height : 'auto', maxHeight : maxHeight, scrollToPos : gotoSelect });			
			if($.browser.msie){
				selectOne.selectBox.find('.'+$.prefix+'scroller-container:first').bind('mousedown mouseup', function(){ selectOne.focus(); return false; });	
				selectOne.selectBox.find('.'+$.prefix+'scroller-vBar:last').bind('mousedown mouseup', function(){ selectOne.focus(); return false; });	
				selectOne.selectBox.find('.'+$.prefix+'scroller-hBar:last').bind('mousedown mouseup', function(){ selectOne.focus(); return false; });	
				selectOne.selectBox.find('.'+$.prefix+'scroller-grip:last').bind('mousedown mouseup', function(){ selectOne.focus(); return false; });	
				selectOne.selectBox.find('.'+$.prefix+'scroller-content:first').bind('mousedown mouseup', function(){ selectOne.focus(); return false; });			
				selectOne.selectBox.find('.bar-up').bind('mousedown mouseup', function(){ selectOne.focus(); return false; });	
				selectOne.selectBox.find('.bar-down').bind('mousedown mouseup', function(){ selectOne.focus(); return false; });	
				selectOne.selectBox.find('.bar-trace').bind('mousedown mouseup', function(){ selectOne.focus(); return false; });		
				selectOne.selectBox.find('.bar-cursor').bind('mousedown mouseup', function(){ selectOne.focus(); return false; });	
				selectOne.selectBox.find('.bar-left').bind('mousedown mouseup', function(){ selectOne.focus(); return false; });	
				selectOne.selectBox.find('.bar-right').bind('mousedown mouseup', function(){ selectOne.focus(); return false; });	
				selectOne.selectBox.find('.bar-trace').bind('mousedown mouseup', function(){ selectOne.focus(); return false; });		
				selectOne.selectBox.find('.bar-cursor').bind('mousedown mouseup', function(){ selectOne.focus(); return false; });
			}
		},
		
		closeSelect = function(selectOne) {
			selectOne.isOpen = null;
			$(document).unbind('mousedown.selectOne');
			selectOne.selectBox.remove();			
		},
		
		blurOlder = function(selectOne) {	
			if ($.focused) {
				var focusId 	= $.focused.attr('id');			
				var selectList 	= $('#select-list_'+$.focused.attr('id'));
				if (selectOne.id != focusId && selectList) selectList.remove();				
				$.focused.blur();
			}
		},
		
		moveScroll = function(selectOne, direction) {
			var newIndex 	= $('li').index($('li.selected', selectOne.selectList));		
			var moveScroll 	= false;			
			if (newIndex < selectOne.currIndex) {
				moveScroll = true;
				selectOne.currIndex = newIndex;		
			} else if (newIndex > (selectOne.currIndex+selectOne.numPerList)-1) { 
				moveScroll = true;
				selectOne.currIndex = newIndex-(selectOne.numPerList-1);
				newIndex = newIndex-(selectOne.numPerList-1);			
			}
			if (moveScroll) selectOne.selectBoxContent.scrollComposer({ scrollToPos : (newIndex*21) });
		};		
		
	};
})(jQuery);

