﻿var net = new Object();
net.READY_STATE_UNINITIALIZED = 0;
net.READY_STATE_LOADING = 1;
net.READY_STATE_LOADED = 2;
net.READY_STATE_INTERACTIVE = 3;
net.READY_STATE_COMPLETE = 4;

//Questa classe viene istanziata prendendo due parametri in input:
//il callback per gestire il ritorno delle operazioni terminate correttamente, ed
//il callback per gestire quelle che generano un errore.
net.XMLHTTPRequestWrapper = function(onload, onerror) {
    this.req = null;
    this.onload = (onload) ? onload : this.defaultLoad;
    this.onerror = (onerror) ? onerror : this.defaultError;
}

//L'unico metodo che viene esposto è loadData che accetta i parametri relativi ad una richiesta come:
//l'indirizzo della pagina da richiamare, il metodo, i parametri (in caso di POST) ed il ContentType.
net.XMLHTTPRequestWrapper.prototype.loadData = function(url, method, params, contentType) {
    if (!method) {
        method = "GET";
    }
    if (!contentType && method == "POST") {
        contentType = 'application/x-www-form-urlencoded';
    }
    if (window.XMLHttpRequest) {
        this.req = new XMLHttpRequest();
    } else if (window.ActiveXObject) {
        this.req = new ActiveXObject("Microsoft.XMLHTTP");
    }
    if (this.req) {
        try {
            var loader = this;
            this.req.onreadystatechange = function() {
                net.XMLHTTPRequestWrapper.onReadyState.call(loader);
            }
            this.req.open(method, url, true);
            if (contentType) {
                this.req.setRequestHeader('Content-Type', contentType);
            }
            this.req.send(params);
        }
        catch (err) {
            this.onerror.call(this);
        }
    }
}

net.XMLHTTPRequestWrapper.onReadyState = function() {
    var req = this.req;
    if (req.readyState == net.READY_STATE_COMPLETE) {
        if (req.status == 200 || req.status == 0) {
            this.onload.call(this);
        }
        else {
            this.onerror.call(this);
        }
    }
}

net.XMLHTTPRequestWrapper.prototype.defaultError = function() {
    alert("error fetching data!"
			+ "\n\nreadyState:" + this.req.readyState
			+ "\nstatus: " + this.req.status
			+ "\nheaders: " + this.req.getAllResponseHeaders());
}

net.XMLHTTPRequestWrapper.prototype.defaultLoad = function() {
    alert("Server Procedure Correctly Executed!"
			+ "\n\nresponseText:" + this.req.responseText
			+ "\nresponseXML: " + this.req.responseXML);
}

//-----------------------------------------------------------------------------
//GESTIONE RICHIESTE
//-----------------------------------------------------------------------------
var action_type = '';

//Funzione per il recupero di una form:
function sendingForm(formname, page, id, args) {
    //Costruisce la variabile che include i valori del form:
    var params_post = "";

    //Recupera il form con il nome:
    var form = document.forms[formname];

    //Funzione che genera la coppia chiave/valore dei controlli nel form:
    function GetElemValue(name, value) {
        params_post += (params_post.length > 0 ? "&" : "") + escape(name).replace(/\+/g, "%2B") + "=" + escape(value ? value : "").replace(/\+/g, "%2B");
        //+ escape(value ? value : "").replace(/\n/g, "%0D");
    }

    //Itera tra gli elementi della form per estrarre la giusta coppia chiave-valore:
    var elemArray = form.elements;
    for (var i = 0; i < elemArray.length; i++) {
        var element = elemArray[i];
        var elemType = element.type.toUpperCase();
        var elemName = element.name;
        if (elemName) {
            if (elemType == "TEXT" || elemType == "TEXTAREA" || elemType == "PASSWORD" || elemType == "BUTTON" || elemType == "RESET" || elemType == "SUBMIT" || elemType == "FILE" || elemType == "IMAGE" || elemType == "HIDDEN")
                GetElemValue(elemName, element.value);
            else if (elemType == "CHECKBOX" && element.checked)
                GetElemValue(elemName, element.value ? element.value : "On");
            else if (elemType == "RADIO" && element.checked)
                GetElemValue(elemName, element.value);
            else if (elemType.indexOf("SELECT") != -1)
                for (var j = 0; j < element.options.length; j++) {
                var option = element.options[j];
                if (option.selected)
                    GetElemValue(elemName, option.value ? option.value : option.text);
            }
        }
    }

    //Aggiunge agli argomenti sempre il nome della form:
    //if (args.length > 0) {args = "&" + args}
    //args = "formname=" + formname + args

    sendingRequest(page, id, args, 'post', params_post);
}

