/* $Id: module-eadeac-search-form.js 13964 2009-03-11 19:46:01Z cbougouin $ */
/**
Copyright (C) 2003-2008 AJLSM, Anaphore
Voir le fichier LICENCE
**/
/* Ce fichier de configuration fait partie de la distribution standard
de Pleade. Vous pouvez le modifier à votre guise. */
var isSuggests=false;
/*  La liste des critères de type "suggest" dans un tableau de String  */
var suggests = new Array();
var simpleSuggest = new Array();

function initSimpleSuggests(){
	var mid;
	$$('input.pl-simple-suggest').each( function(o){
		mid = o.name;
		if ( mid!=null )
			if( !mid.blank() )
					simpleSuggest.push( mid );
	});
		if( simpleSuggest==null || simpleSuggest.length==0 ) return;
		$A(simpleSuggest).compact().each( function(o,i){
			initSuggest( o, i, 'simple' );
			isSuggests = true;
		});
}

function initSuggests() {
	var mid;
	$$('input.pl-suggest').each( function(o){
		mid = o.name;
		if ( mid!=null )
			if( !mid.blank() )
					suggests.push( mid );
	});
		if( suggests==null || suggests.length==0 ) return;
		$A(suggests).compact().each( function(o,i){
			initSuggest( o, i, 'multiple');
			isSuggests = true;
		});
}

function initSuggest(o, i, mode) {
	var dsXhr = new YAHOO.widget.DS_XHR( "functions/suggest.json", ["results", "text", "option", "freq"] );
	dsXhr.scriptQueryParam = "value";
	/*  INFO:	Boucler sur les critères de type "suggest" et initialiser
						leur auto-complete. On reconnaît un tel critère à ses
						composants :
						1) input/@id='query[0-9]+_input'			: zone de saisie
						2) input/@id='query[0-9]+_field'			: nom du champ
						3)   div/@id='query[0-9]+_container'	: conteneur suggestions
						4)   div/@id='query[0-9]+_values'		: valeurs sélectionnées
	[MP]  */
	var idi = o + "-input",
			idf = o + "-field",
			idc = o + "-container",
			idv = o + "-values";
	if( $(idi)==null
			|| $(idf)==null
			|| $(idc)==null
			|| $(idv)==null ) {
			/* 	On supprime le critère qui n'est pas complet de la liste
						Ca permet de ne pas s'embêter lors de la validation, cf.
						suggest2work() [MP]  */
			suggests.splice(1,1);
			return;
	}
  var sdxdbid = "";
  try{ sdxdbid = dbid; } catch(e){}
	dsXhr.scriptQueryAppend = ( (sdxdbid!="")? "base=" + dbid.split(" ").join('&base=') : "" ) + // l'identifiant de(s) base(s) de documents ; la variable est initialisee dans search.xsl au moment de la construction de la base XHTML
                            "&field=" + $(idf).value;
	var autoComp = new YAHOO.widget.AutoComplete(idi,idc, dsXhr);
	/* 	Modifier le delais d'activation du suggest. 0.2'' par défaut.  */
	autoComp.queryDelay = 0.5;/*  TODO:	Attendre que l'utilisateur ait fini de taper plutot que d'attendre 0.5'' apres que l'utilisateur ait tape la premiere lettre [MP]  */
	autoComp.prehighlightClassName = "yui-ac-prehighlight";
	/* autoComp.typeAhead = true; */
	autoComp.useShadow = true;
	autoComp.maxResultsDisplayed = 10;
  autoComp.useIFrame = true; // NOTE (MP) : Permet aux suggests d'etre correctement affiches dans IE s'ils sont places au-dessus d'une liste (select). Comportement bizarre avec Opera qui rend pas le service inutilisable pour autant : affichage d'un "gros bloc blanc".
	autoComp.animHoriz = true;
	autoComp.minQueryLength = 1;

	/* On surcharge complètement cette méthode */
	autoComp.generateRequest  = function(sQuery) {
		/* Code récupéré depuis YUI 2.6 */
    var dataType = this.dataSource.dataType;

    // Transform query string in to a request for remote data
    // By default, local data doesn't need a transformation, just passes along the query as is.
    if(dataType === YAHOO.util.DataSourceBase.TYPE_XHR) {
        // By default, XHR GET requests look like "{scriptURI}?{scriptQueryParam}={sQuery}&{scriptQueryAppend}"
        if(!this.dataSource.connMethodPost) {
						/* Début surcharge */
						var nQuery = sQuery;
						/* TODO: HACK pour creer une WilcardTermEnum avec * au debut et a la fin
						// troncature au debut et a la fin
						if( sQuery.match(/^\*.+\*$/) ){;}
						else{
							// pas de troncature au debut
							if( !sQuery.match(/^\*.+$/) )
									nQuery = '*' + nQuery;
							// pas de troncature a la fin
							if( !sQuery.match(/^.+\*$/) )
									nQuery = nQuery + '*';
						}
						*/
						nQuery = nQuery.replace(/(%28|%29|%2E|%5B|%5C|%5D%|5E|%7B|%7C|%7D|%3F)/g, "\\$1");// echappe les caracteres reserves en expression reguliere dans la requete utilisateur.
						sQuery = nQuery;
						/* Fin surcharge */
            sQuery = (this.queryQuestionMark ? "?" : "") + (this.dataSource.scriptQueryParam || "query") + "=" + sQuery +
                (this.dataSource.scriptQueryAppend ? ("&" + this.dataSource.scriptQueryAppend) : "");
        }
        // By default, XHR POST bodies are sent to the {scriptURI} like "{scriptQueryParam}={sQuery}&{scriptQueryAppend}"
        else {
            sQuery = (this.dataSource.scriptQueryParam || "query") + "=" + sQuery +
                (this.dataSource.scriptQueryAppend ? ("&" + this.dataSource.scriptQueryAppend) : "");
        }
    }
    // By default, remote script node requests look like "{scriptURI}&{scriptCallbackParam}={callbackString}&{scriptQueryParam}={sQuery}&{scriptQueryAppend}"
    else if(dataType === YAHOO.util.DataSourceBase.TYPE_SCRIPTNODE) {
        sQuery = "&" + (this.dataSource.scriptQueryParam || "query") + "=" + sQuery +
            (this.dataSource.scriptQueryAppend ? ("&" + this.dataSource.scriptQueryAppend) : "");
    }
		return sQuery;
	};
	autoComp.textboxFocusEvent.subscribe(function(){
		var sInputValue = $(idi).value;
		if(sInputValue.length === 0) {
			var oSelf = this;
			setTimeout(function(){oSelf.sendQuery(sInputValue);},0);
		}
	});
	/* 	Pour agir sur le conteneur de resultats, par exemple le placer
				correctement ou le redimensionner. */
	autoComp.doBeforeExpandContainer = function(oTextbox, oContainer, sQuery, aResults) {
		var pos = YAHOO.util.Dom.getXY(oTextbox);
		pos[1] += YAHOO.util.Dom.get(oTextbox).offsetHeight + 2;
		/* Les positions pour la solution temporaire de la liste à droite
		pour parer au bogue IE
		pos[1] += YAHOO.util.Dom.get(oTextbox).offsetHeight - 17;
		pos[0] += YAHOO.util.Dom.get(oTextbox).offsetWidth + 5; */
		// DEBUG: IE a besoin de ce z-index pour afficher la liste des suggests au-dessus des boutons de validation du formulaire
		YAHOO.util.Dom.setStyle(oContainer,"z-index", "1000");
		YAHOO.util.Dom.setXY(oContainer,pos);
    // on ajoute une classe css odd/even sur les li
    var lis = autoComp.getListItems();
    if(lis!=null && lis.length>0){
      var li = null;
      for(var i=0,l=lis.length; i<l; i++){
        li = lis[i];
        if(li!=null){
          YAHOO.util.Dom.addClass(li, ((i % 2 == 0) ? "odd":"even") );
        }
      }
      li=null;
    }
    lis=null;
		return true;
	};
	/* 	Pour formater les resultats ici : texte (docFreq)
	autoComp.formatResult = function(oResultItem, sQuery) {
		return oResultItem[0] + " (" + oResultItem[2] + ")";
	}; */
	autoComp.itemSelectEvent.subscribe(function(event, obj) {
			var value = obj[2][0];	// l'objet est un resultat format JSON suivant le schema definit plus haut
			if(mode != 'simple'){
				addOccurrence($(idv), value);
				$(idi).value = "";
			}
	});
}

