///////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////
//		Objet AutoComplete
///////////////////////////////////////////////////////////////////

FuncOL = new Array();
function StkFunc(Obj) {
	FuncOL[FuncOL.length] = Obj;
}
function GetStkFunc(element) {
	var obj = new Object();
	for(var i = 0;i < FuncOL.length; i++) {
		obj = FuncOL[i];
		obj.prototype = AutoComplete.prototype;
		if (FuncOL[i]._inputField.id == element.id) return obj;
	}
	return null;
}

function AutoComplete(form,field,adresse) {
	this._adresseRecherche = adresse; 
	
	this._documentForm = form;
	this._inputField = field;
	//this._submitButton = submit;
	this._resultCache=new Object();
	
	this._completeDivRows = 0;
	this._completeDivDivList = null;
	this._highlightedSuggestionIndex = -1;
	this._highlightedSuggestionDiv = null;
	
	this._cursorUpDownPressed = null;
}

AutoComplete.prototype.init = function() {
	this._inputField.autocomplete="off";
	this._currentInputFieldValue=this._inputField.value;
	this._oldInputFieldValue=this._currentInputFieldValue;
	this._inputField.onkeyup=onKeyUpHandler;
	this._inputField.onblur=onBlurHandler;
	this.creeAutocompletionDiv();
	StkFunc(this);
	cacheResults(this._resultCache,"",new Array());
}

AutoComplete.prototype.creeAutocompletionDiv = function() {
  initStyle();
  this._completeDiv=document.createElement("DIV");
  this._completeDiv.id="completeDiv_" + this._inputField.id;
  var borderLeftRight=1;
  var borderTopBottom=1;
  this._completeDiv.style.borderRight="black "+borderLeftRight+"px solid";
  this._completeDiv.style.borderLeft="black "+borderLeftRight+"px solid";
  this._completeDiv.style.borderTop="black "+borderTopBottom+"px solid";
  this._completeDiv.style.borderBottom="black "+borderTopBottom+"px solid";
  this._completeDiv.style.zIndex="1";
  this._completeDiv.style.paddingRight="0";
  this._completeDiv.style.paddingLeft="0";
  this._completeDiv.style.paddingTop="0";
  this._completeDiv.style.paddingBottom="0";
  setCompleteDivSize(this._inputField,this._completeDiv);
  this._completeDiv.style.visibility="hidden";
  this._completeDiv.style.position="absolute";
  this._completeDiv.style.backgroundColor="white";
  document.body.appendChild(this._completeDiv);
  setStylePourElement(this._completeDiv,"AutoCompleteDivListeStyle");
}

// Cache completement les choix de completion
AutoComplete.prototype.hideCompleteDiv = function(){
  this._completeDiv.style.visibility="hidden"
}

// Rends les choix de completion visibles
AutoComplete.prototype.showCompleteDiv = function (){
  this._completeDiv.style.visibility="visible";
  setCompleteDivSize()
}

AutoComplete.prototype.callSuggestions = function(valeur,adresse){
  if(_xmlHttp&&_xmlHttp.readyState!=0){
    _xmlHttp.abort()
  }
  _xmlHttp=getXMLHTTP();
  if(_xmlHttp){
    //appel à l'url distante
    _xmlHttp.open("GET",this._adresseRecherche+"&champ="+this._inputField.id+"&debut="+valeur,true);
    _xmlHttp.onreadystatechange=this.receiveSuggestions;
    // envoi de la requete
    _xmlHttp.send(null)
  }
}

AutoComplete.prototype.receiveSuggestions = function() {
	if(_xmlHttp.readyState==4&&_xmlHttp.responseXML) {
		var liste = traiteXmlSuggestions(_xmlHttp.responseXML)
		var champ = getSenderInputFieldId(_xmlHttp.responseXML);
		var valeur = getSenderStart(_xmlHttp.responseXML);
		var autoC = GetStkFunc(document.getElementById(champ));
		cacheResults(autoC._resultCache,valeur,liste)
		autoC.metsEnPlace(valeur,liste)
	}
}

AutoComplete.prototype.metsEnPlace = function(valeur, 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");
    nouveauDiv.onmousedown=divOnMouseDown;
    nouveauDiv.onmouseover=divOnMouseOver;
    nouveauDiv.onmouseout=divOnMouseOut;
    nouveauDiv.id="nouveauDiv_" + this._inputField.id;
    setStylePourElement(nouveauDiv,"AutoCompleteDiv");
    var nouveauSpan=document.createElement("SPAN");
    nouveauSpan.innerHTML=liste[f]; // le texte de la suggestion
    nouveauDiv.appendChild(nouveauSpan);
    this._completeDiv.appendChild(nouveauDiv)
  }
  this.PressAction();
  if(this._completeDivRows>0) {
    this._completeDiv.height=16*this._completeDivRows+4;
  } else {
    this.hideCompleteDiv();
  }

}

// gère une touche pressée autre que haut/bas/enter
AutoComplete.prototype.PressAction = function(){
  this._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;
  // possiblité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++) {
    setStylePourElement(suggestionList.item(i),"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){
    this._highlightedSuggestionIndex=indice;
    this._highlightedSuggestionDiv=suggestionList.item(this._highlightedSuggestionIndex);
  }else{
    this._highlightedSuggestionIndex=-1;
    this._highlightedSuggestionDiv=null
  }
  var supprSelection=false;
  switch(this._eventKeycode){
    // cursor left, cursor right, page up, page down, others??
    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;
    default:
      break
  }
  // si on a une suggestion (n-1) sélectionnée
  if(!supprSelection&&this._highlightedSuggestionDiv){
    setStylePourElement(this._highlightedSuggestionDiv,"AutoCompleteDivAct");
    var z;
    if(trouve) {
      z=getSuggestion(this._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)
      }
    }
  }else{
    // sinon, plus aucune suggestion de sélectionnée
    this._highlightedSuggestionIndex=-1;
  }
}

// Change la suggestion en surbrillance
AutoComplete.prototype.highlightNewValue = function(C){
  if(!this._completeDivDivList||this._completeDivRows<=0) {
    return;
  }
  this.showCompleteDiv();
  if(C>=this._completeDivRows){
    C=this._completeDivRows-1
  }
  if(this._highlightedSuggestionIndex!=-1&&C!=this._highlightedSuggestionIndex){
    setStylePourElement(this._highlightedSuggestionDiv,"AutoCompleteDiv");
    this._highlightedSuggestionIndex=-1
  }
  if(C<0){
    this._highlightedSuggestionIndex=-1;
    this._inputField.focus();
    return
  }
  this._highlightedSuggestionIndex=C;
  this._highlightedSuggestionDiv=this._completeDivDivList.item(C);
  setStylePourElement(this._highlightedSuggestionDiv,"AutoCompleteDivAct");
  this._inputField.value=getSuggestion(this._highlightedSuggestionDiv);
}



//Evenements                                                       
// permet le blur 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).
AutoComplete.prototype.blurThenGetFocus = function(){
  this._cursorUpDownPressed=true;
  this._inputField.blur();
  setTimeout("document.getElementById('" + this._inputField.id + "').focus();",10);
  return
}

// Change la suggestion selectionné.
// cette méthode traite les touches haut, bas et enter
AutoComplete.prototype.handleCursorUpDownEnter = function(eventCode){
  if(eventCode==40){
    this.highlightNewValue(this._highlightedSuggestionIndex+1);
    return false
  }else if(eventCode==38){
    this.highlightNewValue(this._highlightedSuggestionIndex-1);
    return false
  }else if(eventCode==13||eventCode==3){
    return false
  }
  return true
}