//Funzione per l'invio dell'oggetto XMLHttpRequest di una richiesta asincrona:
function sendingRequest(page, id, args, method_post, params_post) {
    //Memorizza 'HOME' o 'NAVIGATE'
    action_type = id;

    //Inizializza i parametri opzionali:
    if (args === undefined) args = '';
    if (method_post === undefined) method_post = 'get';
    if (params_post === undefined) params_post = '';

    //aggiunge un argomento di refresh alla pagina, sempre differente
    //così da forzare il ri-caricamento dell'html:
    //P.S.: mettere nell'header la dicitura sotto può aiutare:
    //<meta http-equiv="Cache-Control" content="no-cache" /> 
    if (args != '') { args += '&' };
    args += 'httpmethod=' + method_post;
    //aggiunge l'elemento che forza il reload della pagina:
    var args_refresh = "pag" + new Date().getTime();
    args += '&refresh=' + args_refresh;
    
    //Costruisce la QueryString:
    var qryStr = '';
    qryStr = '?&ajax=true&id=' + id;
    //Aggiunge eventuali argomenti aggiuntivi:
    //Pressuppone che args sia strutturato internamente con la separazione dei parametri '&', il nome e '=' il valore.
    if (args != '') qryStr = qryStr + '&' + args;

    if (method_post == 'post') {
        //Richiama loadData in modalità 'post':
        new net.XMLHTTPRequestWrapper(receivedData).loadData(page + qryStr, "POST", params_post);
    } else {
        //Richiama loadData in modalità 'get':
        if (action_type == 'HOME' || action_type == 'NAVIGATE') {
            window.location.hash = args_refresh;
        }
        new net.XMLHTTPRequestWrapper(receivedData).loadData(page + qryStr);
    }
}
//-----------------------------------------------------------------------------
//GESTIONE RISPOSTE
//-----------------------------------------------------------------------------
//Funzioni per la gestione della risposta:
//Conta il numero degli array:
Array.prototype.count = function() {
    return this.length;
}
//Funzione di ricezione della risposta dal server:
//(La validazione della risposta viene gestita all'interno di wrapper.js)
function receivedData() {

    var strResponse = this.req.responseText;

    if (strResponse == undefined) {
        //crea un delay per attendere una risposta:
        var numWhile = 0;
        while (!strResponse) {
            setTimeout(function() { receivedDataWait(); }, 500);
            strResponse = this.req.responseText;
            numWhile += 1;
            if (numWile > 3) {
                strResponse = "TIME OUT!";
            }
        }
    }

    if (strResponse != "TIME OUT!") {
        //crea un array con il contenuto della risposta:
        var update = new Array();
        update = strResponse.split('|');
        //Istanzia le variabili che servono a rappresentare il nome e il contenuto:
        var id = '';
        var contentHTML = '';

        if (update.count() >= 1) {
            //Visualizza il caricamento degli ID:
            for (i = 0; i < update.count(); i = i + 2) {
                id = update[i];
                contentHTML = update[i + 1];
                try {
                    if (id == "redirect") {
                        //E' stato passato un URL di redirect:
                        window.location.href = contentHTML;
                    } else {
                        document.getElementById(id).innerHTML = contentHTML;
                    }
                  
                } catch (e) {
                  if (id != "") {
                     alert(e.message + " (id = '" + id + "')");
                  }// else { Nessun div da riempire...}
                }
            }
        }
        //****************************************************************************
        //============================================================================
        //Richiama la routine 'esterna' che identifica la conclusione della richiesta:
        Sending_End(action_type);
        //============================================================================
        //****************************************************************************
    }
}