/**
*	Ajoute une occurrence pour un critère à sélection multiple.
*
*	@param	div		Le div où sont affichées les occurrences.
*	@param	value	La valeur à ajouter.
*/
function addOccurrence(el, value) {
	if ( el && value ) {
		el = $(el);	// Pour être certain d'avoir unescape objet Prototype
		/*todo : meilleur calcul de n*/
		var n = el.id.gsub('-values','');
		n = n.gsub('query', '');
		// TODO: i18n
		var opdisplay = false;
		if($("query"+n+"-input").hasClassName('dyn_display_op_suggest'))
			opdisplay = true;
		var update_display_op_suggest_string = "";
		if(opdisplay)
				update_display_op_suggest_string = "update_display_op_suggest('" + n + "');";
		el.update(el.innerHTML + '<div class="pl-form-suggest-value"><a href="#" onclick="javascript:Element.extend(this.parentNode).remove();'+ update_display_op_suggest_string +'"> ' + value + '</a></div>');
		if(opdisplay)
			update_display_op_suggest(n);
	}
}

/**
 *	Initialisation des boutons et des bulles d'aide YUI
 */
function initHelp() {
	/** [JC] Ici, on a soit l'affichage par un panel, ... */
	if(search_help_mode == 'panels'){
		$$(".panel-help").each(function(div) {
			div.style.display="block";	//on s'assure que ce sera affiche puisqu'on le cache au chargement de la page
			var id = div.getAttribute("id");
			var idButton = id + "-button";
			var panel = new YAHOO.widget.Panel(id, {
																	underlay: "none",
																	width:"300px",
																	height: "200px",
																	visible:false,
																	draggable:true,
																	constraintoviewport:true,
																	context:[idButton, "tr", "bl"]
																});
			panel.render();
			// Fonction declanchant l'apparition / disparition de l'aide quand on clique sur le bouton
			/** [JC] Ce code ne fonctionnera qu'avec YUI 2.5 */
			/*var resize = new YAHOO.util.Resize(id, {
					handles: ['br'],
					autoRatio: false,
					minWidth: 300,
					minHeight: 200,
					status: true
			});

			// Setup resize handler to update the size of the Panel's body element
			// whenever the size of the 'resizablepanel' DIV changes
			resize.on('resize', function(args) {

					var panelHeight = args.height;

					var headerHeight = this.header.offsetHeight; // Content + Padding + Border
					var footerHeight = this.footer.offsetHeight; // Content + Padding + Border

					var bodyHeight = (panelHeight - headerHeight - footerHeight);
					var bodyContentHeight = (IE_QUIRKS) ? bodyHeight : bodyHeight - PANEL_BODY_PADDING;

					YAHOO.util.Dom.setStyle(this.body, 'height', bodyContentHeight + 'px');

					if (IE_SYNC) {

							// Keep the underlay and iframe size in sync.

							// You could also set the width property, to achieve the
							// same results, if you wanted to keep the panel's internal
							// width property in sync with the DOM width.

							this.sizeUnderlay();

							// Syncing the iframe can be expensive. Disable iframe if you
							// don't need it.

							this.syncIframe();
					}
			}, panel, true);*/


			// Fonction declanchant l'apparition / disparition de l'aide quand on clique sur le bouton
			Event.observe(idButton, "click", function() {
				try {
					if( panel.cfg.getProperty("visible") ) panel.hide();
					else {panel.render();panel.show();}
				} catch(e) { panel.render();panel.show(); }
			});
		});
	/** Soit l'affichage par un tooltip */
	} else if(search_help_mode == 'tooltips'){
		$$(".panel-help").each(function(div) {
			var id = div.getAttribute("id");

			var width = 350;
			var text = div.innerHTML;
			var idButton = id + "-button";
			new YAHOO.widget.Tooltip(id + "-tooltip", { context:idButton, text:text, width:width, container:idButton } );
		});
	}
}

