// autocomplete and related changes
// Copyright 2004 Leslie A. Hensley
// hensleyl@papermountain.org
// you have a license to do what ever you like with this code
// orginally from Avai Bryant 
// http://www.cincomsmalltalk.com/userblogs/avi/blogView?entry=3268075684

// Feb-2006 Modifiche mie

if (navigator.userAgent.indexOf("Safari") > 0) {
  isSafari = true;
  isMoz = false;
  isIE = false;
} else if (navigator.product == "Gecko") {
  isSafari = false;
  isMoz = true;
  isIE = false;
} else {
  isSafari = false;
  isMoz = false;
  isIE = true;
}


















/////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////
///
/// Funzione che setta gli oggetti per l'autocompletion.
///
/// idTextBox : id dell'oggetto testo a cui aggangiare l'autocompletion
/// popupId   : id del div dove creare la lista di oggetti
/// Ancora    : id del div che serve per sapere dove far apparire l'autocompletion
///				deve essere un div perch? si pu? prendere la posizione
///
///	Uri       : pagina da chiamare per per avere la lista 
///
/// idRitorno : id dell'oggetto input dove mettere l'id del risultato
///
///	queste cose bisogna cambiarle: bisogna passagli due funzioni: una per 
/// settare altre variabili che non centra con l'autocompletion generale
/// e un'altra funzione per definire il click cosa deve settare dopo il click le variabili
///
/// idProvincia: id dell'oggetto dove inserire la provincia
/// dsCap: id dell'oggetto dove inserire il cap primario
///
/////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////


