var _searchId = 1;
var _lastIdSearch = null;

ajax.tabSearch = new Array();  

ajax.search = function(form, field, submit) {
	// Identifiant de la recherche
	var id = "suggests" + _searchId;
	this.idSearch = id;
	_searchId++;

	window[id] = this;
	ajax.tabSearch.push(this);

	// Paramétres
	this.documentForm = form;
	this.inputField = field;
	this.submitButton = submit;

	// Désactiver l'aide à la saisie du navigateur
	this.inputField.setAttribute("autocomplete", "off");

	// Div contenant les suggestions
	this.completeDiv = null;
	this.completeDivRows = 0;
	this.completeDivDivList = null;

	// Données par défaut
	this.creeAutocompletionDiv();
	this.currentInputFieldValue = this.inputField.value;
	this.oldInputFieldValue = this.currentInputFieldValue;
	this.valeur = '';

	// Evenements
	this.eventKeycode = null;
	this.cursorUpDownPressed = null;

	// Gestionnaires d'évenement
	this.inputField.onkeyup = this.onKeyUpHandler;
	this.inputField.onblur = this.onBlurHandler;
	window.onresize = function(event) {
		// Recalcule la taille des suggestions
		window[id].setCompleteDivSize();
	};

	// Premier déclenchement de la fonction dans 1 seconde
	setTimeout("window." + id + ".mainLoop()", 1000);
}