/**
 *	Travail sur le formulaire de recherche avant de l'envoyer.
 */

// un tableau dans lequel on va consigner les erreurs
var arrErrors = new Array();

function form2work( myForm ) {
	if (myForm==null || myForm.elements==0) return false;

	// travail sur les champs suggests
	if ( isSuggests && suggests!=null && suggests.length > 0 )
	{
		$A(suggests).compact().each( function(o,i){
			var idi = o + "-input",
					idv = o + "-values";
			if( $(idi) && $(idv) )
          suggest2work( $(idi), $(idv) );
		});
	}

	// travail sur les combo multiple
	$$('select.pl-form-slct-multiple-combo').each(function(select){
		var n = select.name.gsub('query','');
		var myValues = $('query'+n+'-values'); // le conteneur de toutes les values
		multipleCombo2work(select, myValues);
	});

	// travail sur les champ à tronquer automatiquement
	$$('input.pl-form-truncate-left').each(function(input){
		if(!input.value.blank())
			 input.value = '*' + input.value;
	});
	$$('input.pl-form-truncate-right').each(function(input){
		if(!input.value.blank())
			 input.value = input.value + '*';
	});
	$$('input.pl-form-truncate-both').each(function(input){
		if(!input.value.blank())
			 input.value = '*' + input.value + '*';
	});
	// Initialise le tableau des erreurs au cas ou il ne serait pas vide
	arrErrors.clear();

	// verification du remplissage du formulaire
		var errMessage = "";
		var errFieldID = "";

		// verification des formats (si le champ n'est pas vide)
		$$('a.format').each( function(a,i){
				var formatRegexp =  "^" + a.getAttribute('title') + "$";
				var targetID = a.getAttribute('target');
        var target = $(targetID);
				if(target!=null){
					var value = target.getValue();
					if(!value.blank() && value.search(formatRegexp) != 0){
            errMessage = '"' + value + '"' + _usersMessages.search_form_msg_format_not_valid + getLabel('label' + getN(target.name));
            errFieldID = targetID;
            addErrorMessage(errMessage, errFieldID);
          }
				}
		});

		// Verifications sur les dates
		var dbID = "";
		var deID = "";
		var duID = "";
		// on récupère les input de date (au passage on les mets à chaîne vide s'ils contiennent que des espaces)
		$$('input.pl-form-date').each(function(input){
				if(input.name.match(/db\d/g)){
					dbID = input.id;
				}
				if(input.name.match(/de\d/g)){
					deID = input.id;
				}
				if(input.name.match(/du\d/g)){
					duID = input.id;
				}
				if(input.value.blank())
					input.value = "";
		});


		// Verification db < de (uniquement quand ce sont des années)
		if(dbID!='' && deID!=''){
			var db = $(dbID).getValue() ;
			var de = $(deID).getValue() ;
			// dans le cas ou "db" et "de" sont des années correctement remplies, on verifie l'ordre
			if( db.match(/^(\d)+$/) && de.match(/^(\d)+$/) ){
				if( parseInt(db) > parseInt(de) ){
					errMessage = _usersMessages.search_form_msg_date_unordered;
					errFieldID = dbID + ',' + deID;
					addErrorMessage(errMessage, errFieldID);
				}
			}
		}

		// Verification que tous les champs ne sont pas vides
		var countEmptyFields = 0;
		var countFields = 0;
		$(myForm).getElements().each(function(el,i){
				if(el.name.indexOf('query') != -1 ||
           el.name.indexOf('du') != -1 ||
           el.name.indexOf('db') != -1 ||
           el.name.indexOf('de') != -1 ||
           el.name.indexOf('date') != -1 ||
           el.name.indexOf('from') != -1 ||
           el.name.indexOf('to') != -1)
        {
					countFields += 1;
					// un checkbox non coché aura un getValue() = "null"
					if(el.getValue()=='' || el.getValue() == null){
						countEmptyFields += 1;
					}
				}
		});
		if(countEmptyFields == countFields){
			errMessage = _usersMessages.search_form_msg_all_fields_empty;
			errFieldID = "";
			addErrorMessage(errMessage, errFieldID);
		}

	// Travail sur le champ "cdc"
	var cdcvalue = "";
	var cdcinputs = $(myForm).getInputs("checkbox", "_cdcid");
	cdcinputs.each(function(o){
		if ( o.getValue() != null ) {
			if ( cdcvalue != "" ) cdcvalue += sep;
			cdcvalue += o.getValue();
		}
	});
	if ( cdcvalue != "" )
		$$("input.pl-cdc")[0].value = cdcvalue;

	// Travail sur les critères "alternate field"
	var altinputs = $(myForm).getInputs("checkbox");
	altinputs.each(function(cb) {
		if (cb.name.substring(0,3) == "alt" && cb.checked) {
			// On va seulement modifier le paramètre du champ à chercher
			var no = cb.name.substring(3);
			var fieldId = "champ" + no;
			if ($(fieldId)) $(fieldId).value = cb.value;
			// Idem pour le champ "h" s'il existe
			fieldId = "champh" + no;
			if ($(fieldId) && $("h" + cb.name)) {$(fieldId).value = $F("h" + cb.name)};
		}
	});

	// Résultat de la fonction : s'il y a des erreurs on les affiche sans valider, sinon on valide
	if(arrErrors.length > 0){
		displayErrors(myForm);
		return false;
	}
	else{
		return true;
	}
}

