//Décode une chaîne
function html_entity_decode(texte) {
	texte = texte.replace(/&quot;/g,'"'); // 34 22
	texte = texte.replace(/&amp;/g,'&'); // 38 26	
	texte = texte.replace(/&#39;/g,"'"); // 39 27
	texte = texte.replace(/&lt;/g,'<'); // 60 3C
	texte = texte.replace(/&gt;/g,'>'); // 62 3E
	texte = texte.replace(/&circ;/g,'^'); // 94 5E
	texte = texte.replace(/&lsquo;/g,'‘'); // 145 91
	texte = texte.replace(/&rsquo;/g,'’'); // 146 92
	texte = texte.replace(/&ldquo;/g,'“'); // 147 93
	texte = texte.replace(/&rdquo;/g,'”'); // 148 94
	texte = texte.replace(/&bull;/g,'•'); // 149 95
	texte = texte.replace(/&ndash;/g,'–'); // 150 96
	texte = texte.replace(/&mdash;/g,'—'); // 151 97
	texte = texte.replace(/&tilde;/g,'˜'); // 152 98
	texte = texte.replace(/&trade;/g,'™'); // 153 99
	texte = texte.replace(/&scaron;/g,'š'); // 154 9A
	texte = texte.replace(/&rsaquo;/g,'›'); // 155 9B
	texte = texte.replace(/&oelig;/g,'œ'); // 156 9C
	texte = texte.replace(/&#357;/g,''); // 157 9D
	texte = texte.replace(/&#382;/g,'ž'); // 158 9E
	texte = texte.replace(/&Yuml;/g,'Ÿ'); // 159 9F
	texte = texte.replace(/&nbsp;/g,' '); // 160 A0
	texte = texte.replace(/&iexcl;/g,'¡'); // 161 A1
	texte = texte.replace(/&cent;/g,'¢'); // 162 A2
	texte = texte.replace(/&pound;/g,'£'); // 163 A3
	texte = texte.replace(/&curren;/g,' '); // 164 A4
	texte = texte.replace(/&yen;/g,'¥'); // 165 A5
	texte = texte.replace(/&brvbar;/g,'¦'); // 166 A6
	texte = texte.replace(/&sect;/g,'§'); // 167 A7
	texte = texte.replace(/&uml;/g,'¨'); // 168 A8
	texte = texte.replace(/&copy;/g,'©'); // 169 A9
	texte = texte.replace(/&ordf;/g,'ª'); // 170 AA
	texte = texte.replace(/&laquo;/g,'«'); // 171 AB
	texte = texte.replace(/&not;/g,'¬'); // 172 AC
	texte = texte.replace(/&shy;/g,'­'); // 173 AD
	texte = texte.replace(/&reg;/g,'®'); // 174 AE
	texte = texte.replace(/&macr;/g,'¯'); // 175 AF
	texte = texte.replace(/&deg;/g,'°'); // 176 B0
	texte = texte.replace(/&plusmn;/g,'±'); // 177 B1
	texte = texte.replace(/&sup2;/g,'²'); // 178 B2
	texte = texte.replace(/&sup3;/g,'³'); // 179 B3
	texte = texte.replace(/&acute;/g,'´'); // 180 B4
	texte = texte.replace(/&micro;/g,'µ'); // 181 B5
	texte = texte.replace(/&para/g,'¶'); // 182 B6
	texte = texte.replace(/&middot;/g,'·'); // 183 B7
	texte = texte.replace(/&cedil;/g,'¸'); // 184 B8
	texte = texte.replace(/&sup1;/g,'¹'); // 185 B9
	texte = texte.replace(/&ordm;/g,'º'); // 186 BA
	texte = texte.replace(/&raquo;/g,'»'); // 187 BB
	texte = texte.replace(/&frac14;/g,'¼'); // 188 BC
	texte = texte.replace(/&frac12;/g,'½'); // 189 BD
	texte = texte.replace(/&frac34;/g,'¾'); // 190 BE
	texte = texte.replace(/&iquest;/g,'¿'); // 191 BF
	texte = texte.replace(/&Agrave;/g,'À'); // 192 C0
	texte = texte.replace(/&Aacute;/g,'Á'); // 193 C1
	texte = texte.replace(/&Acirc;/g,'Â'); // 194 C2
	texte = texte.replace(/&Atilde;/g,'Ã'); // 195 C3
	texte = texte.replace(/&Auml;/g,'Ä'); // 196 C4
	texte = texte.replace(/&Aring;/g,'Å'); // 197 C5
	texte = texte.replace(/&AElig;/g,'Æ'); // 198 C6
	texte = texte.replace(/&Ccedil;/g,'Ç'); // 199 C7
	texte = texte.replace(/&Egrave;/g,'È'); // 200 C8
	texte = texte.replace(/&Eacute;/g,'É'); // 201 C9
	texte = texte.replace(/&Ecirc;/g,'Ê'); // 202 CA
	texte = texte.replace(/&Euml;/g,'Ë'); // 203 CB
	texte = texte.replace(/&Igrave;/g,'Ì'); // 204 CC
	texte = texte.replace(/&Iacute;/g,'Í'); // 205 CD
	texte = texte.replace(/&Icirc;/g,'Î'); // 206 CE
	texte = texte.replace(/&Iuml;/g,'Ï'); // 207 CF
	texte = texte.replace(/&ETH;/g,'Ð'); // 208 D0
	texte = texte.replace(/&Ntilde;/g,'Ñ'); // 209 D1
	texte = texte.replace(/&Ograve;/g,'Ò'); // 210 D2
	texte = texte.replace(/&Oacute;/g,'Ó'); // 211 D3
	texte = texte.replace(/&Ocirc;/g,'Ô'); // 212 D4
	texte = texte.replace(/&Otilde;/g,'Õ'); // 213 D5
	texte = texte.replace(/&Ouml;/g,'Ö'); // 214 D6
	texte = texte.replace(/&times;/g,'×'); // 215 D7
	texte = texte.replace(/&Oslash;/g,'Ø'); // 216 D8
	texte = texte.replace(/&Ugrave;/g,'Ù'); // 217 D9
	texte = texte.replace(/&Uacute;/g,'Ú'); // 218 DA
	texte = texte.replace(/&Ucirc;/g,'Û'); // 219 DB
	texte = texte.replace(/&Uuml;/g,'Ü'); // 220 DC
	texte = texte.replace(/&Yacute;/g,'Ý'); // 221 DD
	texte = texte.replace(/&THORN;/g,'Þ'); // 222 DE
	texte = texte.replace(/&szlig;/g,'ß'); // 223 DF
	texte = texte.replace(/&agrave;/g,'à'); // 224 E0
	texte = texte.replace(/&aacute;/g,'á'); // 225 E1
	texte = texte.replace(/&acirc;/g,'â'); // 226 E2
	texte = texte.replace(/&atilde;/g,'ã'); // 227 E3
	texte = texte.replace(/&auml;/g,'ä'); // 228 E4
	texte = texte.replace(/&aring;/g,'å'); // 229 E5
	texte = texte.replace(/&aelig;/g,'æ'); // 230 E6
	texte = texte.replace(/&ccedil;/g,'ç'); // 231 E7
	texte = texte.replace(/&egrave;/g,'è'); // 232 E8
	texte = texte.replace(/&eacute;/g,'é'); // 233 E9
	texte = texte.replace(/&ecirc;/g,'ê'); // 234 EA
	texte = texte.replace(/&euml;/g,'ë'); // 235 EB
	texte = texte.replace(/&igrave;/g,'ì'); // 236 EC
	texte = texte.replace(/&iacute;/g,'í'); // 237 ED
	texte = texte.replace(/&icirc;/g,'î'); // 238 EE
	texte = texte.replace(/&iuml;/g,'ï'); // 239 EF
	texte = texte.replace(/&eth;/g,'ð'); // 240 F0
	texte = texte.replace(/&ntilde;/g,'ñ'); // 241 F1
	texte = texte.replace(/&ograve;/g,'ò'); // 242 F2
	texte = texte.replace(/&oacute;/g,'ó'); // 243 F3
	texte = texte.replace(/&ocirc;/g,'ô'); // 244 F4
	texte = texte.replace(/&otilde;/g,'õ'); // 245 F5
	texte = texte.replace(/&ouml;/g,'ö'); // 246 F6
	texte = texte.replace(/&divide;/g,'÷'); // 247 F7
	texte = texte.replace(/&oslash;/g,'ø'); // 248 F8
	texte = texte.replace(/&ugrave;/g,'ù'); // 249 F9
	texte = texte.replace(/&uacute;/g,'ú'); // 250 FA
	texte = texte.replace(/&ucirc;/g,'û'); // 251 FB
	texte = texte.replace(/&uuml;/g,'ü'); // 252 FC
	texte = texte.replace(/&yacute;/g,'ý'); // 253 FD
	texte = texte.replace(/&thorn;/g,'þ'); // 254 FE
	texte = texte.replace(/&yuml;/g,'ÿ'); // 255 FF
	return texte;
}

var SearchCompletion = function()
{
	this._DefaultValue='Recherche' ;
	this._documentForm=null; // le formulaire contenant notre champ texte
	this._inputField=null; // le champ texte lui-même
	this._submitButton=null; // le bouton submit de notre formulaire
	
	this._oldInputFieldValue=""; // valeur précédente du champ texte
	this._currentInputFieldValue=""; // valeur actuelle du champ texte
	this._resultCache=new Object(); // mécanisme de cache des requetes
	
	this._xmlHttp = null; //l'objet xmlHttpRequest utilisé pour contacter le serveur
	this._adresseRecherche = "/ajax.php" //l'adresse à interroger pour trouver les suggestions
	
	this._lastKeyCode=null;
	this._eventKeycode = null;
	this._completeDivRows = 0;
	this._completeDivDivList = null;
	this._highlightedSuggestionIndex = -1;
	this._highlightedSuggestionDiv = null;
	this._cursorUpDownPressed = null;
	this._typeRecherche = '' ;
	this._NbResultsToDisplay = 10 ;
}
SearchCompletion.prototype =
{
// retourne un objet xmlHttpRequest.
// méthode compatible entre tous les navigateurs (IE/Firefox/Opera)
	getXMLHTTP:function()
	{
		var xhr=null;
		if(window.XMLHttpRequest) // Firefox et autres
			xhr = new XMLHttpRequest();
		else if(window.ActiveXObject){ // Internet Explorer
		try {
		xhr = new ActiveXObject("Msxml2.XMLHTTP");
		} catch (e) {
		try {
		xhr = new ActiveXObject("Microsoft.XMLHTTP");
		} catch (e1) {
		xhr = null;
		}
		}
		}
		else { // XMLHttpRequest non supporté par le navigateur
		alert("Votre navigateur ne supporte pas les objets XMLHTTPRequest...");
		}
		return xhr;
	},

	addEvent : function(elem,_type,_delegate)
	{
	    if(elem)
	    {
	        if (elem.attachEvent)
	        {
	            elem.attachEvent ("on"+_type,_delegate);
	        } 
	        else if (elem.addEventListener) 
	        {
	            elem.addEventListener (_type,_delegate,false);
	        } 
	        else
	        {
	            elem["on"+_type] = _delegate;
	        }
	    }
	},

	focusSearchInput:function(event)
	{
		var obj = event.target || event.srcElement;
		if((!obj)||(!obj.value)) return;
		var val = obj.value.replace(/\s+$/g,'') ;
		if(val==this._DefaultValue)
			obj.value='';
		/*obj.style.color='#000000';
		*/
	},

	init : function(form,field,submit,type)
	{
		  this._typeRecherche = type ;
		  this._documentForm=form;
		  this._inputField=field;
		  this._submitButton=submit;
		  this._inputField.setAttribute('autocomplete',"off");
		  this.creeAutocompletionDiv();
		  this._currentInputFieldValue=this._inputField.value;
		  this._oldInputFieldValue=this._currentInputFieldValue;
		  this.cacheResults("",new Array())
		  
		  this._DefaultValue=this._inputField.value.replace(/\s+$/g,'') ;
		  
		  var _this = this ;
		  this.addEvent(document,"keydown", function(event)
		  {
			  _this.onKeyDownHandler.call(_this,this,event) ;
		  }) ;
		  
		  this.addEvent(this._inputField,"keyup", function(event)
		  {
			  _this.onKeyUpHandler.call(_this,this,event) ;
		  }) ;
		  
		  this.addEvent(this._inputField,"blur", function(event)
		  {
			  _this.onBlurHandler.call(_this,this,event) ;
		  }) ;
		  
		  this.addEvent(window,"resize", function(event)
		  {
			  _this.onResizeHandler.call(_this,this,event) ;
		  }) ;
		  
		  this._inputField.onfocus = '' ;
		  this.addEvent(this._inputField,"focus", function(event)
		  {
			  _this.focusSearchInput.call(_this,event) ;
		  }) ;
		  
		  // Premier déclenchement de la fonction dans 200 millisecondes
		  setTimeout(function(){ _this.mainLoop() },200) ;
	},



	// tourne en permanence pour suggerer suite à un changement du champ texte
	mainLoop : function()
	{
	  if(this._oldInputFieldValue!=this._currentInputFieldValue){
	    var valeur=this.escapeURI(this._currentInputFieldValue);
	    var suggestions=this._resultCache[this._currentInputFieldValue];
	    if(suggestions){ // la réponse était encore dans le cache
	      this.metsEnPlace(valeur,suggestions)
	    }else{
	      this.callSuggestions(valeur) // appel distant
	    }
	    this._inputField.focus()
	  }
	  this._oldInputFieldValue=this._currentInputFieldValue;
	  var _this = this ;
	  setTimeout(function(){ _this.mainLoop() },200) ; // la fonction se redéclenchera dans 200 ms
	  return true
	},

	// echappe les caractère spéciaux
	escapeURI:function(La){
	  if(encodeURIComponent) {
	    return encodeURIComponent(La);
	  }
	  if(escape) {
	    return escape(La)
	  }
	},

	callSuggestions:function(valeur)
	{
	  if(this._xmlHttp && this._xmlHttp.readyState!=0){
	    this._xmlHttp.abort()
	  }
	  this._xmlHttp=this.getXMLHTTP();
	  if(this._xmlHttp){
	  	
	    //appel à l'url distante
	    var datas = 'Type='+this._typeRecherche+'&ACTION=SEARCH_COMPLETION&SCH='+valeur+'&LIMIT='+this._NbResultsToDisplay ;
	    this._xmlHttp.open("POST",this._adresseRecherche,true);
	    this._xmlHttp.setRequestHeader('Content-Type','application/x-www-form-urlencoded');
		this._xmlHttp.send(datas);
		var _this = this ;
	    this._xmlHttp.onreadystatechange=function() {
	     if(_this._xmlHttp.readyState==4) {
	      	if(_this._xmlHttp.status == 200)
	      	{
		        var liste = _this.traiteSuggestions(_this._xmlHttp.responseText)
		        _this.cacheResults(valeur,liste)
		        _this.metsEnPlace(valeur,liste)
	        }
	      }
	    };
	  }
	},

	// Mecanisme de caching des réponses
	cacheResults:function(debut,suggestions)
	{
	  this._resultCache[debut]=suggestions
	},

	// Transformation XML en tableau
	traiteSuggestions:function(results)
	{
		rep=results.split('\n');
		
		var row=0 ; nr=0 ; html='' ;
		var optionsListe = new Array();
		while(row<500)
		{
			try { data=rep[row++].split("\t",3); } catch(e) { break ; }
			if(data[0]=="EXIT") { break; }
			if((data[0])&&(data[0]!="BEGIN")) { alert('ERROR IN BEGIN='+data[0]+'\nREP='+rep[row-1]+'\n'+results); return; }
			if(data[2]*1>0)
			{
				while(row<500)
				{
					info=rep[row++].split("\t",5);
					if(info[0]=='END') break ; 
					optionsListe.push(info[0].unescapeHTML());
					nr++;
				}
				
			} else row++;
		}
		return optionsListe;
	},

	//insère une règle avec son nom
	insereCSS : function(nom,regle)
	{
	  if (document.styleSheets) {
	    var I=document.styleSheets[0];
	    if(I.addRule){ // méthode IE
	      I.addRule(nom,regle)
	    }else if(I.insertRule){ // méthode DOM
	      I.insertRule(nom+" { "+regle+" }",I.cssRules.length)
	    }
	  }
	},

	initStyle:function()
	{
	  var AutoCompleteDivListeStyle="font-size: 13px; font-family: arial,sans-serif; word-wrap:break-word; ";
	  var AutoCompleteDivStyle="display: block; padding-left: 3; padding-right: 3; height: 16px; overflow: hidden; background-color: white;";
	  var AutoCompleteDivActStyle="background-color: #3366cc; color: white ! important; ";
	  this.insereCSS(".AutoCompleteDivListeStyle",AutoCompleteDivListeStyle);
	  this.insereCSS(".AutoCompleteDiv",AutoCompleteDivStyle);
	  this.insereCSS(".AutoCompleteDivAct",AutoCompleteDivActStyle);
	},

	setStylePourElement:function(c,name)
	{
	  c.className=name;
	},
	
	// calcule le décalage à gauche
	calculateOffsetLeft:function(r)
	{
	  return this.calculateOffset(r,"offsetLeft")
	},
	
	// calcule le décalage vertical
	calculateOffsetTop:function(r){
	  return this.calculateOffset(r,"offsetTop")
	},
	
	calculateOffset:function(r,attr){
	  var kb=0;
	  while(r){
	    kb+=r[attr];
	    r=r.offsetParent
	  }
	  return kb
	},

	// calcule la largeur du champ
	calculateWidth:function(){
	  return this._inputField.offsetWidth-2*1
	},
	
	setCompleteDivSize:function(){
	  if(this._completeDiv){
	    this._completeDiv.style.left=this.calculateOffsetLeft(this._inputField)+"px";
	    this._completeDiv.style.top=this.calculateOffsetTop(this._inputField)+this._inputField.offsetHeight-1+"px";
	    this._completeDiv.style.width=this.calculateWidth()+"px"
	  }
	},

	creeAutocompletionDiv:function()
	{
	  this.initStyle();
	  this._completeDiv=document.createElement("DIV");
	  this._completeDiv.id="completeDiv";
	  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";
	  this.setCompleteDivSize();
	  this._completeDiv.style.visibility="hidden";
	  this._completeDiv.style.position="absolute";
	  this._completeDiv.style.backgroundColor="white";
	  document.body.appendChild(this._completeDiv);
	  this.setStylePourElement(this._completeDiv,"AutoCompleteDivListeStyle");
	},

	metsEnPlace:function(valeur, liste)
	{
	  while(this._completeDiv.childNodes.length>0) {
	    this._completeDiv.removeChild(this._completeDiv.childNodes[0]);
	  }
	  
	  var _this = this ;
	
	  // mise en place des suggestions
	  for(var f=0; f<liste.length; ++f){
	    var nouveauDiv=document.createElement("DIV");
	    
		this.addEvent(nouveauDiv,"mousedown", function(event) {
			var target = event.target || event.srcElement;
			_this.divOnMouseDown.call(_this,event) ;
			/*
			try
			{_this.divOnMouseDown.call(_this,event)
			}catch(e){
				try{_this.divOnMouseDown.call(_this,target,event)}catch(e){}
			}
			*/
		}) ;
		
		this.addEvent(nouveauDiv,"mouseover", function(event) {
			_this.divOnMouseOver.call(_this,this,event) ; }) ;
		
		this.addEvent(nouveauDiv,"mouseout", function(event) {
			  _this.divOnMouseOut.call(_this,this,event) ; }) ;
			  
	    this.setStylePourElement(nouveauDiv,"AutoCompleteDiv");
	    var nouveauA=document.createElement("A");
	    nouveauA.innerHTML=liste[f]; // le texte de la suggestion
	    nouveauDiv.appendChild(nouveauA);
	    this._completeDiv.appendChild(nouveauDiv)
	  }
	  this.PressAction();
	  if(this._completeDivRows>0) {
	    this._completeDiv.height=16*this._completeDivRows+4;
	  } else {
	    this.hideCompleteDiv();
	  }
	
	},



	// Handler pour le keydown du document
	onKeyDownHandler:function(obj,event){
	  // accès evenement compatible IE/Firefox
	  if(!event&&window.event) {
	    event=window.event;
	  }
	  // on enregistre la touche ayant déclenché l'evenement
	  if(event) {
	    this._lastKeyCode=event.keyCode;
	  }
	},

	
	// Handler pour le keyup de lu champ texte
	onKeyUpHandler:function(obj,event)
	{
	  // accès evenement compatible IE/Firefox
	  if(!event&&window.event) {
	    event=window.event;
	  }
	  this._eventKeycode=event.keyCode;
	  // Dans les cas touches touche haute(38) ou touche basse (40)
	  if(this._eventKeycode==40||this._eventKeycode==38) {
	    // on autorise le blur du champ (traitement dans onblur)
	    this.blurThenGetFocus();
	  }
	  // taille de la selection
	  var N=this.rangeSize(this._inputField);
	  // taille du texte avant la selection (selection = suggestion d'autocomplétion)
	  var v=this.beforeRangeSize(this._inputField);
	  // contenu du champ texte
	  var V=this._inputField.value;
	  if(this._eventKeycode!=0){
	    if(N>0&&v!=-1) {
	      // on recupere uniquement le champ texte tapé par l'utilisateur
	      V=V.substring(0,v);
	    }
	    // 13 = touche entrée
	    if(this._eventKeycode==13||this._eventKeycode==3){
	      var d=this._inputField;
	      // on mets en place l'ensemble du champ texte en repoussant la selection
	      if(this._inputField.createTextRange){
	        var t=this._inputField.createTextRange();
	        t.moveStart("character",this._inputField.value.length);
	        this._inputField.select()
	      } else if (d.setSelectionRange){
	        this._inputField.setSelectionRange(this._inputField.value.length,this._inputField.value.length)
	      }
	    } else {
	      // si on a pas pu agrandir le champ non selectionné, on le mets en place violemment.
	      if(this._inputField.value!=V) {
	        this._inputField.value=V
	      }
	    }
	  }
	  // si la touche n'est ni haut, ni bas, on stocke la valeur utilisateur du champ
	  if(this._eventKeycode!=40 && this._eventKeycode!=38) {
	    // le champ courant n est pas change si key Up ou key Down
	  	this._currentInputFieldValue=V;
	  }
	  if(this.handleCursorUpDownEnter(this._eventKeycode)&&this._eventKeycode!=0) {
	    // si on a préssé une touche autre que haut/bas/enter
	    this.PressAction();
	  }
	},
	
	// Change la suggestion selectionné.
	// cette méthode traite les touches haut, bas et enter
	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
	},



	// gère une touche pressée autre que haut/bas/enter
	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(this.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++) {
	    this.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){
	    this.setStylePourElement(this._highlightedSuggestionDiv,"AutoCompleteDivAct");
	    var z;
	    if(trouve) {
	      z=this.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;
	  }
	},


	// 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).
	blurThenGetFocus:function()
	{
	  this._cursorUpDownPressed=true;
	  this._inputField.blur();
	  var _this = this ;
	  setTimeout(function(){ _this._inputField.focus() },10);
	  return
	},

	// taille de la selection dans le champ input
	rangeSize:function(n){
	  var N=-1;
	  if(n.createTextRange){
	    var fa=document.selection.createRange().duplicate();
	    N=fa.text.length
	  }else if(n.setSelectionRange){
	    N=n.selectionEnd-n.selectionStart
	  }
	  return N
	},

	// taille du champ input non selectionne
	beforeRangeSize:function(n){
	  var v=0;
	  if(n.createTextRange){
	    var fa=document.selection.createRange().duplicate();
	    fa.moveEnd("textedit",1);
	    v=n.value.length-fa.text.length
	  }else if(n.setSelectionRange){
	    v=n.selectionStart
	  }else{
	    v=-1
	  }
	  return v
	},

	// Place le curseur à la fin du champ
	cursorAfterValue:function(n){
	  if(n.createTextRange){
	    var t=n.createTextRange();
	    t.moveStart("character",n.value.length);
	    t.select()
	  } else if(n.setSelectionRange) {
	    n.setSelectionRange(n.value.length,n.value.length)
	  }
	},
	
	
	// Retourne la valeur de la possibilite (texte) contenu dans une div de possibilite
	getSuggestion:function(uneDiv){
	  if(!uneDiv) {
	    return null;
	  }
	  try { var val = uneDiv.getElementsByTagName('A')[0].innerHTML ; }
	  catch(e){var val = uneDiv.innerHTML ;}
	  val = val.toLowerCase().replace('<strong>','') ;
	  val = val.replace('</strong>','') ; 
	  return html_entity_decode(this.trimCR(val)) ;
	},
	
	// supprime les caractères retour chariot et line feed d'une chaine de caractères
	trimCR:function(chaine){
	  for(var f=0,nChaine="",zb="\n\r"; f<chaine.length; f++) {
	    if (zb.indexOf(chaine.charAt(f))==-1) {
	      nChaine+=chaine.charAt(f);
	    }
	  }
	  return nChaine
	},

	// Cache completement les choix de completion
	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(this._highlightedSuggestionIndex!=-1&&C!=this._highlightedSuggestionIndex){
	    this.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);
	  this.setStylePourElement(this._highlightedSuggestionDiv,"AutoCompleteDivAct");
	  this._inputField.value=this.getSuggestion(this._highlightedSuggestionDiv);
	},

	// Handler de resize de la fenetre
	onResizeHandler:function(obj,event){
	  // recalcule la taille des suggestions
	  this.setCompleteDivSize();
	},

	// Handler de blur sur le champ texte
	onBlurHandler:function(obj,event){
	  if(!this._cursorUpDownPressed){
	    // si le blur n'est pas causé par la touche haut/bas
	    this.hideCompleteDiv();
	    if(this._inputField.value=='')
	    	this._inputField.value = this._DefaultValue ;
	    // Si la dernière touche préssé est tab, on passe au bouton de validation
	    if(this._lastKeyCode==9){
	      this._submitButton.focus();
	      this._lastKeyCode=-1
	    }
	  }
	  this._cursorUpDownPressed=false
	},
	
	// declenchee quand on clique sur une div contenant une possibilite
	divOnMouseDown:function(event)
	{
	  var targetElt = event.target || event.srcElement;
	  if(this._documentForm)
	  {
		  this._inputField.value=this.getSuggestion(targetElt);
		  /*this._documentForm.submit()*/
	  }
	},
	
	// declenchee quand on passe sur une div de possibilite. La div précédente est passee en style normal
	divOnMouseOver:function(targetElt,event)
	{
	  if(this._highlightedSuggestionDiv) {
	  	this.setStylePourElement(this._highlightedSuggestionDiv,"AutoCompleteDiv");
	  }
	  this.setStylePourElement(targetElt,"AutoCompleteDivAct")
	},
	
	// declenchee quand la sourie quitte une div de possiblite. La div repasse a l'etat normal
	divOnMouseOut : function(targetElt,event)
	{
	  this.setStylePourElement(targetElt,"AutoCompleteDiv");
	}
} ;


window.onload = function()
{
	if(document.getElementById('SCHLocation'))
	{
		new SearchCompletion().init(document.getElementById('SCHLocation'),
		document.getElementById('FieldSCHLocation'),document.getElementById('SubmitSCHLocation'),'Location') ;
	}
	if(document.getElementById('SCHVenteM'))
	{
		new SearchCompletion().init(document.getElementById('SCHVenteM'),
		document.getElementById('FieldSCHVenteM'),document.getElementById('SubmitSCHVenteM'),'VenteM') ;
	}
	if(document.getElementById('SCHVenteO'))
	{
		new SearchCompletion().init(document.getElementById('SCHVenteO'),
		document.getElementById('FieldSCHVenteO'),document.getElementById('SubmitSCHVenteO'),'VenteO') ;
	}
	if(document.getElementById('SCHVente'))
	{
		new SearchCompletion().init(document.getElementById('SCHVente'),
		document.getElementById('FieldSCHVente'),document.getElementById('SubmitSCHVente'),'VenteO,VenteM') ;
	}
};