ajax.search.prototype =
{
	// Tourne en permanence pour suggérer suite à un changement du champ texte
	mainLoop: function() {
		// Nouvelle valeur
		if(this.oldInputFieldValue != this.currentInputFieldValue) {
			var suggestions = obtenirCache(this.currentInputFieldValue);
			this.valeur = escapeURI(this.currentInputFieldValue);
	
			if(suggestions)
				this.mettreEnPlace(suggestions);
			else {
				_lastIdSearch = this.idSearch;
				ajaxLoader(_rootPath + 'includes/ajax.php', 'search', 'valeur=' + this.valeur);
			}
	
			this.inputField.focus();
		}
	
		this.oldInputFieldValue = this.currentInputFieldValue;
		// La fonction sera relancée dans Xms
		setTimeout("window." + this.idSearch + ".mainLoop()", 300);
		return true;
	},

	creeAutocompletionDiv: function() {
		this.completeDiv = document.createElement("div");
		this.completeDiv.id = "search_" + this.idSearch;
		this.setCompleteDivSize();
		document.body.appendChild(this.completeDiv);
		this.completeDiv.className = "search_suggests AutoCompleteDivListeStyle";
		this.hideCompleteDiv();
	},

	mettreEnPlace: function(liste) {
		while(this.completeDiv.childNodes.length > 0)
			this.completeDiv.removeChild(this.completeDiv.childNodes[0]);
	
		// Mise en place des suggestions
		for(var f = 0; f < liste.length; ++f) {
			var nouveauDiv = document.createElement("DIV");
			// Evénements sur la div
			nouveauDiv.className = "AutoCompleteDiv";
			nouveauDiv.onmousedown = this.divOnMouseDown;
			nouveauDiv.onmouseover = divOnMouseOver;
			nouveauDiv.onmouseout = divOnMouseOut;
	
			var nouveauSpan = document.createElement("SPAN");
			// Texte de la suggestion
			nouveauSpan.innerHTML = liste[f];
			nouveauDiv.appendChild(nouveauSpan);
			this.completeDiv.appendChild(nouveauDiv);
		}
	
		this.pressAction();
	
		if(this.completeDivRows > 0)
			this.completeDiv.height = 16 * this.completeDivRows + 4;
		else
			this.hideCompleteDiv();
	},

	// calcule la largeur du champ
	calculateWidth: function() {
		return this.inputField.offsetWidth - 2;
	},

	setCompleteDivSize: function() {
		if(this.completeDiv) {
			this.completeDiv.style.left = calculateOffsetLeft(this.inputField) + "px";
			this.completeDiv.style.top = (calculateOffsetTop(this.inputField) + this.inputField.offsetHeight - 1) + "px";
			this.completeDiv.style.width = this.calculateWidth() + "px";
		}
	},

	// Change la suggestion sélectionnée. Traite les touches haut, bas et enter
	handleCursorUpDownEnter: function(eventCode) {
		if(eventCode == 40) {
			this.highlightNewValue(_highlightedSuggestionIndex + 1);
			return false;
		} else if(eventCode == 38) {
			this.highlightNewValue(_highlightedSuggestionIndex - 1);
			return false;
		} else if(eventCode == 13 || eventCode == 3)
			return false;
	
		return true;
	},

	// gère une touche pressée autre que haut/bas/enter
	pressAction: function() {
		_highlightedSuggestionIndex = -1;
		var suggestionList = this.completeDiv.getElementsByTagName("div");
		var suggestionLongueur = suggestionList.length;

		// On stocke les valeurs précédentes
		// Nombre de possibilités de complétion
		this.completeDivRows = suggestionLongueur;
		// Possibilités de complétion
		this.completeDivDivList = suggestionList;
	
		// Si le champ est vide, on cache les propositions de complétion
		if(this.currentInputFieldValue == "" || suggestionLongueur == 0)
			this.hideCompleteDiv();
		else
			this.showCompleteDiv();
	
		var trouve = false;
		// si on a du texte sur lequel travailler
		if(this.currentInputFieldValue.length > 0) {
			var indice;
			// T vaut true si on a dans la liste de suggestions un mot commencant comme l'entrée utilisateur
			for(indice = 0; indice < suggestionLongueur; indice++) {
				if(getSuggestion(suggestionList.item(indice)).toUpperCase().indexOf(this.currentInputFieldValue.toUpperCase()) == 0) {
					trouve = true;
					break;
				}
			}
		}
	
		// On désélectionne toutes les suggestions
		for(var i = 0; i < suggestionLongueur; i++)
			suggestionList.item(i).className = "AutoCompleteDiv";
	
		// Si l'entrée utilisateur (n) est le début d'une suggestion (n-1) on sélectionne cette suggestion avant de continuer
		if(trouve) {
			_highlightedSuggestionIndex = indice;
			_highlightedSuggestionDiv = suggestionList.item(_highlightedSuggestionIndex);
		} else {
			_highlightedSuggestionIndex = -1;
			_highlightedSuggestionDiv = null;
		}
	
		var supprSelection = false;
	
		switch(this.eventKeycode) {
			// cursor left, cursor right, page up, page down...
			case 8:
			case 33:
			case 34:
			case 35:
			case 35:
			case 36:
			case 37:
			case 39:
			case 45:
			case 46:
				// on supprime la suggestion du texte utilisateur
				supprSelection = true;
			break;
		}
	
		// si on a une suggestion (n-1) sélectionnée
		if(!supprSelection && _highlightedSuggestionDiv) {
			_highlightedSuggestionDiv.className = "AutoCompleteDivAct";
			var z;
			if(trouve)
				z = getSuggestion(_highlightedSuggestionDiv).substr(0);
			else
				z = this.currentInputFieldValue;
	
			if(z != this.inputField.value) {
				if(this.inputField.value != this.currentInputFieldValue)
					return;
		
				// Si on peut créer des range dans le document
				if(this.inputField.createTextRange || this.inputField.setSelectionRange)
					this.inputField.value = z;
	
				// On sélectionne la fin de la suggestion
				if(this.inputField.createTextRange) {
					var t = this.inputField.createTextRange();
					t.moveStart("character", this.currentInputFieldValue.length);
					t.select();
				}
				else if(this.inputField.setSelectionRange)
					this.inputField.setSelectionRange(this.currentInputFieldValue.length, this.inputField.value.length);
			}
		// Sinon, plus aucune suggestion de sélectionnée
		}
		else
			_highlightedSuggestionIndex = -1;
	},

	// Permet le blur (perte du focus) du champ texte après que la touche haut/bas ai été pressé.
	// Le focus est récupéré après traitement (via le timeout).
	blurThenGetFocus: function() {
		this.cursorUpDownPressed = true;
		this.inputField.blur();
		setTimeout("window." + this.idSearch + ".inputField.focus();", 10);
		return;
	},

	// Cache complètement les choix de complétion
	hideCompleteDiv: function() {
		this.completeDiv.style.visibility = "hidden";
	},
	
	// Rends les choix de completion visibles
	showCompleteDiv: function() {
		this.completeDiv.style.visibility = "visible";
		this.setCompleteDivSize();
	},

	// Change la suggestion en surbrillance
	highlightNewValue: function(C) {
		if(!this.completeDivDivList || this.completeDivRows <= 0)
			return;
	
		this.showCompleteDiv();
		if(C >= this.completeDivRows)
			C = this.completeDivRows - 1;
	
		if(_highlightedSuggestionIndex != -1 && C != _highlightedSuggestionIndex) {
			_highlightedSuggestionDiv.className = "AutoCompleteDiv";
			_highlightedSuggestionIndex = -1;
		}
	
		if(C < 0) {
			_highlightedSuggestionIndex = -1;
			this.inputField.focus();
			return;
		}
	
		_highlightedSuggestionIndex = C;
		_highlightedSuggestionDiv = this.completeDivDivList.item(C);
		_highlightedSuggestionDiv.className = "AutoCompleteDivAct";
		this.inputField.value = getSuggestion(_highlightedSuggestionDiv);
	},

	// Déclenchée quand on clique sur une div contenant une possibilité
	divOnMouseDown: function(event) {
		this.inputField.value = getSuggestion(this);
		this.documentForm.submit();
	},

	// Handler pour le keyup du champ texte
	onKeyUpHandler: function(event) {
		ajaxSearch = ajax.search.getByInputField(this);

		if(!event && window.event)
			event = window.event;
	
		ajaxSearch.eventKeycode = event.keyCode;
	
		// Dans les cas touches touche haute (38) ou touche basse (40)
		if(ajaxSearch.eventKeycode == 40 || ajaxSearch.eventKeycode == 38)
			ajaxSearch.blurThenGetFocus();
	
		// Taille de la selection
		var N = rangeSize(ajaxSearch.inputField);
		// Taille du texte avant les suggestions
		var v = beforeRangeSize(ajaxSearch.inputField);
		// contenu du champ texte
		var V = ajaxSearch.inputField.value;
	
		if(ajaxSearch.eventKeycode != 0) {
			// On recupere uniquement le champ texte tapé par l'utilisateur
			if(N > 0 && v != -1)
				V = V.substring(0, v);
	
			// 13 = touche entrée
			if(ajaxSearch.eventKeycode == 13 || ajaxSearch.eventKeycode == 3) {
				var d = ajaxSearch.inputField;
				// On met en place l'ensemble du champ texte en repoussant la sélection
				if(ajaxSearch.inputField.createTextRange) {
					var t = ajaxSearch.inputField.createTextRange();
					t.moveStart("character", ajaxSearch.inputField.value.length);
					ajaxSearch.inputField.select();
				} else if(d.setSelectionRange)
					ajaxSearch.inputField.setSelectionRange(ajaxSearch.inputField.value.length, ajaxSearch.inputField.value.length);
			} else {
				// si on a pas pu agrandir le champ non sélectionné, on le mets en place violemment.
				if(ajaxSearch.inputField.value != V)
					ajaxSearch.inputField.value = V;
			}
		}
				   
		// Si la touche n'est ni haut, ni bas, on stocke la valeur utilisateur du champ
		if(ajaxSearch.eventKeycode != 40 && ajaxSearch.eventKeycode != 38)
			ajaxSearch.currentInputFieldValue = V;
	
		// Si on a pressé une touche autre que haut/bas/enter
		if(ajaxSearch.handleCursorUpDownEnter(ajaxSearch.eventKeycode) && ajaxSearch.eventKeycode != 0)
			ajaxSearch.pressAction();
	},

	// Handler de blur sur le champ texte
	onBlurHandler: function(event){
		ajaxSearch = ajax.search.getByInputField(this);
		if(!ajaxSearch.cursorUpDownPressed) {
			// Si le blur n'est pas causé par la touche haut/bas
			ajaxSearch.hideCompleteDiv();
			// Si la dernière touche pressé est tab, on passe au bouton de validation
			if(_lastKeyCode == 9) {
				ajaxSearch.submitButton.focus();
				_lastKeyCode = -1;
			}
		}
		ajaxSearch.cursorUpDownPressed = false;
	}
};

ajax.search.getByInputField = function(inputField)  
{
	for(var i = 0; ajax.tabSearch[i]; i++)
	{
		if(ajax.tabSearch[i].inputField == inputField)
			return ajax.tabSearch[i];
	}
	return false;
};
