/* ==================================================================*/
/* FUNZIONI AJAX WINTRADE ===========================================*/
/* ==================================================================*/



/**********************************************************************
	Crea e ritorna una XMLHttpRequest
**********************************************************************/
function wt_createXMLHttpRequest() {
	if (window.ActiveXObject) {
		return new ActiveXObject("Microsoft.XMLHTTP");
	} 
	else if (window.XMLHttpRequest) {
		return new XMLHttpRequest();
	}
}



/**********************************************************************
	Aggiorna un array di campi select leggendo i dati da file XML
	
	Attenzione: se si vuole eseguire la stessa operazione da una popup,
	utilizzare la wt_updateSelectArrayFromPopup() (vedi)
	
	aSel    = array di "oggetti" che rappresentano le select;
			  ogni oggetto dev'essere così stutturato:
				selectArray[i].id                   = id del campo select i-esimo
				selectArray[i].xmlUrl               = url del file XML contenente i dati
				selectArray[i].xmlTagName           = nome dei tag XML che contengono i dati voluti
				selectArray[i].xmlOptValueTagName   = nome dei tag XML che contengono i valori per le option
				selectArray[i].xmlOptTextTagName    = nome dei tag XML che contengono i testi per le option
				selectArray[i].defaultValue         = valore della option da selezionare per default (null=la prima).
													  E' possibile anche passare anche un array (per le select multiple).
													  Se viene passato anche vSel, vSel viene considerato
													  al posto di defaultValue
				selectArray[i].valueSourceId		= (FACOLTATIVO) id del campo input dal quale leggere l'attributo
													  "value" da passare all'xmlUrl per filtrare i dati da leggere.
													  Se valueSourceId non viene definito, all'xmlUrl viene passato
													  il value della select che precede quella corrente (se esiste).
				selectArray[i].finalCallBack		= (FACOLTATIVO) riferimento ad una funzione che deve essere
													  richiamata una volta completato l'aggiornamento di tutte
													  le select
	iSel    = indice della prima select da aggiornare
	vSel    = valore della option da preselezionare (null = la prima)
			  E' possibile anche passare anche un array (per le select multiple).
**********************************************************************/
function wt_updateSelectArray(aSel, iSel, vSel) {
	
	// Azzero tutte le select dell'array -----------------------
	wt_clearSelectArray(aSel, iSel);

	var xmlHttp = wt_createXMLHttpRequest();
	var rqstURL = aSel[iSel].xmlUrl;
	
	// se la select attuale dipende da una sorgente di valori, nell'url
	// passo anche il valore attuale di tale sorgente...
	if(aSel[iSel].valueSourceId) {
		var sourceSel = document.getElementById(aSel[iSel].valueSourceId);
		var values = "";
		
		if(sourceSel.options) {
			for(var i=0; i<sourceSel.options.length; i++) {
				if(sourceSel.options[i].selected) {
					if(values == "")
						values = sourceSel.options[i].value;
					else
						values = values + "," + sourceSel.options[i].value;
				}
			}
		}
		else {
			// nel caso la sorgente non sia una select (TODO: DA PROVARE)
			values = document.getElementById(aSel[iSel].valueSourceId).value;
		}	
	  
		rqstURL += values;

	}
	// ... altrimenti, se la select attuale non è la prima, nell'url
	// passo anche il valore della select che la precede, in modo da
	// caricare in essa solo i dati relativi alla option selezionata
	// nella select precedente
	else if(iSel > 0) {
		var sourceSel = document.getElementById(aSel[iSel-1].id);
		var values = "";
		
		if(sourceSel.options) {
			for(var i=0; i<sourceSel.options.length; i++) {
				if(sourceSel.options[i].selected) {
					if(values == "")
						values = sourceSel.options[i].value;
					else
						values = values + "," + sourceSel.options[i].value;
				}
			}
		}
		else {
			// nel caso la sorgente non sia una select (TODO: DA PROVARE)
			values = document.getElementById(aSel[iSel-1].id).value;
		}	
	  
		rqstURL += values;
	}
	
	rqstURL = wt_getNoCachedRqstURL(rqstURL);
	
	//debug: alert("rqstURL= " + rqstURL);
	
	// definisco in questo modo la callback per poterle inviare dei parametri
	xmlHttp.onreadystatechange = function() {wt_updateSelectArray_callBack(xmlHttp, aSel, iSel, vSel);}; 
	xmlHttp.open("GET", rqstURL, true);
	xmlHttp.send(null);

}



