/**
 * Créer un zone permettant d'afficher une liste importante de Checkbox ou Radio boutons.
 *
 * AFAIRE : Tests de compatibilités à refaire !
 * AFAIRE : Ré-activer le nextFormField avec prises en compte de n'importe qu'elle sutrucutre html
 * Amélioration : Simuler le clic sur un label pour lancer l'apparition !
 *
 */
function nMultInput(idSource, url, inputType, inputName, nbrItem, widthCol, strValid, prevSelect, strInfo, strCheck, callback) {

	/*
	 * Paramètrage de la class
	 */
	this.timeAppear = 100; /* durée d'apparition de la zone de contenu en ms */
	this.imgLoader = 'images/ajax-loader.gif'; /* chemin du loader */
	this.idSuffixeContainer = '-nMultInput'; /* suffixe qui sera ajoute à l'id de la source pour le conteneur principal */
	this.idSuffixeListe = '-nMultInputListes'; /* suffixe qui sera ajouté à l'id de la source pour le div contenant les champs */

	this.dimCoins = [8, 9]; /* Dimension en pixel des images de coins => Width, Height */
	this.heightItem = 18; /* Hauteur en pixel associé à une item */
	this.heightHead = 38;
	this.heightFoot = 54;

	/*
	 * Propriétés privées
	 */
	this.idSource = idSource; /* l'id de l'element sur lequel est associé le click d'ouverture */
	this.idContainer = idSource+this.idSuffixeContainer; /* l'id qui sera associé à la div conteneur nMultInput */
	this.idListe = idSource+this.idSuffixeListe; /* l'id qui sera associé à la div contenant les listes des champs */

	this.urlAjax = url; /* l'url de la page contenant la structure html à afficher dans le conteneur nMultInput */
	this.inputType = (inputType === 'radio') ? 'radio' : 'checkbox';
	this.inputName = inputName;

	this.nbrItem = nbrItem; /* le nombre de champs checkbox/radio par colonne */
	this.widthCol = widthCol; /* Largeur en pixel associé à une colone */

	this.prevSelect = (typeof(prevSelect) != 'undefined' && prevSelect.length > 0) ? prevSelect : false;

	this.callback = (typeof(callback) != 'undefined' && callback.length > 0) ? callback : false;
	this.prevResult = false;

	this.strInfoClass = '';
	switch(typeof(strInfo)) {
		case('string'):
			this.strInfo = strInfo;
			break;
		case('object'):
			this.strInfo = strInfo[0];
			this.strInfoClass = strInfo[1];
			break;
		case('undefined'):
			this.strInfo = false;
			break;
	}

	this.strCheckAll = (typeof(strCheck) != 'undefined') ? strCheck[0] : false; /* le texte affiché sur le bouton "Cocher tout" */
	this.strUncheckAll = (typeof(strCheck) != 'undefined') ? strCheck[1] : false; /* le texte affiché sur le bouton "Décocher tout" */

	this.strValid = strValid; /* le texte affiché sur le bouton de validation */

	this.posContainer;
	this.dimContainer;
	this.dimMilieu;

	this.txtOrigin = $('#'+this.idSource).text();
	this.prevFormField;
	this.nextFormField;
	this.boolListnerTab = false;

//	this.setNearFormField();
	this.setOnclickEvent();

//	var myBind = this;
//	$(document).bind('keydown', function(e) {
//		var key = e.charCode || e.keyCode || 0;
//		if((key == 9  && e.shiftKey) && e.target == myBind.nextFormField) {
//			myBind.load(e);
//			return false;
//		}
//		else if((key == 9 && !e.shiftKey) && e.target == myBind.prevFormField) {
//			myBind.load(e);
//			return false;
//		}
//	});

	// Si on a un résultat à précharger on lance automatiquement le chargement
	if(this.prevSelect != false) this.load(null);
}