// Ajoute un message d'erreur dans le tableau des erreurs
function addErrorMessage(message, fieldID){
	arrErrors.push( { "message" : message , "fieldID" : fieldID } );
}

// Affiche une message d'erreur
function displayErrors(myForm){
	// Enlève l'éventuelle surbrillance sur les anciennes erreurs
	myForm.getElements().each(function(el){
      el.removeClassName('pl-form-error');
	});
	// Pour chaque (nouvelle) erreur, on affiche le message et on mets en surbrillance l'élément
	var errBox = $$("div.pl-form-errors")[0];
	errBox.innerHTML = "";
    arrErrors.each(function(error){
        errBox.innerHTML += error.message + "<br/>";
        $A(error.fieldID.split(',')).each(function(fieldID){
            if($(fieldID)){
                $(fieldID).addClassName('pl-form-error');
            }
        })
    });
    errBox.show();
    var p = errBox.up('div.pl-form-message');
    if (p) p.show();
}

function getLabel(id){
	if($(id)){
		var td = $(id);
	return Try.these(
		function(){
			var select = td.down('select');
			return select.options[select.selectedIndex].innerHTML
		},
		function(){
			return td.innerHTML
		}
		)
	}
}

function getN(string){
	return string.match(/\d+/g);
}

function clearInput(id){
	if($(id)){
		var input = $(id);
		if(!input.value.blank())
			input.value = "";
	}
}

function reloadNoParam(formID){
	var nameParam = ""
	if(!formID.blank())
		nameParam = '?name=' + formID;
	location.href = location.pathname + nameParam;
}

/**
 * Fonction utilisee dans l'implementation des listes dependante
 * La fonction est appelee par le critere source. Elle recupere la liste des
 * items (option) qui sera utilisee pour mettre a jour le critere cible.
 *
 * La fonction ne peut fonctionner qu'avec des criteres source et cible de
 * SELECT. La cible doit obligatoirement etre incluse dans un element DIV, ceci
 * afin de palier au bogue IE pour lequel la mise a jour du contenu d'un SELECT
 * ne fonctionne pas.

 * Les identifiants des criteres source et cible doivent etre construit suivant
 * le partron : {nom de la base de recherche}-{nom du champ}-slct
 *
 * @param source {Node}     Critere source, element XHTML SELECT (req)
 * @param targetId {String} Identifiant du critere cible (req)
 * @param FirstOpt {String} Clé i18n ou tout chaine utilisee pour le premier item du critere cible (opt)
 * @param i18nPre {String}  Prefixe i18n qui sera utilise lors de la construction de la liste (opt)
 * @param i18nCat {String}  Catalogue i18n qui sera utilise lors de la construction de la liste (opt)
 *
 * Cette fonction depend completement de la librairie Javascript Prototype
 * (version 1.5, version utlterieure non testee).
 */