/**********************************************************************
	Callback della XMLHttpRequest richiamata dalla wt_updateSelectArray()
	Viene richiamata ad ogni cambio stato della richiesta.
	Ha gli stessi parametri della wt_updateSelectArray() più il parametro
	xmlHttp.
**********************************************************************/
function wt_updateSelectArray_callBack(xmlHttp, aSel, iSel, vSel) {
	/*
		controllo stato richiesta:
			0 = non inizializzata
			1 = caricamento in corso
			2 = caricamento completato
			3 = interattiva
			4 = completata
		
			e lo stato HTTP:
			200 = OK
			404 = not found
			500 = errore del server
			...
	*/
	if(xmlHttp.readyState == 4) {
		if(xmlHttp.status == 200) {

			
			
			// popolo la select iSel-esima -----------------------------
			var sel = document.getElementById(aSel[iSel].id);
			var dati = xmlHttp.responseXML.getElementsByTagName(aSel[iSel].xmlTagName);
			var option = null;
							  
			//debug: alert("aggiorno select " + aSel[iSel].xmlTagName + "\ndati.length=" + dati.length);

			for(var i = 0; i < dati.length; i++) {
				
				var dato = dati[i]; 
				var optionValue = dato.getElementsByTagName(aSel[iSel].xmlOptValueTagName)[0].childNodes[0].nodeValue;
				var optionText = dato.getElementsByTagName(aSel[iSel].xmlOptTextTagName)[0].childNodes[0].nodeValue;
				//debug: alert("optionValue=" + optionValue + "\noptionText=" + optionText);
			
				// preseleziono l'option richiesta --------
				var valoreDaSelezionare;
				var optionSelected;
				if(vSel != null)
					valoreDaSelezionare = vSel;
				else
					valoreDaSelezionare = aSel[iSel].defaultValue;
				
				
				// il valore da selezionare è un array di valori (select multipla) -------
				if(valoreDaSelezionare != null && wt_isArray(valoreDaSelezionare)) {
					optionSelected = false;
					for(var j = 0; j < valoreDaSelezionare.length; j++) {
						//debug: alert("array valoreDaSelezionare[" + j +"]=" + valoreDaSelezionare[j] + " ----- optionValue=" + optionValue);
						if(optionValue == valoreDaSelezionare[j]) {
							optionSelected = true;
							break;
						}
					}
				}
				// il valore da selezionare è singolo (select semplice) -------------------
				else {
					//debug: alert("valore singolo");
					if(optionValue == valoreDaSelezionare)
						optionSelected = true;
					else
						optionSelected = false;
				}
				
				// aggiungo la option alla select ------    
				wt_appendOption(sel, optionValue, optionText, optionSelected);
				
			}
			
			// Riabilito la select -----------
			wt_enableSelect(sel);
			

			
			// Richiamo la funzione "finale" (se richiesto) ------------
			if(aSel[iSel].finalCallBack) {
				aSel[iSel].finalCallBack();	
			}

			// Aggiorno la select successiva dell'array ----------------
			if(iSel+1 < aSel.length)
				wt_updateSelectArray(aSel, iSel+1, null);

				
		}
		else {
			//debug: alert("Errore (" + xmlHttp.status + ") nel caricamento dati !");
		}
	}
}



