//--------------------------------
// Mario Menis
// Ajax Functions
// -------------------------------
//
// Ver 2.2
//	01.09.08 : Correzioni core
// Ver 2.1
//	01.09.08 : Patch.
//
// Ver 2.0
//      01.08.08 : Aggiunto openAjax che renderà obsoleta openAjaxLink
//                 sintassi : openAjax(arr_source,arr_dest,opt)
//                 Aggiunta possibilita di lavorare in sincorno.
//		   Aggiunto redirect a /index.php se status 401 ( NON AUTORIZZATO / SESSIONE SCADUTA )
// Ver 1.3
//	05.05.08 : Aggiunto supporto POST
// Ver 1.2
//	29.04.08 : Ora e' possibile passare una destinazione NULL per eseguire codice JS arbitrario
// Ver 1.1
//	10.04.08 : Aggiunto supporto per destinazioni di tipo SELECT. Il valore assegnato è l'indice "selectedIndex"
// Ver 1.0
// 	08.04.08 : Prima versione in produzione.
//		 : La funzione principale è openAjaxLink(where,what,preload) dove where e what sono array contenenti le destinazioni gli script da eseguire per ciascuno.
//		 : Gli elementi dell'array destinazione possono essere a loro volta array contenenti più destinazioni a patto che lo script relativo restituisca più pagine.
//		 : Per restituire più pagine lo script deve stampare il boundary "{ajaxEOF}" su uno singola riga tra una pagina e l'altra.
//		 : La destinazione può essere 'null'. In questo caso il contenuto restituito dello script relativo sarà scartato.
//		 : Lo script può contenere 'null'. In questo caso la destinazione verrà "svuotata"
//		 : Le destinazioni valide sono: 
//		 :    1)stringhe di riferimento all'id di un DIV / TEXTAREA / IMG e qualunque altro controllo che fornisca un value (Es: INPUT TYPE TEXT/HIDDEN)
//		 :    2)Array di stringhe definite come il punto 1)
//		 :    3)Immagini ( viene modificata la proprietà src )
//		 :    4)TODO... oggetti



// Oggetto Ajax base
function MyassegnaXMLHttpRequest() {
  var
  XHR = null,
  browserUtente = navigator.userAgent.toUpperCase();
  if(typeof(XMLHttpRequest) === "function" || typeof(XMLHttpRequest) === "object") {
    XHR = new XMLHttpRequest();
  } else if( window.ActiveXObject && browserUtente.indexOf("MSIE 4") < 0 ) {
    if(browserUtente.indexOf("MSIE 5") < 0) {
      XHR = new ActiveXObject("Msxml2.XMLHTTP");
    } else {
      XHR = new ActiveXObject("Microsoft.XMLHTTP");
    }
  }
  return XHR;
}