function updateSelect(source, targetId, firstOpt, i18nPre, i18nCat) {

  // DEBUG alert("dans updateSelect avec source:"+source+", targetId:"+targetId+", firstOpt:"+firstOpt+", i18nPre:"+i18nPre+", i18nCat:"+i18nCat);

  if (!source) return false;

  // recuperation des noms de base, champ source, valeur source, champ cible
  var idSrc = "", base = "", fieldSrc = "", valueSrc = "", idTgt = "", fieldTgt = "", value = "";
  idSrc = source.id; // construit suivant le patron : ({base}-)?{champ}-slct
  if (idSrc.blank()) return false;
  base = idSrc.substring( 0, idSrc.indexOf("-") );
  fieldSrc = idSrc.substring( (idSrc.indexOf("-") + 1), idSrc.lastIndexOf("-") );
  try {
    value = $F(source);
  } catch(e) {
    value = source.value;
  }
  fieldTgt = targetId ? targetId.substring( (targetId.indexOf("-") + 1) , targetId.lastIndexOf("-") ) : field;

  if( fieldSrc.blank() || !value ) return false;

  // l'URL
  var url = "functions/sdx-terms-options.txt";
  var params = ( (base.blank()) ? "" : "base=" + base ) +
               ( (i18nPre.blank()) ? "" : "&i18n-prefixe=" + i18nPre ) +
               ( (i18nCat.blank()) ? "" : "&18n-catalogue=" + i18nCat ) +
               ( (firstOpt.blank()) ? "" : "&first-option=" + firstOpt ) +
               "&field=" + fieldSrc + "&value=" + value;
  params += "&field=" + ( fieldTgt ? fieldTgt : fieldSrc );

  // la requete Ajax qui fait le travail
  new Ajax.Request(url + '?' + params, {
    method: 'get',
    /*parameters: params,*/
    onSuccess: function(transport) {

      // la cible : on en a une ou elle est confondue avec la source
      var target = targetId ? $(targetId) : source;
      if( !target ) return false;
      var div = target.up( 'div' );
      if( !div ) return false;

      // reconstruction du select cible : 1- attributs, 2- premiere option, 3- innerHTML
      // on filtre les attributs suivant la liste donnees par la DTD HTML 4.x ; si on ne filtre pas , sous IE, on peut avoir une liste assez impressionnant d'attributs inutiles
      var atts = "";
      var attsSrc = target.attributes;
      if ( attsSrc ) {
        var n = "", v = "";
        var includes = [ "id", "class", "style", "title", "lang", "dir", "name", "size", "multiple", "disabled", "tabindex", "onfocus", "onblur", "onchange" ];
        for ( var i=0, l=attsSrc.length; i < l; i++ ) {
          if ( attsSrc[i] ) {
            n = attsSrc[i].nodeName;
            // v = attsSrc[i].nodeValue;
            v = target.readAttribute( n ); // methode Prototype pour retourner la valeur d'un attribut : "it cleans up the horrible mess Internet Explorer makes when handling attributes."
            if (n && v && $A(includes).indexOf(n)!=-1) {
              atts += " " + n + '="' + attsSrc[i].nodeValue + '"';
            }
            // DEBUG else alert("bloque: "+n+" = " +v);
          }
        }
      }

      // reconstruction
      // DEBUG alert("avant:\n"+div.innerHTML);
      div.innerHTML = '<select' + atts + '>' + transport.responseText + '</select>';
      //DEBUG alert("apres:\n"+div.innerHTML);

      // selection du premier item
      $(target).selectedIndex = 0;

    }
  });
}

/**
*	Une fonction pour initiliaser les handler des liens vers des thésaurus
*	ou index.
*/
function initIndexLinks() {

	// On boucle sur les div concernés
	$$(".panel-index").each( function(div) {

		// On lui donne un display block (FIXME: pourquoi, dans le HTML il est à none?)
		div.style.display = "block";

		// L'attribut et celui du bouton correspondant, qui partagent une même forme
		var id = div.getAttribute("id");
		var idButton = id + "-button";

		// La taille du panneau dépend du type
		var width = "250px";
		var height = "200px";
		if ( div.hasClassName("panel-index-terms") ) {
			width = "400px";
			height = "600px";
		}

		// On crée le panel YUI
		var panel = new YAHOO.widget.Panel(id, {
				underlay: "none",
				width: width,
				height: height,
				visible: false,
				draggable: true,
				constraintoviewport: true,
				context: [idButton, "bl", "tr"]
			}
		);

		// On le prépare
		panel.render();

		// On associe un handler au bouton pour l'afficher ou non
		Event.observe(idButton, "click", function() {
			try {
				if ( panel.cfg.getProperty("visible") ) panel.hide();
				else {
					panel.render();
					panel.show();
					// On doit charger son contenu si ce n'est déjà fait
					if ( div.getElementsByClassName("ygtvitem").length == 0 ) loadIndexContent(div);
				}
			}
			catch(e) {
				panel.render();
				panel.show();
			}
		});
	});
}