/**********************************************************************
	Azzera le option di un array di campi select, inserisce una sola
	option con un messaggio di "loading" e disabilita ogni select
	
	aSel    = array di "oggetti" che rappresentano le select
			  (vedi updateArraySelect())
	iSel    = indice della prima select da azzerare
**********************************************************************/
function wt_clearSelectArray(aSel, iSel) {
	var sel;
	
	for(i=iSel; i < aSel.length; i++) {
		
	sel = document.getElementById(aSel[i].id)
		
		sel.disabled = true;
		
		wt_clearSelect(sel);
		
		wt_appendOption(sel, "", "attendere caricamento...", true);

	} 
}



 /**********************************************************************
	Rimuove la option con il messaggio di loading e riabilita
	la select 
	
	sel    = l'oggetto select da riabilitare
**********************************************************************/
function wt_enableSelect(sel) {
	// rimuovo messaggio di caricamento
	sel.removeChild(sel.childNodes[0]);
	
	// riabilito select
	sel.disabled = false;
}




 /**********************************************************************
	Rimuove le option di una select.
	
	sel    = l'oggetto select da azzerare
**********************************************************************/
function wt_clearSelect(sel) {
	while(sel.childNodes.length > 0) {
		sel.removeChild(sel.childNodes[0]);
	}
}




 /**********************************************************************
	Aggiunge una option ad una select.
	
	sel             = l'oggetto select 
	optionValue     = valore della option
	optionText      = testo della option
	optionSelected  = true/false per selezionare o meno la option
**********************************************************************/
function wt_appendOption(sel, optionValue, optionText, optionSelected) { 
	var option = document.createElement("option");
	
	option.appendChild(document.createTextNode(optionText));
	option.setAttribute("value", optionValue);
	if(optionSelected)
		option.setAttribute("selected", "selected");

	sel.appendChild(option);
}




 /**********************************************************************
	Questa funzione dev'essere richiamata al posto della
	wt_updateSelectArray() se si vuole aggiornare l'array da una popup
	e chiudere la popup stessa.
	
	E' necessario fare così altrimenti per un bug di Firefox (? da verificare)
	richiamando direttamente la wt_updateSelectArray() dalla popup e poi 
	chiudendola si perde l'oggetto XMLHttpRequest (in quanto viene
	associato al context della popup)
**********************************************************************/
function wt_updateSelectArrayFromPopup(aSel, iSel, vSel) {
	var f = function() {wt_updateSelectArray(aSel, iSel, vSel);};
	setTimeout(f, 0);
} 




/**********************************************************************
	Questa funzione richiama una callBack passandole il
	valore singolo letto dalla pagina XML richiesta.
	Se la pagina dovesse ritornare più elementi con lo stesso
	tagName viene ritornato solo il valore del primo.
	
	rqstURL		= url della pagina XML
	tagName		= nome dell'elemento che contiene il valore da leggere
	callBack	= riferimento alla funzione da richiamare e alla quale
				  verrà passato il valore letto
**********************************************************************/
function wt_getXMLSingleValue(rqstURL, tagName, callBack) {
	var xmlHttp = wt_createXMLHttpRequest();

	//debug: alert("wt_getXMLSingleValue(): inizio");


	rqstURL = wt_getNoCachedRqstURL(rqstURL);

	//debug: alert("rqstURL=" + rqstURL);
	
	xmlHttp.onreadystatechange = function() {
		if(xmlHttp.readyState == 4) {
			if(xmlHttp.status == 200) {
				var value = xmlHttp.responseXML.getElementsByTagName(tagName)[0].childNodes[0].nodeValue;
				callBack(value);
			}
			else {
				//debug: alert("Errore (" + xmlHttp.status + ") nel caricamento dati !");
			}

		}
	}; 
	
	xmlHttp.open("GET", rqstURL, true);
	xmlHttp.send(null);
}



/**********************************************************************
	Questa funzione ritorna un URL "univoco" per impedire che venga
	ritornata una versione in cache della pagina corrispondente
	in una tipica chiamata Ajax
	
	rqstURL = l'url da trasformare
**********************************************************************/
function wt_getNoCachedRqstURL(rqstURL) {
	return rqstURL += "&ts_" + new Date().getTime();
}



/**********************************************************************
	Valuta se un oggetto è un'Array
**********************************************************************/
function wt_isArray(obj) {
    return obj.constructor == Array;
}
