var Url = {

    // public method for url encoding
    encode : function (string) {
        return escape(this._utf8_encode(string));
    },

    // public method for url decoding
    decode : function (string) {
        return this._utf8_decode(unescape(string));
    },

    // private method for UTF-8 encoding
    _utf8_encode : function (string) {
        string = string.replace(/\r\n/g,"\n");
        var utftext = "";

        for (var n = 0; n < string.length; n++) {

            var c = string.charCodeAt(n);

            if (c < 128) {
                utftext += String.fromCharCode(c);
            }
            else if((c > 127) && (c < 2048)) {
                utftext += String.fromCharCode((c >> 6) | 192);
                utftext += String.fromCharCode((c & 63) | 128);
            }
            else {
                utftext += String.fromCharCode((c >> 12) | 224);
                utftext += String.fromCharCode(((c >> 6) & 63) | 128);
                utftext += String.fromCharCode((c & 63) | 128);
            }
            
        }

        return utftext;
    },

    // private method for UTF-8 decoding
    _utf8_decode : function (utftext) {
        var string = "";
        var i = 0;
        var c = c1 = c2 = 0;

        while ( i < utftext.length ) {

            c = utftext.charCodeAt(i);
            if (c < 128) {
                car = String.fromCharCode(c);
                i++;
            }
            else if((c > 191) && (c < 224)) {
                c2 = utftext.charCodeAt(i+1);
                car = String.fromCharCode(((c & 31) << 6) | (c2 & 63));
                i += 2;
            }
            else {
                c2 = utftext.charCodeAt(i+1);
                c3 = utftext.charCodeAt(i+2);
                car = String.fromCharCode(((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63));
                i += 3;
            }
            if (car == "+"){
                car = " ";
            }
            string += car;
            
        }
        return string;
    }

}




// funzione per prendere un elemento con id univoco
		function prendiElementoDaId(id_elemento) {
			var elemento;
			if(document.getElementById)
				elemento = document.getElementById(id_elemento);
			else
				elemento = document.all[id_elemento];
			return elemento;
		};
	
	// funzione per assegnare un oggetto XMLHttpRequest
		function assegnaXMLHttpRequest() {
			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;
			
		};



/** OGGETTI / ARRAY */

	// oggetto di verifica stato
		var readyState = {
			INATTIVO:	0,
			INIZIALIZZATO:	1,
			RICHIESTA:	2,
			RISPOSTA:	3,
			COMPLETATO:	4
		};

	// array descrittivo dei codici restituiti dal server
	// [la scelta dell' array è per evitare problemi con vecchi browsers]
		var statusText = new Array();
		statusText[100] = "Continue";
		statusText[101] = "Switching Protocols";
		statusText[200] = "OK";
		statusText[201] = "Created";
		statusText[202] = "Accepted";
		statusText[203] = "Non-Authoritative Information";
		statusText[204] = "No Content";
		statusText[205] = "Reset Content";
		statusText[206] = "Partial Content";
		statusText[300] = "Multiple Choices";
		statusText[301] = "Moved Permanently";
		statusText[302] = "Found";
		statusText[303] = "See Other";
		statusText[304] = "Not Modified";
		statusText[305] = "Use Proxy";
		statusText[306] = "(unused, but reserved)";
		statusText[307] = "Temporary Redirect";
		statusText[400] = "Bad Request";
		statusText[401] = "Unauthorized";
		statusText[402] = "Payment Required";
		statusText[403] = "Forbidden";
		statusText[404] = "Not Found";
		statusText[405] = "Method Not Allowed";
		statusText[406] = "Not Acceptable";
		statusText[407] = "Proxy Authentication Required";
		statusText[408] = "Request Timeout";
		statusText[409] = "Conflict";
		statusText[410] = "Gone";
		statusText[411] = "Length Required";
		statusText[412] = "Precondition Failed";
		statusText[413] = "Request Entity Too Large";
		statusText[414] = "Request-URI Too Long";
		statusText[415] = "Unsupported Media Type";
		statusText[416] = "Requested Range Not Satisfiable";
		statusText[417] = "Expectation Failed";
		statusText[500] = "Internal Server Error";
		statusText[501] = "Not Implemented";
		statusText[502] = "Bad Gateway";
		statusText[503] = "Service Unavailable";
		statusText[504] = "Gateway Timeout";
		statusText[505] = "HTTP Version Not Supported";
		statusText[509] = "Bandwidth Limit Exceeded";

function carica(link) {
  var  
    ajax = assegnaXMLHttpRequest(),
    elemento = prendiElementoDaId(link.id),
    usaLink = true,

    // variabili di controllo del tempo
  
    // data di inizio interazione
    dataChiamata = new Date(),
    // tempo in millisecondi dell'inizio
    inizioChiamata = dataChiamata.getTime(),
    // secondi di attesa prima di fermare l'interazione
    massimaAttesa = 10,
    // variabile cui assegnare la funzione di verifica
    verificaTempoTrascorso;

  if(ajax) {
  	
    usaLink = false;
	
    // parametro fittizio all'elemento link
    // per evitare un doppio click
    if(!link.clicked) {

      // se il parametro è risultato undefined o false
      // entriamo e gli assegnamo true
      link.clicked = true;
		elemento = prendiElementoDaId("inmueble" + link.id_inm);
      // NOTA. Qualora l'elemento dovesse essere parte di un form si potrebbe
      // sfruttare il parametro "disabled", assegnandolo solo quando necessario.

      // effettuiamo la chiamata sul parametro href
      ajax.open("get", link.page + "?id_inmueble=" + link.id_inm, true);
   			// imposto il giusto header
	  
	  //ajax.setRequestHeader("content-type", "application/x-www-form-urlencoded");

			// effettuo la richiesta inviando la variabile leggi con contenuto Dante
      //ajax.send("id_inmueble=" + link.id_inm);
      
      ajax.setRequestHeader("connection", "close");
      
      ajax.onreadystatechange = function() {

        // se la richiesta è già stata completata
        if(ajax.readyState === readyState.COMPLETATO) {
          // annulliamo la funzione di verifica tempo
          verificaTempoTrascorso = function(){};

          // e continuiamo con i normali controlli
          if(statusText[ajax.status] === "OK") {
            if(ajax.responseText)
              elemento.innerHTML = ajax.responseText;
            else
              elemento.innerHTML =
                "L'XML restituito dalla richiesta non è valido.<br />" +
                ajax.responseText.split('<').join("&lt;").split('>').join("&gt;");
          }
          else
            elemento.innerHTML =
              "Imposible realizar la operacion requerida" +
              "Error: " + statusText[ajax.status];

          // se il link non dovesse esser sovrascritto, come invece accade in questo esempio,
          // è importante ricordarsi di riabilitarlo reimpostando il parametro fittizio
          // Esempio: link.clicked = false;
        }

        // se la richiesta non è stata ancora ultimata
        // è possibile sfruttare la variabile massimaAttesa
        // per verificare se il controllo sul tempo trascorso
        // sia stato creato o meno.
        // Essendo tale valore un intero rappresentante i secondi
        // ma non essendo ancora stato riassegnato nel corrispettivo
        // in millesimi, questo else if può garantire che
        // il codice al suo interno verrà eseguito una sola volta
        else if(massimaAttesa < 1000) {

          // conversione di massimaAttesain millisecondi
          massimaAttesa = massimaAttesa * 1000;

          // il controllo sul tempo trascorso deve essere
          // asincrono a questa funzione poichè non è detto
          // che il cambio di stato della richiesta
          // venga effettuato in tempi utili.
          // Una funzione apposita per la verifica
          // è la soluzione più indicata
          verificaTempoTrascorso = function() {

            // ogni chiamata asincrona a questa funzione
            // dovrà verificare la durata dell'interazione
            // è necessario quindi ridichiarare la variabile
            // al fine di ottenere il nuovo oggetto Date
            dataChiamata = new Date();

            // Se il tempo trascorso è maggiore della
            // massima attesa ...
            if((dataChiamata.getTime() - inizioChiamata) > massimaAttesa) {

              // ... interrompiamo la richiesta ed
              // informarmiamo l'utente di quanto avvenuto.

              // Quindi riassegnamo onreadystatechange ad una
              // funzione vuota, poichè quest'evento sarà
              // sollevato chiamando il metodo abort()
              ajax.onreadystatechange = function(){return;};

              // è possibile a questo punto richiamare il metodo abort
              // ed annullare le operazioni dell'oggetto XMLHttpRequest
              ajax.abort();

              // creiamo un elemento per avvertire l'utente
              // del fallimento della richiesta da aggiungere
              // a quello predisposto per mostrare il risultato.
              // Usiamo il metodo createElement() del document e
              // non innerHTML,che potrebbe riscrivere il link selezionato
              // annullando l'assegnazione del parametro fittizio.
              // Avendo annullato l'utilità dell'oggetto XMLHttpRequest
              // è possibile anche riciclare la variabile 'ajax'.
              //ajax = document.createElement("p");
              //ajax.innerHTML =
              //   "Spiacente, richiesta fallita.<br />" +
              //   "La prego di ritentare tra qualche istante.";

              //elemento.appendChild(ajax);
       
       
              // è possibile ripristinare il parametro fittizio del link
              // su 'false' sia subito che con qualche istante di latenza,
              // Infatti l'attuale situazione può essere generata dalla
              // risposta lenta di un server sovraccarico e qualche attimo
              // di tranquillità in più non guasta.
              // Tuttavia per semplificare il codice ripristiniamo il link qui.
              link.clicked = false;
            }

            // se invece il tempo è inferiore al timeout
            else
              // si richiama questa stessa funzione, con un tempo
              // che non dovrà essere ne alto ne troppo basso.
              setTimeout(verificaTempoTrascorso, 100);
          };

          // definita la funzione non resta che avviarla
          verificaTempoTrascorso();
        };
      };
      ajax.send(null);
    };
  };
  return usaLink;
};