/**
*	Charge le contenu d'un index dans un panneau.
*/
function loadIndexContent(div) {
	// Des informations importantes proviennent de l'identifiant qui est de la forme:
	//	form.panel-index.{champ}.{type}.{index-id}
	var id = div.getAttribute("id");
	var idParts = id.split("\.");
	var indexId = idParts[5];
	var indexType = idParts[4];

	var bdid = div.down("div.bd").getAttribute("id");
	var bdidParts = bdid.split("\.");
	var indexNum = bdidParts[7];

	// On doit trouver le div qui contiendra le contenu dans le panel
	var contentDiv = $("index.content." + indexId);
	// Maintenant on appelle la bonne méthode, selon le type d'index
	if ( indexType == "thesx" ) loadIndexContentThesx(indexId, contentDiv);
	else if (indexType == "terms" ) loadIndexContentTerms(indexId, contentDiv, indexNum);
}

/**
*	Charge le contenu d'une liste de termes dans un panneau.
*/
function loadIndexContentTerms(termsId, div, indexNum) {
	// La ou les base(s) de documents
	var baseParam = "";
	$$('input.pl-form-srch-base').each( function(o){
		bs = o.value;
		if ( bs!=null ) baseParam += '&base='+ bs;
	});
	// L'URL à appeler au départ
	var url = "navindex.xsp?context=search-form-panel&field=" + termsId + "&indexnum=" + indexNum + baseParam;
	//if( navindex_from_input == 'true' && value != '') url += '&value=' + value + '*';
	// Une fonction générique pour charger du contenu dans un div depuis Ajax
	loadAjaxContent(url, div);
}

/**
*	Charge une URL dans un div.
*/
function loadAjaxContent(url, div) {
	var req = new Ajax.Updater($(div), url, {evalScripts: true});
}

/**
*	Prépare les liens hypertextes d'un panneau pour qu'ils recherchent le contenu du panneau.
*	@param classname	Classe du lien à modifier (ex : "pl-pg-term")
*	@param divid		Id du div qui contient la liste de termes; celui passé à loadIndexContentTerms (ex : "index.content.jsubject")
*	@param field		Nom du champ (ex : "fsubject")
*/
function prepareTermLinks(classname, divid, field, indexNum) {
	// $(divid).getElementsByClassName(classname).each(
  var terms = $(divid).getElementsByClassName(classname);
	$A(terms).each(
		function(a) {
			a.observe('click', function(event) {
					if ($("query" + indexNum + "-input").hasClassName('pl-simple-suggest')) { // Cas d'unioccurrence (simple suggest)
						$("query" + indexNum + "-input").value=event.element().childNodes[0].nodeValue;
					}
					else {
						var termsContainer = $("query" + indexNum + "-values");
						addOccurrence(termsContainer, event.element().childNodes[0].nodeValue);
						return false;
					}
				}
			);
		}
	);
}

/*
*	Charge le contenu d'un thésaurus dans un panneau
*/
function loadIndexContentThesx(thesId, div) {
	// L'URL à appeler
	var url = "functions/thesx/functions/" + thesId + "/list-concepts/__thesx__root__.json";
	// Le TreeView
	var tree = new YAHOO.widget.TreeView(div);
	// On doit intercepter les clicks sur les éléments au niveau de l'arbre, pas de chaque éléments individuellement
	tree.subscribe("clickEvent", thesxTVLabelClick);
	// La racine du TreeView YUI
	var root = tree.getRoot();
	// On appelle la méthode générique pour gérer la navigation
	thesxTVHandler(root, null, url, true);
}

/**
*	Handler pour le JSON de ThesX et son affichage dans un TreeView
*	@param	parent			Le noeud TV parent où afficher le contenu
*	@param	fnLoadComplete	La fonction à appeler une fois le contenu chargé (peut être null)
*	@param	url				L'URL du contenu (format json)
*	@param	draw			Indique si oui ou non on doit lancer l'affichage du TV (donner true uniquement pour la racine)
*/
function thesxTVHandler(parent, fnLoadComplete, url, draw) {
	// On ajuste l'URL
	var realUrl = url;
	if ( !realUrl ) realUrl = parent.href;
	// On va chercher le contenu en Ajax
	var req = new Ajax.Request(realUrl, {
			method: "get",
			onSuccess: function(r) {
				// On reçoit un array d'objets avec des propriétés thesid, id, nom, children et href
				var entries = r.responseText.evalJSON();
				// On boucle sur les objets obtenus et on construit pour chacun un noeud dans l'arbre
				entries.each(function(n) {
					var newNode = new YAHOO.widget.HTMLNode('<span class="tree_labels">' + n.nom + '</span>', parent, false);
					if (n.href) { // Il pourrait ne pas y avoir de lien
						newNode.href = "functions/thesx/functions/" + n.thesid + "/list-concepts/" + n.id + ".json";
					}
					// On conserve des propriétés
					newNode.id = n.id;
					newNode.type = n.type;
					newNode.label = n.nom;
					if (n.children) newNode.setDynamicLoad(thesxTVHandler);
					if (fnLoadComplete) fnLoadComplete();
				});
				if (draw) parent.tree.render();
			}
		}
	);
}