function autocompletion_object (idTextBox, popupId, Ancora, uri, idRitorno, url_dettaglio, funzione_post, funzione_svuota){
	this.xmlreq=false;


	/*this.nome="pippo";
	this.parametro=nome_funzione_get;
	this.update=function () {
        alert ("alert: "+this.nome);
    }
	this.prova=function () {
        this.update();
    }
    */
    /**
	 * ritorna la request per browser Microsoft
	 */
	this.newXMLHttpRequestAutoComplete=function () {
		//alert ("this.newXMLHttpRequestAutoComplete");
		try {
			req= new ActiveXObject("Msxml2.XMLHTTP");
		} catch (e1) {
			try {
				req= new ActiveXObject("Microsoft.XMLHTTP");
			} catch (e2) {
				req = false;
			}
		}
		return (req);
	}
    
    
    
    /*
	  liveUpdater returns the live update function to use
	  uriFunc: The function to generate the uri
	  postFunc: <optional> Function to run after processing is complete
	  preFunc: <option> Function to run before processing starts
	*/
	
	this.liveUpdater=function () {
		//alert ("liveUpdater");
		return createLiveUpdaterFunction();
	}
    
    
    
    
	this.update=function () {
		
        if(request && request.readyState < 4)
            request.abort();
            
        // per IE occorre ricreare la request, altrimenti
        // non scatta il trigger "onreadystatechange"
        if(!window.XMLHttpRequest)
            request = newXMLHttpRequestAutoComplete();
            //request = new ActiveXObject("Microsoft.XMLHTTP");

        // eventuale funzione pre-request
        preFunc();
        
        request.onreadystatechange = processRequestChange;
        
         
        
        request.open("GET", constructUri());
        request.send(null);
        return true;
    }
    
    
    
    
    /**
     * Funzione che parsa l'XML risultato 
     * l'XML prodotto e' 
     *   <body>
     *     <div id="autocomplete-popup">
		 *       <ul>
		 *         <li id="11702">SANT'ANGELO IN COLLE</li> 
		 *         <li id="11703">SANT'ANGELO IN FORMIS</li> 
		 *         ...
		 *       </ul>
		 *     </div>
		 *   </body>
     */
    this.processRequestChange=function () {
		if(request.readyState == 4) {
			//alert ("4");
			if((request.status == 200)||(request.status == 0)) {
				var xmlDoc = request.responseXML
				var body = xmlDoc.getElementsByTagName("body");
				if(body.length>0) {
					var nodes = body[0].childNodes
					for(var i=0;i<nodes.length;i++) {
						if(nodes[i].nodeType==1 && nodes[i].getAttribute("id")!=null) {
							//var id = popupId;
							// praticamente recupero il div e ci metto dentro <ul> della response
							//alert (flattenChildren(nodes[i].childNodes));
							popup.innerHTML = flattenChildren(nodes[i].childNodes);
						}
					}
				}
				//evalScripts(xmlDoc);
				// addirittura se nell'xml c'? un tag script lo esegue..
				var scripts = xmlDoc.getElementsByTagName("script");
				for(var i=0;i<scripts.length;i++) {
					if(scripts[i].firstChild!=null) {
						var script = scripts[i].firstChild.nodeValue
						if(script != null) {
							eval(script)
						}
					}
				}
				// eventuale funzione post-request
				post();
		      } else {
		        // An HTTP problem has occurred
		        alert("HTTP error "+request.status+": "+request.statusText);
		      }
		}
	}
    
	this.createLiveUpdaterFunction=function () {
		//alert ("createLiveUpdaterFunction");
	    // Mozilla permette di riutilizzare sempre la stessa request
	    if (window.XMLHttpRequest) {
	      request=new XMLHttpRequest();
	    }
	
		return update();
	} 
    
    
    this.evalScripts=function (node) {
		for(var i=0;i<node.childNodes.length;i++) {
			if(node.childNodes[i].tagName == "script") {
				if(node.childNodes[i].firstChild!=null) {
					var script = node.childNodes[i].firstChild.nodeValue
					if(script != null) {
						eval(script);
					}
				}
			} else {
				this.evalScripts(node.childNodes[i]);
			}
		}
	}
    
    
    this.constructUri = function () {
        var separator = "?";
        if(uri.indexOf("?") >= 0)
            separator = "&";
            
        //alert(uri + separator + "s=" + escape(inputField.value));
        if (inputField){
	        return uri + separator + "s=" + escape(inputField.value);
		}else{
			return uri + separator + "s=";
		}
    }
    
    
    this.hidePopup=function () {
		if(inputField.value=="") {
			id_ritornoObj.value="";	
			empty_function();
			
		}
		popup.style.visibility = 'hidden';
    }
    
    
    this.handlePopupOver=function () {
		removeListener(inputField, 'blur', hidePopup);
    }
    
    
    this.handlePopupOut=function () {
		if(popup.style.visibility == 'visible') {
			addListener(inputField, 'blur', hidePopup);
		}
	}
    
    
    this.handleClick=function (e) {
    
    
    	if (!selectFunction){
    		if (options && options[current]) {
				inputField.value = options[current].innerHTML;
				// recupero le info associate al comune selezionato
				id_ritornoObj.value = options[current].getAttribute("id");
				
				if (post_function){
					post_function(urlDettaglio+options[current].getAttribute("id"));
				}
			}
		}else{
			selectFunction(options[current]);
		}
    
    	/*
		inputField.value = eventElement(e).innerHTML;
      
		// recupero le info associate al comune selezionato
		//-----------------------------------------------------------
		// NOTA: la dichiarazione della funzione nella pagina HTML
		// deve essere fatta dopo la definizione dei campi altrimenti
		// getElementById torna null
		//-----------------------------------------------------------
		id_ritornoObj.value = options[current].getAttribute("id");
		//ho tolto per fare delle prove
		//id_provinciaObj.value = options[current].getAttribute("lang");
		//ds_capObj.value = options[current].getAttribute("prefix");
		if (post_function){
			post_function(urlDettaglio+options[current].getAttribute("id"));
		}*/
		popup.style.visibility = 'hidden';
		inputField.focus();
    }
    
    this.handleOver=function (e) {
    	if (options && options[current]) {
			options[current].className = '';
			current = eventElement(e).index;
			options[current].className = 'selected';
		}
	}
    
    
    
    this.post=function () {
		current = 0;
		options = popup.getElementsByTagName("li");
		
        if((options.length > 1) || (options.length == 1 && options[0].innerHTML != inputField.value)) {
			setPopupStyles();
			for(var i = 0; i < options.length; i++) {
				options[i].index = i;
				addOptionHandlers(options[i]);
			}
			options[0].className = 'selected';
		} else {
			popup.style.visibility = 'hidden';
		}
	}
    
    
    this.findPosX=function (obj) {
		var curleft = 0;
		if (obj.offsetParent) {
			while (obj.offsetParent) {
				curleft += obj.offsetLeft
				obj = obj.offsetParent;
			}
		} else if (obj.x) {
			curleft += obj.x;
		}
		return curleft;
	}

	this.findPosY=function (obj) {
		var curtop = 0;
		if (obj.offsetParent) {
			while (obj.offsetParent) {
				curtop += obj.offsetTop
				obj = obj.offsetParent;
			}
		} else if (obj.y) {
			curtop += obj.y;
		}
		return curtop;
	}

	this.setPopupStyles=function () {
		// uso l'oggetto ancora per sapere dove posizionare la popup
		// l'oggetto ancora ? solo un div posizionato sotto alla textbox in questione
		var maxHeight=150;
		popup.style.left = findPosX(objAncora)+'px';
		popup.style.top = findPosY(objAncora)+'px';
		if(popup.offsetHeight < maxHeight) {
			popup.style.overflow = 'hidden';
		} else if(isMoz) {
			popup.style.maxHeight = maxHeight + 'px';
			popup.style.overflow = '-moz-scrollbars-vertical';
		} else {
			popup.style.height = maxHeight + 'px';
			popup.style.overflowY = 'auto';
		}
		popup.scrollTop = 0;
		popup.style.visibility = 'visible';
	}  
    
    
    this.addOptionHandlers=function (option) {
		this.addListener(option, "click", this.handleClick);
		this.addListener(option, "mouseover", this.handleOver);
    }
    
  


	this.start=function (e) {
	
		
		//alert("start");
		if (timeout) {
			window.clearTimeout(timeout);
		}
		//up arrow
		if(e.keyCode == 38) {
			if(current > 0) {
				if (options && options[current]) {
					options[current].className = '';
					current--;
					options[current].className = 'selected';
					options[current].scrollIntoView(false);
					window.status="aaaaaaaaaaaaaaaaaa"+current;
				}
			}
		} else if(e.keyCode == 40) { //down arrow
			if(current < options.length - 1) {
				if (options && options[current]) {
					options[current].className = '';
					current++;
					options[current].className = 'selected';
					options[current].scrollIntoView(false);
					window.status="aaaaaaaaaaaaaaaaaa"+current;
				}
			}
		} else if((e.keyCode == 13 || e.keyCode == 9) && popup.style.visibility == 'visible') { //enter or tab

			if (!selectFunction){
				if (options && options[current]) {
					inputField.value = options[current].innerHTML;
					// recupero le info associate al comune selezionato
					id_ritornoObj.value = options[current].getAttribute("id");
					
					if (post_function){
						post_function(urlDettaglio+options[current].getAttribute("id"));
					}
				}
			}else{
				selectFunction(options[current]);
			}
			
			
			popup.style.visibility = 'hidden';
			inputField.focus();
			// L'evento viene cancellato
			if(isIE) {
				event.returnValue = false;
			} else {
				e.preventDefault();
			}
		} else {
			//alert ("invoco ajax a tempo");
			//liveUpdater();
			// invoco in ajax a tempo
			timeout = window.setTimeout( liveUpdater, 300);
		}
		
	}
    
    this.sgancia=function(){
    	removeKeyListener(inputField, this.start);
    }
    
    
    
    this.aggangia=function(){
		uri=this.uri;
	    inputField = this.inputField;
	    popup = this.popup;
	    options = this.options; 
	    current = this.current;
	    originalPopupTop = this.originalPopupTop;
	    urlDettaglio=this.urlDettaglio;
	    
	    post_function=this.post_function;
	    empty_function=this.empty_function;
	
	    id_ritornoObj=this.id_ritornoObj;
	    
	    objAncora=this.objAncora;
	    
	    
	    postFunc=this.postFunc;
		preFunc=this.preFunc;
		timeout=this.timeout;
	    this.timeout = false;
	    
		createLiveUpdaterFunction=this.createLiveUpdaterFunction;
		update=this.update;
		newXMLHttpRequestAutoComplete=this.newXMLHttpRequestAutoComplete;
		
		
		processRequestChange=this.processRequestChange;
	    liveUpdater = this.liveUpdater;
	    
        post=this.post;
        setPopupStyles=this.setPopupStyles;
        findPosX=this.findPosX;
        findPosY=this.findPosY;
        addOptionHandlers=this.addOptionHandlers;
        
        handleClick=this.handleClick;
        handleOver=this.handleOver;
        hidePopup=this.hidePopup;
        constructUri=this.constructUri;
		selectFunction=this.selectFunction;
		start=this.start;
		request=this.request;	   
	   
		//alert ("prova"+inputField.value);
		addKeyListener(inputField, this.start);
		addListener(popup, 'mouseover', this.handlePopupOver);
		addListener(popup, 'mouseout', this.handlePopupOut);	
	}      
    
    this.uri=uri;
    this.inputField = document.getElementById(idTextBox);
    this.popup = document.getElementById(popupId);
    this.options = new Array(); 
    this.current = 0;
    this.originalPopupTop = this.popup.offsetTop;    
    this.urlDettaglio=url_dettaglio;
    
    
    this.selectFunction=false;
    this.post_function=funzione_post;
    this.empty_function=funzione_svuota;

    this.id_ritornoObj=document.getElementById(idRitorno);
    
    this.objAncora=document.getElementById(Ancora);
    
    
    if(!this.postFunc) this.postFunc = function () {};
	if(!this.preFunc) this.preFunc = function () {};
    this.timeout = false;

    this.aggangia();

}


	
	
	
	
	
	
	
	
	

	
