//Copyright (C) 2003-2011 AJLSM, Anaphore
//Voir le fichier LICENCE
//$Id: SearchForm.js 21160 2011-11-24 10:55:23Z pdechando $

/**
 * @fileOverview Classe permettant d'initaliser le formulaire de recherche
 * @author Julien Huet
 */
/**
 * @class Classe permettant d'initaliser le formulaire de recherche
 * @augments Operator
 * @augments HelpPanels
 * @augments SuggestManager
 * @author Julien Huet
 */
var SearchForm = new Class(/** @lends SearchForm */{
	Implements: [Operator, HelpPanels, SuggestManager],
	
	/**
	* @private
	* @type SearchFormValidator
	*/
	searchFormValidator: null,
	
	/**
	* @private
	* @type SearchFormSuggest
	*/
	suggest : null,
	
	/**
	* @private
	* @type SearchCdc
	*/
	cdcSearch: null,
	
	/** <strong>Constructor</strong><br/>  */
	initialize: function(){
		//initialisation de variables
		this.cdc_2check_ids = '';
		this.search_help_mode = search_help_mode;
		this.navindex_from_input = '';
		this.suggest_starts_with = '';
		this.dbid = '';
		this.suggest = '';
		this.cdcSearch = '';

		this.searchFormValidator = new SearchFormValidator(this);		
		this.suggest = new SearchFormSuggest(this);
		// Focus sur le premier champs
		this.initFocus();
	},

	/**
	* Fonction d'initialisation du formulaire de recherche
	* @param {Boolean} b_initSuggest 
	* @param {Boolean} b_initSimpleSuggests
	* @param {Boolean} b_initHelp
	* @param {Boolean} b_initCdcSearch
	* @param {Boolean} b_initIndexLinks
	* @param {Boolean} b_update_all_display_op_suggest
	* @param {Boolean} b_init_dyn_display_op_checkbox
	* @param {Boolean} b_init_dyn_display_op_select
	* @param {Boolean} b_initMultipleComboSelect
	* @param {Boolean} b_update_all_display_op_multiple_combo
	*/
	init: function(
		b_initSuggest,
		b_initSimpleSuggests,
		b_initHelp,
		b_initCdcSearch,
		b_initIndexLinks, 
		b_update_all_display_op_suggest,
		b_init_dyn_display_op_checkbox,
		b_init_dyn_display_op_select,
		b_initMultipleComboSelect,
		b_update_all_display_op_multiple_combo
	){
		if ( b_initSuggest ) {
			this.suggest.initSuggests();
		}
		if ( b_initSimpleSuggests ) {
			this.suggest.initSimpleSuggests();
		}
		if ( b_initHelp ) {
			this.initHelp();
		}
		if ( b_initCdcSearch ) {
			this.initCdcSearch();
		}
		if ( b_initIndexLinks ) {
			this.initIndexLinks();
		}
		if ( b_update_all_display_op_suggest ) {
			this.update_all_display_op_suggest();
		}
		if ( b_init_dyn_display_op_checkbox ) {
			this.init_dyn_display_op_checkbox();
		}
		if ( b_init_dyn_display_op_select ) {
			this.init_dyn_display_op_select();
		}
		if ( b_initMultipleComboSelect ) {
			this.suggest.initMultipleComboSelect();
		}
		if ( b_update_all_display_op_multiple_combo ) {
			this.update_all_display_op_multiple_combo();
		}
	},

	/**
	* Fonction permettant de mettre le focus sur un noeud a l'initialisation
	*/
	initFocus: function(){
		var mainContainer;
		if($('search-form')) mainContainer = $('search-form').getFirst('form');
		if(mainContainer){
			var inputsTxtTable = mainContainer.getElements('input.pl-form-txt');
			var again = true;
			for ( var i=0; i< inputsTxtTable.length && again; i++ ) {
				var input = inputsTxtTable[i];
				if ( input.getStyle('display') != 'none' ) {
					// Fix bug : le focus n'est pas bien géré au retour sur un formulaire pour le modifier
					// On en gère plus le focus automatiquement et l'utilisateur active la zone qu'il veut
					//input.focus();
					again = false;
				}
			};
		}
	},
	
	/**
	* Initialisation des boutons et des bulles d'aide YUI
	*/
	initHelp: function() {
		/** [JC] Ici, on a soit l'affichage par un panel, ... */
		if(this.search_help_mode == 'panels'){
			// appel a la methode de la class HelPanelManager afin de creer les panneaux d'aide
			this.initHelpPanels();
		/** Soit l'affichage par un tooltip */
		} else if(this.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 } );
			});
		}
	},

	/**
	* Une fonction pour initiliaser les handler des liens vers des thésaurus
	* ou index.
	*/
	initIndexLinks : function() {
		// On boucle sur les div concernés
		$$('.panel-index').each( function(div) {
			// L'attribut et celui du bouton correspondant, qui partagent une même forme
			var id = div.getAttribute('id');
			var idButton = id + '-button';
			// On lui donne un display block (FIXME: pourquoi, dans le HTML il est à none?)
			div.setStyle('display', 'block');
			
			var panel = new IndexPanel(div, this.cdcSearch);
	
			// On associe un handler au bouton pour l'afficher ou non
			$(idButton).addEvent('click', function() {
				try {
					if ( panel.isVisible() ) {
						panel.hide();
					} else {
						panel.show();
						// On doit charger son contenu si ce n'est déjà fait
						// On passe en paramètre l'objet "cdcSearch" ont le navindex aura besoin pour pouvoir se filtrer
						// par rapport aux choix dans le CdC
						if ( !div.getElement('.ygtvitem')) panel.loadContent();
					}
				}
				catch(e) {
					panel.show();
				}
			});
		}.bind(this));
	},

	/**
	* Fonction permettant d'initialiser le cadre de classement
	*/
	initCdcSearch: function(){
		this.cdcSearch = new SearchCdc(this);
		this.cdcSearch.load();
	},

	/**
	* Ajoute une occurrence pour un critère à sélection multiple.
	* @param {Element} div   Le div où sont affichées les occurrences.
	* @param {String}  value La valeur à ajouter.
	*/
	addOccurrence: function(el, value) {
		if ( el && value ) {
			el = $(el); // Pour être certain d'avoir unescape objet Prototype
			var n = el.id.replace(/\-values/g, '');
			n = n.replace(/\query/g, '');
			var opdisplay = false;
			if ( $('query' + n + '-input').hasClass('dyn_display_op_suggest') ) {
				opdisplay = true;
			}
			var update_display_op_suggest_fn = $empty;
			if ( opdisplay ) {
				update_display_op_suggest_fn = function(){
					searchForm.update_display_op_suggest(n);
				}
			}

			this.addSuggest(el,value,value,update_display_op_suggest_fn);
			if ( opdisplay ) {
				this.update_display_op_suggest(n);
			}
		}
	},

	/**
	* Ajoute une occurrence pour un select combo à sélection multiple.
	* @param {Integer} n      indice du champ
	* @param {String}  select La valeur à ajouter.
	*/
	addOccurrenceFromCombo: function(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()){
				var opdisplay = false;
				if ( select.hasClass('dyn_display_op_multiple_combo') ) {
					opdisplay = true;
				}
				var update_display_op_multiple_combo_fn = $empty;
				if ( opdisplay ) {
					update_display_op_multiple_combo_fn = function(){
						searchForm.update_display_op_multiple_combo(n);
					}
				}
				this.addSuggest(el,valueUI,value,update_display_op_multiple_combo_fn);
				if (opdisplay) {
					this.update_display_op_multiple_combo(n);
				}
			}
		}
	},

	/**
	* reloadNoParam
	*/
	reloadNoParam: function(){
		//les paramétres de l'url
		var params = location.href.substr(location.href.indexOf('?'), location.href.length);

		/*Réinitialisation de la page en fonction du context*/
		if(params.indexOf('base=') == -1){ //on n'est pas dans le context du formulaire. ex subset
			location.href = location.href
		}
		else{ //on est dans le context du formulaire
			location.href = location.pathname;
		}
	},

	/**
	* Prépare les liens hypertextes d'un panneau pour qu'ils recherchent le contenu du panneau.
	* @param {String} classname Classe du lien à modifier (ex : "pl-pg-term")
	* @param {String} divid Id du div qui contient la liste de termes; celui passé à loadIndexContentTerms (ex : "index.content.jsubject")
	* @param {String} field Nom du champ (ex : "fsubject")
	*/
	prepareTermLinks: function(classname, divid, field, indexNum) {
		var terms = $(divid).getElements('.'+classname);
		$A(terms).each(
			function(a) {
				a.addEvent('click', function(event) {
						if ( !$('query' + indexNum + '-input') && !$('query' + indexNum + '-values') && $('query' + indexNum + '_du')!=null ) {
							$('query' + indexNum + '_du').value=event.target.firstChild.nodeValue;
						} else if ( $('query' + indexNum + '-input').hasClass('pl-simple-suggest')) {
							// Cas d'unioccurrence (simple suggest)
							$('query' + indexNum + '-input').value=event.target.firstChild.nodeValue;
						} else {
							var termsContainer = $('query' + indexNum + '-values');
							this.addOccurrence(termsContainer, event.target.firstChild.nodeValue);
							return false;
						}
					}.bind(this)
				);
			}.bind(this)
		);
	},

	updateSelects: function(source, docs, targets, filter) {
		_targets = JSON.decode(targets);
		_targets.each(function(_t){
			_key = (_t.i18nKey) ? _t.i18nKey : '';
			_prefix = (_t.i18nPrefix) ? _t.i18nPrefix : '';
			_catalog = (_t.i18nCatalog) ? _t.i18nCatalog : '';
			this.updateSelect(source, docs+'-'+_t.value+'-slct', _key, _prefix, _catalog, filter);
		}, this);
	},

	/**
	* 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 {Node} source Critere source, element XHTML SELECT (req)
	* @param {String} targetId Identifiant du critere cible utilisé lors de la requete ajax (req)
	* @param {String} FirstOpt Clé i18n ou tout chaine utilisee pour le premier item du critere cible (opt)
	* @param {String} i18nPre Prefixe i18n qui sera utilise lors de la construction de la liste (opt)
	* @param {String} i18nCat Catalogue i18n qui sera utilise lors de la construction de la liste (opt)
	* @param {String} filter Les filtres qui s'appliquent aux criteres (req)
	*/
	updateSelect: function(source, targetId, firstOpt, i18nPre, i18nCat, filter) {
		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*/
		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 = $(source).get('value');
		} catch(e) {
			value = source.value;
		}

		fieldTgt = targetId ? targetId.substring( (targetId.indexOf('-') + 1) , targetId.lastIndexOf('-') ) : field;
		if( fieldSrc.blank() ) return false;
		
		// 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.getParent( '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 = '';
			/* [CB] : on ne reporte pas l'attribut disabled car maintenant que l'on remplit la liste on veut qu'elle soit active !*/
			var includes = [ 'id', 'class', 'style', 'title', 'lang', 'dir', 'name', 'size', 'multiple', 'tabindex', 'onfocus', 'onblur', 'onchange' ];
			for ( var i=0, l=attsSrc.length; i < l; i++ ) {
				if ( attsSrc[i] ) {
					n = attsSrc[i].nodeName;
					v = target.getProperty( 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 + '"';
					}
				}
			}
		}

		// Si on arrive ici avec value vide, c'est que l'on est dans le cas où la liste dépendante est vide au départ
		if ( !value ) {
			// reconstruction
			div.innerHTML = '<select' + atts + ' disabled="disabled">' + '<option value="">'+ _usersMessages.search_form_updateSelect_empty +'</option>' + '</select>';
			// selection du premier item
			$(target).selectedIndex = 0;
			// On exécute le onchange si y en a un
			if ( $(target).getProperty('onchange') != '' && $(target).getProperty('onchange') != null) {
				$(target).onchange();
			}
			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 ) +
				( (filter.blank()) ? '' : filter ) +
				'&field=' + fieldSrc + '&value=' + value;
		params += '&field=' + ( fieldTgt ? fieldTgt : fieldSrc );

		// la requete Ajax qui fait le travail
		var req = new Request({
			url: url,
			method: 'get',
			onSuccess: function(transport) {
				// reconstruction
				div.innerHTML = '<select' + atts + '>' + transport + '</select>';
				// selection du premier item
				$(target).selectedIndex = 0;
				
			}
		});
		req.send(encodeURI(params));
	},
	
	/**
	* Fonction pour effacer le contenu d'un champ
	* @param {String} id
	*/
	clearInput: function(id){
		if($(id)){
			var input = $(id);
			if ( !input.value.blank() ) {
				input.value = '';
			}
		}
	},

	/**
	* ChangeFirstLetter Appellée lorsque l'on change la première lettre dans un navindex eventuellement
	* @param {Object} evt
	* @param {Object} data
	*/
	changeFirstLetter: function(evt, data){
		var url = 'filtered-navindex.xsp?context=' + data.displaycontext + data.filter.replace(/&amp;/g, '&') + '&field=' + data.field + '&hpp=' + data.hpp + '&base=' + data.base;
		if( $('first-letter' + data.indexnum) != 'all') {
			url += '&value=' + $('first-letter' + data.indexnum).get('value') + '*';
			if ( data.filter != '' ) {
				url += '&field=' + data.field;
			}
		}
		url += '&indexnum=' + data.indexnum;
		
		// Récupère les choix dans le CdC dans la query d'appel du sdx et les ajoute ici
		if(data.cdcfilter != '') url += data.cdcfilter.replace(/&amp;/g, '&');
		
		windowManager.loadAjaxContent(url, $(data.parentdivid));
	},

  /**
  * Show/Hide groups
  * @param {String} t
  * @param {Mootools.Element} a
  **/
  toggleGroup: function(t, a) {
    $(t).toggle();
    a.toggleClass('tbody_hidden');
    a.toggleClass('tbody_visible');
  }

});