// Oggetto ajax automatico ( decide le operazioni da eseguire in base all'input)
function objAutoAjax(what,where) {
	// assegnamento dinamico di un valore ad un oggetto
        function assignDynValue(who,val) {
			// Esecuzione di codice senza assegnamento
                        if ( val.match(/^\n*\/\/\ Javascript/)) {
                                eval(val);
                                return;
                        }
                        dest = document.getElementById(who);
                        if (!dest) {
                                alert('destinazione \''+who+'\' non trovata');
								alert(val);
                                return;
                        }
			// Assegnamento html ad un DIV
                        if (dest.tagName=='DIV') {
                                dest.innerHTML=val;
			// Assegnamento testo ad una textarea
                        } else if (dest.tagName=='TEXTAREA') {
                                dest.value=val;
			} else if (dest.tagName=='SELECT') {
				dest.selectedIndex=val;
			// ..
			// .. TODO .. Assegnamento elementi tipo bottoni,checkbox.. etc
			// ..
			} else if (dest.tagName=='LABEL') {
				dest.innerText=val;
			// Assegnamento di default alla propieta' value
                        } else {
                                dest.value=val;
                        }
        }
	// Normalizzazione degli assegnamenti verso stringhe di id,array, e (oggetti TODO)
        function assignDynByTypeDef(a,b) {
                // stringa ( rif. all'id dell'oggetto)
                if (typeof(a)=='string') {
                        assignDynValue(a,b);
                // array
                } else if ( (typeof(a)=='object') && (a instanceof Array) ) {
                        for (var i=0;i<a.length;i++) {
                                if (b instanceof Array) {
					if (b[i] !== null) {
	                                        assignDynValue(a[i],b[i]);
					}
                                } else {
                                        assignDynValue(a[i],b);
                                }
                        }
                        // Altro? Passaggio diretto dell'oggetto?? ... TODO
                } else {
                        alert("Errore oAA003: impossibile ricavare la natura della destinazione");
                }
        }


	// Inizializzazione oggetto Ajax
        var myAjax=MyassegnaXMLHttpRequest();
	if (!myAjax) {
		// Broswer non compatibile
		alert('Il tuo broswer non supporta le funzionalita\' richieste.');
		return;
	}
		


	// Creazione oggetto indipendente, proprieta' e metodi di invio.
        var oAjax = {
                ajax    : myAjax,
                what    : what,
                where   : where,
                preload : 0,
		method  : "POST",
		async	: true,
        
		parseResponse	: function() {
	                if (this.ajax.status===200) {
        	                // Valuto la destinazione: ( n.b. da rendere il costrutto compatibile con la funzione assignDynByTypeDef
                	        // se stringa: ( rif. all'id dell'oggetto)
                        	if (typeof(where)=='string') {
	                                assignDynValue(where,this.ajax.responseText);
        	                // se array:
                	        } else if ( (typeof(where)=='object') && (where instanceof Array) ) {
                        	        myRetVals = this.ajax.responseText.split('\n{ajaxEOF}\n');
                                	for (var i=0;i<where.length;i++) {
                                                assignDynValue(where[i],myRetVals[i]);
	                                }
        	                // Se destinazione NULL (esecuzione codice js)
                	        } else if (!where) {
                        	        assignDynValue(null,this.ajax.responseText);
	                        // Altro? Passaggio diretto dell'oggetto?? ... TODO
        	                } else {
                	                alert("Errore oAA003: impossibile ricavare la natura della destinazione");
	                        }
        	        } else if (this.ajax.status===401) {
                	                // 2008-08-01 - Patch GM. Redirect in index su accesso non autorizzato
                        	        window.location.href='/index.php';
	                } else {
        	                // Errori ajax durante la ricezione.
                                alert("Errore oAA002: " + this.ajax.status + ":" + this.ajax.statusText);
                	}
        	},


        	readyStateFunction 	: function() {
	                if (this.ajax.readyState===4) {
				this.parseResponse();
                	// Gestione degli altri stadi ajax
	                } else if (this.ajax.readyState===3) {
        	        } else if (this.ajax.readyState===2) {
                	} else if (this.ajax.readyState===1) {
	                } else {
        	                // Gestione errore generico ajax
                	        alert('Errore oAA001. Riprova piu\' tardi.');
	                }
        	},


                go      : function() {
                                if (!this.what) {
                                        assignDynByTypeDef(this.where,'');
                                } else {
                                        // Se immagine
                                        if (document.getElementById(this.where) &&  document.getElementById(this.where).tagName=='IMG') {
                                                document.getElementById(this.where).src=this.what;
                                                return;
                                        }
                                        // Preloader
                                        if (this.preload) {
                                                assignDynByTypeDef(this.where,this.preload);
                                        }
					
					if (this.method == "POST") { 	
						link_post=this.what.split("?");
						if (!link_post[1]) link_post[1]='';

						if (!this.async) {
							//alert('Sync mode on');
							//this.ajax.async = false;
						} 

						this.ajax.open("POST",link_post[0],this.async);

						this.ajax.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
						this.ajax.setRequestHeader("Content-length", link_post[1].length);
						this.ajax.setRequestHeader("Connection", "close");
						this.ajax.send(link_post[1]);
					} else {
						if (!this.async) {
							//alert('Sync mode on');
							//this.ajax.async = false;
						} 
						this.ajax.open("GET",this.what+(what.match(/\?/)?"&":"?")+"req="+Math.floor(Math.random()*1000)+""+Math.floor(Math.random()*1000), this.async);
                                       	  this.ajax.setRequestHeader("connection", "close");
                                       	  this.ajax.send(null);
					}
					if (this.async) {
						var me=this;
						this.ajax.onreadystatechange=function(){me.readyStateFunction();};
					} else {
						this.parseResponse();
					}
                                }
                          }

        }
        return oAjax;
}



// Main function.
function openAjaxLink(where,what,preload,method) {
		
		if (document.noauth==1) {
			//alert('salto autenticazione');
			document.noauth=0;
		} else {
			openAjax(['/include_page/auth.php'],[null],'async:0');
		}
		

        for (i=0;i<what.length;i++) {
                ajax=objAutoAjax(what[i],where[i]);
		ajax.method=(method?method:"GET");
                if ( typeof(preload) == 'string' ) {
                        ajax.preload=preload;
                } else if (preload instanceof Array) {
                        if ( typeof(preload[i]) == 'string') {
                                ajax.preload=preload[i];
                        } else if ( preload[i] instanceof Array) {
                                ajax.preload=preload[i];
                        } else {
                                alert('Preloader non definito');
                                return;
                        }
                } else {
                        ajax.preload=0;
                }
                ajax.go();
        }
}

function openAjax(what,where,opt) {

	// Gestione opzioni
	opts=opt.replace(/ /g,'').split(';');
	for (i=0;i<opts.length;i++) {
		param=opts[i].split(':');
		switch (param[0]) {
			case 'preload':
				var preload=param[1]; break;
			case 'preloads':
				var preload=param[1].split(',');  break;
			case 'method':
				var method=param[1]; break;
			case 'async':
				var async=param[1]; break;
			case 'auth':
				openAjax(Array(param[1]),[null],'async:0'); break;
			default:
				alert('openAjax: Parametro non supportato \''+param[0]+'\''); return;
		}
	}
	for (i=0;i<what.length;i++) {
        ajax=objAutoAjax(what[i],where[i]);

		ajax.method=(method?method:"POST");
		ajax.async=(async==0?false:true);
		//alert(ajax.async);
        if ( typeof(preload) == 'string' ) {
  			ajax.preload=preload;
        } else if (preload instanceof Array) {
            if ( typeof(preload[i]) == 'string') {
            	ajax.preload=preload[i];
            } else if ( preload[i] instanceof Array) {
            	ajax.preload=preload[i];
            } else {
            	alert('Preloader non definito');
                return;
            }
        } else {
        	ajax.preload=0;
        }
		/*
		// Patch per FF 3.0.1 - In modalità sincrona FF non lancia l'evento OnReadyStateChange;
		// La patch controlla ogni 500mS se ci è pervenuto qualche cosa.
		if (navigator.appName.match(/netscape/i)) {
			//alert('Trovato FF/NN:'+navigator.userAgent);
			if (navigator.userAgent.match(/Firefox\/3\.0\.1/i)) {
				//alert("Trovato FFox buggy");
				ajax.wait();
			}
		}
		*/
        ajax.go();
    }
}