nMultInput.prototype = {

	/*
	 * Récupère et définie le dernier input, select, ou textarea avant le nMultInput ainsi que le suivant.
	 * Les éléments seront ensuites utilisés pour la gestion de la navigation grâce au bouton de tabulation.
	 */
//	setNearFormField: function() {
//		var myBind = this;
//	 	// On récupère tout les enfants du form dans lequel se trouve le nMultInput
//		var formElems = $('#'+myBind.idSource).parents('form').children();
//		var i = 0; // i stockera la position du nMultInput
//		jQuery.each(formElems, function() {
//			// On recherche dans tout les enfants du form, la position du nMultInput
//			var child = $(this).find('#'+myBind.idSource);
//			if(child.length > 0) return false;
//			i++;
//		});
//
//		// On récupère le dernier input/select/textarea de l'élément précédent
//		myBind.prevFormField = (i > 0) ? $(formElems[(i-1)]).find(':input:last')[0] : false;
//		// On récupère le premier input/select/textarea de l'élément suivant
//		myBind.nextFormField = (i < (formElems.length-1)) ? $(formElems[(i+1)]).find(':input:first')[0] : false;
//		return true;
//	},

	/*
	 * Ajoute la propriété onclick à l'élément source portant l'id this.idSource.
	 */
	setOnclickEvent: function() {
		var myBind = this;
		$('#'+myBind.idSource).bind('click', function(e) { myBind.load(e); });
	},

	/*
	 * Lance l'affichage de la div de nMultInput.
	 *
	 * Dans le cas ou 'e' est null, on est dans un chargement sans clic utilisateur.
	 * On charge donc tout le contenu MAIS ON N'AFFICHE PAS LA DIV !
	 */
	load: function(e) {
		if(e != null) e.stopPropagation();

		this.prevResult = $('#'+this.idSource).text();

		// Si une autre fenêtre nMultInput est ouverte, on la ferme
		var nMultTinpurOpenned  = $('.nMultInput:visible');
		if(nMultTinpurOpenned.length > 0) {
			nMultTinpurOpenned.hide();
			$(document).unbind('click');
		}

		var myBind = this;

		/* On ajoute un listener sur l'evenement click du document */
		// Seulement dans le cas d'une demande d'affichage par clic et non pas lors du préchargement
		if(e != null) $(document).bind('click', function(e) {	myBind.hideElem(e); });

		/* Dans le cas où la div a déjà été chargée on se charge juste de la ré-afficher */
		var nMultInput = $('#'+myBind.idContainer);
		if(nMultInput.length > 0) {
			// On appelle la fonction de focus en paramètre car il faut attendre la fin du fadeIn
			nMultInput.fadeIn(myBind.timeAppear, function() {
				$("#"+myBind.idListe+" input[type='"+myBind.inputType+"']:first").focus();
			});
			return;
		}

		// On créé la liste des paramètres à passer à la requête ajax
		var random = new Date();
		$ajax_param ='type='+myBind.inputType+'&item='+myBind.nbrItem+'&name='+myBind.inputName+'&r='+random.getTime();
		if(myBind.prevSelect !== false) $ajax_param+= '&prev='+myBind.prevSelect;

		/* On charge le contenu en AJAX */
		$.ajax({
		  type: 'POST',
		  url: myBind.urlAjax,
		  data: $ajax_param,
		  dataType: 'html',
		  success: function(html) {
		  	myBind.includeContent(html);
  		  if(e != null)	$('#'+myBind.idContainer).fadeIn(myBind.timeAppear); // On lance l'apparition
		  },
		  complete: function() {
		  	$("#"+myBind.idListe+" input[type='"+myBind.inputType+"']:first").focus();
		  	if(e == null) myBind.updResults();
		  }
		});
	},

	includeContent: function(html) {

		this.setSize(html);

		this.posContainer = $('#'+this.idSource).position();
		this.posContainer.top += $('#'+this.idSource).height()+2;

		/* On ajoute la structure au DOM puis on insère le retour AJAX dans cette structure */
  	$('#'+this.idSource).after(this.getStruct());
  	$('#'+this.idListe).html(html);

  	/* On ajoute les evenements sur le contenu */
  	// AFAIRE : voir si pas de problemes de concurence entre les class !
  	if(this.inputType != 'checkbox') { $('#'+this.idContainer+' .nMultInputBouton').hide(); }
  	if(this.strInfo === false) { $('#'+this.idContainer+' .nMultInputInfos').hide(); }
  	if(this.strCheckAll === false && this.strInfo === false) { $('#'+this.idContainer+' .nMultInputHead').hide(); }

  	var myBind = this;
  	$('#'+myBind.idContainer+' .nMultInputAll').bind('click', function(e) { myBind.checkAll(e, true); });
  	$('#'+myBind.idContainer+' .nMultiUncheckAll').bind('click', function(e) { myBind.checkAll(e, false); });
		$('#'+myBind.idContainer+' .nMultInputSubmit').bind('click keydown', function(e) {
			var key = e.charCode || e.keyCode || 0;
			if(key === 0 || key === 9) myBind.hideElem(e);
		});

  	var inputs = $("#"+myBind.idListe+" input[type='"+myBind.inputType+"']");
		if(inputs.length > 0) $(inputs[0]).focus(); /* On met le focus sur le premier element */
  	inputs.bind('click', function() { myBind.updResults(); });
	},

	setSize: function(html) {

		var nbrInput = $(html).find("input[type='"+this.inputType+"']").length;

		var nbrColonne = Math.ceil(nbrInput/this.nbrItem);

		var width = nbrColonne*this.widthCol;

		var height = (this.nbrItem*this.heightItem) + this.heightFoot;
		if(this.strCheckAll != false || this.strInfo != false) height += this.heightHead;

//		alert(this.nbrItem + '*' + this.heightItem + ' + ' +this.heightFoot + ' + ' + this.heightHead);

		this.dimMilieu = [width, height];

		var widthContainer = width+(this.dimCoins[0]*2);
		var heightContainer = height+(this.dimCoins[1]*2);
		this.dimContainer = [widthContainer, heightContainer];
	},

	getStruct: function() {
		return '<div id="'+this.idContainer+'" class="nMultInput" style="display:none;width:'+this.dimContainer[0]+'px;top:'+this.posContainer.top+'px;left:'+this.posContainer.left+'px;"><div class="nMultInputHaut" style="width:'+this.dimContainer[0]+'px;"><div class="nMultInputHG"></div><div class="nMultInputHM" style="width:'+this.dimMilieu[0]+'px;"></div><div class="nMultInputHD"></div></div><div class="nMultInputMilieu" style="width:'+this.dimContainer[0]+'px;height:'+this.dimMilieu[1]+'px;"><div class="nMultInputMG" style="height:'+this.dimMilieu[1]+'px;"></div><div class="nMultInputMM" style="width:'+this.dimMilieu[0]+'px;height:'+this.dimMilieu[1]+'px;"><div class="nMultInputHead"><p class="nMultInputBouton nMultInputAll">'+this.strCheckAll+'</p><p class="nMultInputBouton nMultiUncheckAll">'+this.strUncheckAll+'</p><p class="nMultInputInfos '+this.strInfoClass+'"><em>'+this.strInfo+'</em></p></div><div id="'+this.idListe+'" class="nMultInputListes"></div><div class="nMultInputSubmit"><input type="button" id="nMultInputSubmit-'+this.idSource+'" value="'+this.strValid+'" /></div></div><div class="nMultInputMD" style="height:'+this.dimMilieu[1]+'px;"></div></div><div class="nMultInputBas" style="width:'+this.dimContainer[0]+'px;"><div class="nMultInputBG"></div><div class="nMultInputBM" style="width:'+this.dimMilieu[0]+'px;"></div><div class="nMultInputBD"></div></div></div>';
	},

	hideElem: function(e) {

		if($(e.target).parents('#'+this.idContainer).length === 0 || e.target.parentNode.className == 'nMultInputSubmit') {

			e.stopPropagation(); // Evite de propager l'evenement click sur la méthode listenerTab
			var myBind = this;
			$('#'+myBind.idContainer).hide();
			if(myBind.callback != false && myBind.prevResult != $('#'+myBind.idSource).text()) { eval(myBind.callback); };
			$(document).unbind('click');

			var key = e.charCode || e.keyCode || 0;

			/* Si on ferme puis on enchaine par une tabulation alors on déclenche le listener */
			/* Si on ferme puis on enchaine par un click on annule la prochaine tabulation */
			var targetName = e.target.tagName.toLowerCase();
			var goListenerTab = (key == 9 || (targetName == 'input' && e.target.id != 'nMultInputSubmit-'+this.idSource) || targetName == 'select' || targetName == 'textarea') ? false : true;

			// AFAIRE : Réactiver le listenertab
//			if(goListenerTab) {
//				myBind.boolListenerTab = true;
//				$(document).one('click', function(e) { myBind.boolListenerTab = false; });
//				$(document).one('keydown', function(e) {
//					myBind.listenerTab(e);
//					return false;
//				});
//			}
		}
	},

	listenerTab: function(e) {
		var key = e.charCode || e.keyCode || 0;
		if(key === 9 && this.boolListenerTab) { this.nextFormField.focus(); }
		this.boolListenerTab = false;
	},

	checkAll: function(e, bool) {
		var inputs = $("#"+this.idListe+" input[type='checkbox']");
		jQuery.each(inputs, function() { this.checked = bool; });
		this.updResults();
	},

	updResults: function() {

		var myBind = this;
		var result = [];

		var inputs = $('#'+myBind.idListe+" input[type="+myBind.inputType+"]:checked");
		jQuery.each(inputs, function() {
			var string = $(this).parent().text();
			result[result.length] = (string.substr(0,1) == ' ') ? string.substr(1,string.length) : string;
		});

		var text = (result.length > 0) ? result.join(', ') : myBind.txtOrigin;
		$('#'+myBind.idSource).text(text);
	}
}