/**
*	Fonction appelée lorsqu'un clic survient sur une entrée du thésaurus.
*/
function thesxTVLabelClick(args) {
	n = args.node;
	// On doit trouver l'identifiant du div qui recevra la valeur
	// Ce div est de classe pl-form-suggest-values et il se situe
	// à l'intérieur du même te que le div du TV
	var tr = null;
	$(n.tree.id).ancestors().each(function(a) {
			if ( a.tagName.toLowerCase() == "tr" && tr == null ) {
				tr = a;
				$break;
			}
	});
	var div = tr.getElementsByClassName("pl-form-suggest-values")[0];
	// On doit l'ajouter dans la liste des occurences
	addOccurrence(div, n.label);
	return false;
}

/**
*	Ensemble de fonctions qui permettent de gerer l'affichage des operateurs intra-champ selon le nombre de selections courantes
*/

/* Fonction appelée au chargement de la page pour initialiser l'affichage (ou non) des operateurs
	 intra-champ les listes deroulantes a selection multiple */
function init_dyn_display_op_select(){
	//DEBUG	alert("init_dyn_display_op_select()");
	// mettre a jour l'affichage des operateurs intra-champ pour les select
	update_all_display_op_select();
	// pour tous les select avec class="dyn_display_op" on initialise le onchange pour afficher les operateurs intra-champs
	$$('select.dyn_display_op_select').each(function(select){
	 var n = select.name.gsub('query','');
	 Event.observe( select, 'change', function(){update_display_op_select(n, this)} )
	});
}

/* Fonction appelée au chargement de la page pour initialiser l'affichage (ou non) des operateurs
	 intra-champ des listes type checkbox (avec @op-display=true) */
function init_dyn_display_op_checkbox(){
	//DEBUG	alert("init_dyn_display_op_checkbox()");
	// mettre a jour l'affichage des operateurs intra-champ pour les checkbox
	update_all_display_op_checkboxList();
	// pour tous les span avec class="dyn_display_op_checkbox" on initialise le onchange pour afficher les operateurs intra-champs
	$$('span.dyn_display_op_checkbox').each(function(span){
	 var n = span.id.gsub('checkbox_container','');
	 //DEBUG alert("span.dyn_display_op_checkbox [n=" + n + "]" );
	 span.select('input.pl-form-chckbx').each(function(checkbox){
		Event.observe( checkbox, 'change', function(){ update_display_op_checkboxList(n) } )
	 });
	});
}

/* Mise a jour de l'affichage des operateurs intra-champ pour tous les checkbox */
function update_all_display_op_checkboxList(){
	$$('span.dyn_display_op_checkbox').each(function(span){
	 var n = span.id.gsub('checkbox_container','');
	 update_display_op_checkboxList(n);
	});
}

/* Mise a jour de l'affichage des operateurs intra-champ pour les checkbox du champ "n" */
function update_display_op_checkboxList(n){
	//DEBUG alert("update_display_op_checkboxList("+n+")")
	var span = $('checkbox_container' + n);
	var opsid = "ops"+n;
	var countSelected = 0;
	 span.select('input.pl-form-chckbx').each(function(checkbox){
		if( checkbox.checked && !checkbox.value.blank() )
			countSelected++;
	 });
	 //DEBUG	 alert( "[n=" + n + "]" +countSelected + " checkbox coché(s)");
	 if(countSelected >= 2)
		 $(opsid).style.display='block';
	 else
		$(opsid).style.display='none';
}

/* Mise a jour de l'affichage des operateurs intra-champ pour toutes les listes déroulantes caracterisée par la class "dyn_display_op_select_multiple" */
function update_all_display_op_select(){
	//DEBUG	alert('update_all_display_op_select()')
	// pour les select multiple
	$$('select.dyn_display_op_select').each(function(select){
	 var n = select.name.gsub('query','');
	 var opsid = 'ops'+n
	 update_display_op_select(n, select);
	});
}

/* Mise a jour de l'affichage des operateurs intra-champ pour tous les champs de type suggest caracterisé par la class "dyn_display_op_suggest" */
function update_all_display_op_suggest(){
	//DEBUG	alert('update_all_display_op_suggest()')
	$$('input.dyn_display_op_suggest').each(function(input){
		var n = input.name.gsub('query','');
		update_display_op_suggest(n);
	});
}

/* Mise a jour de l'affichage des operateurs intra-champ pour tous les champs de type "multiple combo" caracterisé par la class "dyn_display_op_multiple_combo" */
function update_all_display_op_multiple_combo(){
	//DEBUG	alert('update_all_display_op_multiple_combo()')
	$$('select.dyn_display_op_multiple_combo').each(function(select){
		var n = select.name.gsub('query','');
		update_display_op_multiple_combo(n);
	});
}

