Autocompleter.DWR = Class.create();
Autocompleter.DWR.prototype = Object.extend(new Autocompleter.Base(), {
    initialize: function(element, update, populator, options) {
        this.baseInitialize(element, update, options);
        this.options.array = new Array(0);
        this.populator = populator;
        if (this.options.afterUpdateElement) {
            this.afterUpdateCallback = this.options.afterUpdateElement;
            this.options.afterUpdateElement = this.afterUpdateElement.bind(this);
        }
    },

    // called by the autocompleter on an event.
    getUpdatedChoices: function() {
        var entry = this.getToken();
        if (entry.length >= this.options.partialChars) {
            this.populator(this, this.getToken()); // this is the populator specified in the constructor.
        } else {
            this.hide();
        }
    },

    afterUpdateElement: function(element, selectedElement) {
        if (this.options.dualElement) {
        	if(this.options.listOfChoice){
                this.afterUpdateCallback(element, this.options.dualElement, selectedElement, this.options.array[this.index], this.options.listOfChoice);
        	}else{
        		this.afterUpdateCallback(element, this.options.dualElement, selectedElement, this.options.array[this.index]);
        	}
        } else {
        	if(this.options.listOfChoice){
                this.afterUpdateCallback(element, selectedElement, this.options.array[this.index], this.options.listOfChoice);
        	}else{
        		this.afterUpdateCallback(element, selectedElement, this.options.array[this.index]);
        	}
        }
    },

    // should be called by the populator (specified in the constructor)
    setChoices: function(array) {
        this.options.array = array;
        this.updateChoices(this.options.selector(this));
    },

    setOptions: function(options) {
        this.options = Object.extend({
            choices: 24,
            partialSearch: true,
            partialChars: 2,
            ignoreCase: true,
            fullSearch: true,
            selector: function(instance) {
                var ret = []; // Beginning matches
                var partial = []; // Inside matches
                var entry = instance.getToken();
                var count = 0;
                var valueSelector = instance.options.valueSelector;
                //Div contenant la liste des choix
                var listOfChoice = document.getElementById(instance.options.listOfChoice);
                var inputToSetCode = instance.options.inputToSetCode;
                var inputToSetName = instance.options.inputToSetName;
                
                var isTheFirstCity = true;
                var isTheFirstPoi = true;
                var isTheFirstArea = true;
                var isTheFirst = true;
                var listInnerHTML = "";
                var hasUlOpen = false;
                for (var i = 0; i < instance.options.array.length && ret.length < instance.options.choices; i++) {
                    var elem = valueSelector(instance.options.array[i]);
                    
                    var elemToDisplay;// = elem; // variable pour l'affichage.
                    // Ça c'est moi qui l'ai fait
                    if (elem.isPoiSet) {
                        elemToDisplay = elem.poiTO.title;
                        var highlightedEntry;
                        if (isTheFirstPoi) {
                        	if(hasUlOpen){
                            	listInnerHTML +="</ul>";
                        	}
                        	listInnerHTML += "<span class='itemTypeOfList'>POINTS D'INTERET</span>";
                        	listInnerHTML +="<ul>";
                        	listInnerHTML += "<li>";
                        	hasUlOpen = true;
                        	listInnerHTML += this.createLinkWithEntrySelection(instance.options.listOfChoice, elemToDisplay, elem.poiTO.id, elem.poiTO.lat, elem.poiTO.lng, inputToSetCode, inputToSetName);
                        	highlightedEntry = this.highlightEntrySelection(instance, elemToDisplay, entry, "<li style='width:100%'><table class='firstTableAjaxList'><tr><td class='firstTdAjaxList'>", "</td><td class='secondTdAjaxList'><font class='typeOfCompletionLabel'>POINTS D'INTERET</font></td></tr></table></li>")
                            isTheFirstPoi = false;
                        } else {
                        	listInnerHTML += "<li>";
                        	listInnerHTML += this.createLinkWithEntrySelection(instance.options.listOfChoice, elemToDisplay, elem.poiTO.id, elem.poiTO.lat, elem.poiTO.lng, inputToSetCode, inputToSetName);
                        	highlightedEntry = this.highlightEntrySelection(instance, elemToDisplay, entry, "<li style='width:100%'><table class='tableAjaxList'><tr><td class='firstTdAjaxList'>", "</td></tr></table></li>")
                        }
                        ret.push(highlightedEntry);
                    } else if (elem.isAreaSet && instance.options.showArea) {
                        elemToDisplay = elem.areaTO.nameFre;
                        var highlightedEntry;
                        if (isTheFirstArea) {
                        	if(hasUlOpen){
                            	listInnerHTML +="</ul>";
                        	}
                        	listInnerHTML += "<span class='itemTypeOfList'>R&Eacute;GIONS</span>";
                        	listInnerHTML +="<ul>";
                        	listInnerHTML += "<li>";
                        	hasUlOpen = true;
                        	listInnerHTML += this.createLinkWithEntrySelection(instance.options.listOfChoice, elemToDisplay, elem.areaTO.code, elem.areaTO.lat, elem.areaTO.lng, inputToSetCode, inputToSetName);
                        	highlightedEntry = this.highlightEntrySelection(instance, elemToDisplay, entry, "<li style='width:100%'><table class='firstTableAjaxList'><tr><td class='firstTdAjaxList'>", "</td><td class='secondTdAjaxList'><font class='typeOfCompletionLabel'>R&Eacute;GIONS</font></td></tr></table></li>")
                            isTheFirstArea = false;
                        } else {
                        	listInnerHTML += "<li>";
                        	listInnerHTML += this.createLinkWithEntrySelection(instance.options.listOfChoice, elemToDisplay, elem.areaTO.code, elem.areaTO.lat, elem.areaTO.lng, inputToSetCode, inputToSetName);
                        	highlightedEntry = this.highlightEntrySelection(instance, elemToDisplay, entry, "<li style='width:100%'><table class='tableAjaxList'><tr><td class='firstTdAjaxList'>", "</td></tr></table></li>")
                        }
                        ret.push(highlightedEntry);
                	}else if (elem.isCitySet) {
                        elemToDisplay = elem.cityTO.nameToDisplay;
                        var highlightedEntry;
                        if (isTheFirstCity) {
                        	if(hasUlOpen){
                            	listInnerHTML +="</ul>";
                        	}
                        	listInnerHTML += "<span class='itemTypeOfList'>VILLES</span>";
                        	listInnerHTML +="<ul>";
                        	listInnerHTML += "<li>";
                        	hasUlOpen = true;
                        	listInnerHTML += this.createLinkWithEntrySelection(instance.options.listOfChoice, elemToDisplay, elem.cityTO.cityCode, elem.cityTO.latitude, elem.cityTO.longitude, inputToSetCode, inputToSetName);
                        	highlightedEntry = this.highlightEntrySelection(instance, elemToDisplay, entry, "<li style='width:100%'><table class='firstTableAjaxList'><tr><td class='firstTdAjaxList'>", "</td><td class='secondTdAjaxList'><font class='typeOfCompletionLabel'>VILLES</font></td></tr></table></li>")
                            isTheFirstCity = false;
                        } else {
                        	listInnerHTML += "<li>";
                        	listInnerHTML += this.createLinkWithEntrySelection(instance.options.listOfChoice, elemToDisplay, elem.cityTO.cityCode, elem.cityTO.latitude, elem.cityTO.longitude, inputToSetCode, inputToSetName);
                        	highlightedEntry = this.highlightEntrySelection(instance, elemToDisplay, entry, "<li style='width:100%'><table class='tableAjaxList'><tr><td class='firstTdAjaxList'>", "</td></tr></table></li>")
                        }
                        ret.push(highlightedEntry);
                    } else if (elem.isTitle)  {
						isTheFirst = true;
						
                    } else if(elem.isAirport) {
                    	 elemToDisplay = elem.displayableLabel;
                         var highlightedEntry;
                         if (isTheFirst) {
                         	if(hasUlOpen){
                            	listInnerHTML +="</ul>";
                        	}
                         	listInnerHTML +="<ul>";
                        	hasUlOpen = true;
                        	highlightedEntry = this.highlightEntrySelection(instance, elemToDisplay, entry, "<li style='width:100%'><table class='firstTableAjaxList'><tr><td class='firstTdAjaxList'>", "</td><td class='secondTdAjaxList'><font class='typeOfCompletionLabel'>AEROPORTS</font></td></tr></table></li>")
                            isTheFirst = false;
                         } else {
                        	 highlightedEntry = this.highlightEntrySelection(instance, elemToDisplay, entry, "<li style='width:100%'><table class='tableAjaxList'><tr><td class='firstTdAjaxList'>", "</td></tr></table></li>")
                         }
                     	listInnerHTML += "<li>";
                         listInnerHTML += this.createLinkWithEntrySelection(instance.options.listOfChoice, elemToDisplay, elem.iataCode, "", "", inputToSetCode, inputToSetName);
                         ret.push(highlightedEntry);
                    	 
					} else if(elem.login != null){
	                   	 elemToDisplay = elem.login;
	                     var highlightedEntry;
	                     if (isTheFirst) {
	                    	 highlightedEntry = this.highlightEntrySelection(instance, elemToDisplay, entry, "<li style='width:100%'><table class='firstTableAjaxList'><tr><td class='firstTdAjaxList'>", "</td><td class='secondTdAjaxList'><font class='typeOfCompletionLabel'>AEROPORTS</font></td></tr></table></li>")
	                         isTheFirst = false;
	                     } else {
	                    	 highlightedEntry = this.highlightEntrySelection(instance, elemToDisplay, entry, "<li style='width:100%'><table class='tableAjaxList'><tr><td class='firstTdAjaxList'>", "</td></tr></table></li>")
	                     }
	                     ret.push(highlightedEntry);
	                     
					} else if(elem.codeComptable != null){
	                   	 elemToDisplay = elem.name + " (" + elem.codeComptable + ")";
	                     var highlightedEntry;
	                     if (isTheFirst) {
	                    	 highlightedEntry = this.highlightEntrySelection(instance, elemToDisplay, entry, "<li style='width:100%'><table class='firstTableAjaxList' cellspacing='0'><tr><td class='firstTdAjaxList'>", "</td><td class='secondTdAjaxList'><font class='typeOfCompletionLabel'>AGENCES</font></td></tr></table></li>")
	                         isTheFirst = false;
	                     } else {
	                    	 highlightedEntry = this.highlightEntrySelection(instance, elemToDisplay, entry, "<li style='width:100%'><table class='tableAjaxList'><tr><td class='firstTdAjaxList'>", "</td></tr></table></li>")
	                     }
	                     ret.push(highlightedEntry);
	                     
					}else{
						elemToDisplay = elem;
                        //on ignore les accents 
                        entry = no_accent(entry);
                        elem = no_accent(elemToDisplay);

                        var foundPos = instance.options.ignoreCase ? elem.toLowerCase().indexOf(entry.toLowerCase()) : elem.indexOf(entry);

                        while (foundPos != -1) {
                            if (foundPos == 0 && elem.length != entry.length) {
                                ret.push("<li style='width:100%'><table><tr><td><strong>" + elemToDisplay.substr(0, entry.length) + "</strong>" +
                                elemToDisplay.substr(entry.length) +
                                "</td></tr></table></li>");
                                break;
                            } else if (entry.length >= instance.options.partialChars && instance.options.partialSearch && foundPos != -1) {
                                if (instance.options.fullSearch ||
                                /\s/.test(elem.substr(foundPos - 1, 1))) {
                                    partial.push("<li style='width:100%'><table><tr><td>" + elemToDisplay.substr(0, foundPos) + "<strong>" +
                                    elemToDisplay.substr(foundPos, entry.length) +
                                    "</strong>" +
                                    elemToDisplay.substr(foundPos + entry.length) +
                                    "</td></tr></table></li>");
                                    break;
                                } else {
                                    alert("on l'ajoute pas");
                                }
                            } else {
                                alert("on l'ajoute pas non plus");
                            }
                            foundPos = instance.options.ignoreCase ? elem.toLowerCase().indexOf(entry.toLowerCase(), foundPos + 1) : elem.indexOf(entry, foundPos + 1);
                        }
                    }
                	listInnerHTML += "</li>";
                }
                listInnerHTML += "</ul>";
                if(listOfChoice){
                	listOfChoice.innerHTML = listInnerHTML;
                }
                if (partial.length) {
                    ret = ret.concat(partial.slice(0, instance.options.choices - ret.length))
				}
                return "<ul>" + ret.join('') + "</ul>";
            },
            
            valueSelector: function(object) {
                return object;
            },

            createLinkWithEntrySelection: function(listOfChoice, linkInner, code, lat, lng, inputToSetCode, inputToSetName){
            	//On remplace tout les ' de la chaîne par le code html &#146;
            	var lastFindedIndexOf = 0
            	while (lastFindedIndexOf < linkInner.lastIndexOf("'") && lastFindedIndexOf != -1){
            		lastFindedIndexOf = linkInner.indexOf("'", lastFindedIndexOf);
            		var beforeQuote = linkInner.substring(0, lastFindedIndexOf);
            		var afterQuote = linkInner.substring(lastFindedIndexOf + 1, linkInner.length); 
            		linkInner = beforeQuote + "&#39;" + afterQuote;
            	}
            	var onclick = 'javascript:updateChoice("'+listOfChoice+'","'+inputToSetName+'","'+inputToSetCode+'","'+linkInner+'","'+code+'","'+lat+'","'+lng+'");return false;';
            	var hiddenInf = code+"/"+linkInner;
            	if(lat != "" && lng != ""){
            		hiddenInf += "/"+lat+"/"+lng;
            	}
            	return "<a href='#' onclick='"+onclick+"'>" + linkInner + "<span style='display:none'>"+hiddenInf+"</span></a>";
            },
            
            highlightEntrySelection: function(instance, elemToDisplay, entry, prefix, suffix) {
                var elem = no_accent_strictly(elemToDisplay);
                var entry = no_accent_strictly(entry);

                var foundPos = instance.options.ignoreCase ? elem.toLowerCase().indexOf(entry.toLowerCase()) : elem.indexOf(entry);

                var highlightedEntry = prefix + elemToDisplay + suffix;
                if (foundPos != -1) {
                    if (foundPos == 0 && elem.length != entry.length) {
                    	highlightedEntry = prefix + "<strong>" + elemToDisplay.substr(0, entry.length) + "</strong>" +
                    					elemToDisplay.substr(entry.length) + suffix;
                    } else if (entry.length >= instance.options.partialChars && instance.options.partialSearch && foundPos != -1) {
                        if (instance.options.fullSearch ||
                        /\s/.test(elem.substr(foundPos - 1, 1))) {
                        	highlightedEntry = prefix + elemToDisplay.substr(0, foundPos) + "<strong>" +
                                               elemToDisplay.substr(foundPos, entry.length) + "</strong>" +
                                               elemToDisplay.substr(foundPos + entry.length) + suffix;
                        }
                    }
                }
                return highlightedEntry;
            }
        }, options ||
        {});
    }
    
});