/* Mise a jour de l'affichage des operateurs intra-champ d'une liste déroulante a selection multiple */
function update_display_op_select(n, select){
	//DEBUG	alert("update_display_op_select("+n+", "+select+")");
	var opsid = "ops"+n;
	var countSelected = 0;
	$A(select.options).each(function(o,i){
		if(o.selected && !o.value.blank())
			countSelected++
	});
	//DEBUG	alert(countSelected + " option(s) selectionnée(s)");
	if(countSelected >= 2)
		$(opsid).style.display='block';
	else
		$(opsid).style.display='none';
}

/* Mise a jour de l'affichage des operateurs intra-champ d'un champ de type suggest */
function update_display_op_suggest(n){
	//DEBUG	alert("update_display_op_suggest("+n+")");
	var opsid = "ops"+n;
	var idv = "query" + n + "-values";
	var suggestsValuesEl = $(idv);
	var countSelected = suggestsValuesEl.childElements().length;
	/*BUG sous IE avec select sur des elements ajoutés dynamiquement
	suggestsValuesEl.select('div.pl-form-suggest-value').each(function(div){
		//DEBUG	alert(div.innerHTML);
		countSelected++
	});*/
	//DEBUG	alert(countSelected + " suggestion(s) selectionnée(s)");
			if(countSelected >= 2)
			$(opsid).style.display='block';
		else
			$(opsid).style.display='none';
}

/* Mise a jour de l'affichage des operateurs intra-champ d'un champ de type "multiple combo" */
function update_display_op_multiple_combo(n){
	//DEBUG	alert("update_display_op_multiple_combo("+n+")");
	var opsid = "ops"+n;
	var idv = "query" + n + "-values";
	var suggestsValuesEl = $(idv);
	var countSelected = suggestsValuesEl.childElements().length;
	//DEBUG	alert(countSelected + " suggestion(s) selectionnée(s)");
	if(countSelected >= 2)
			$(opsid).style.display='block';
		else
			$(opsid).style.display='none';
}



/***
* Fonction pour l'initialisation des list combo a plusieurs entrée (type suggest)
***/
function initMultipleComboSelect(){
	//DEBUG alert("initMultipleComboSelect");
	$$('select.pl-form-slct-multiple-combo').each(function(select){
	 var n = select.name.gsub('query','');
	 Event.observe( select, 'change', function(){addOccurrenceFromCombo(n, select)} )
	});
}

/**
*	Ajoute une occurrence pour un select combo à sélection multiple.
*
*	@param	n		indice du champ
*	@param	value	La valeur à ajouter.
*/
function addOccurrenceFromCombo(n, select) {
	//DEBUG	alert( "addOccurrenceFromCombo(" + n + ", " + select + ")" )
	if ( n && select) {
		var el = $('query'+n+'-values');
		var value = select.options[select.selectedIndex].value;
		var valueUI = select.options[select.selectedIndex].innerHTML;
		if(el!=null && !value.blank()){
		// TODO: i18n
		var opdisplay = false;
		if(select.hasClassName('dyn_display_op_multiple_combo'))
			opdisplay = true;
		var update_display_op_multiple_combo_string = "";
		if(opdisplay)
				update_display_op_multiple_combo_string = "update_display_op_multiple_combo('" + n + "')";
		el.update(el.innerHTML + '<div class="pl-form-select-value"><img onclick="javascript:Element.extend(this.parentNode).remove();'+ update_display_op_multiple_combo_string +';" src="theme/images/pl-form-delete.png" alt="Supprimer" /><span class="displayed-value"> ' + valueUI + '</span><span style="display:none;" class="real-value">' + value + '</span></div>');
		if(opdisplay)
			update_display_op_multiple_combo(n);
		}
	}
}

function multipleCombo2work(mySelect, myValues) {
	//DEBUG	alert( "multipleCombo2work(" + mySelect + ", " + myValues + ")" );
	if( mySelect==null
			|| myValues==null ) return false;
	// le select devient un input pour etre envoyé avec le concatenation des "value"
	var name = mySelect.name;
	var myInputString = '<input type="text" name="' + name + '" class="inputFromSelect" />';
	//alert(myInputString)
	mySelect.replace(myInputString);
	var myInput = $(myValues).up().down('input.inputFromSelect');
	$(myValues).select("span.real-value").each( function( o,i ) {
		if( !o.empty() ){
			var v = o.innerHTML.stripTags().strip();
			if ( myInput.value.indexOf( v ) != -1 ) // la valeur y est deja, on continue
					return;
			else if( i!=0 || !myInput.getValue().blank() )
					myInput.value += sep + v;
			else
					myInput.value += v;
		}
	});
}

function changeFirstLetter(evt, data ){
	var url = 'navindex.xsp?context=' + data.displaycontext + '&field=' + data.field + '&hpp=' + data.hpp + '&base=' + data.base;
	if( $F("first-letter" + data.indexnum) != 'all')
		url += '&value=' + $F("first-letter" + data.indexnum) + '*';
	url += '&indexnum=' + data.indexnum;
	loadAjaxContent(url, data.parentdivid);
}

