/**
 * Gestione personalizzata delle richieste asincrone tramite XMLHttp.
 * 
 * @param url l'indirizzo da chiamare
 */
function AjaxRequest(url) {

    /** Numero massimo di volte per uno stesso hander puo' essere invocato consecutivamente */
    this.MAX_HANDLER_RETRIG = 10000 ;

    //compatibilita' IE5/6
    if(!window.XMLHttpRequest)
        window.XMLHttpRequest = function() { return new ActiveXObject('Microsoft.XMLHTTP') }
    
    this.url = url ;
    this.handlers = new Array() ;
    this.xmlhttp = new XMLHttpRequest() ;
    this.handlerIndex = 0 ;
    this.retrig = 0 ;
    this.multisending = false ;
    this.multiaborting = false ;
 
}

/**
 * Aggiunge un handler alla lista degli handler. 
 * 
 * Agli handler verra' passato come primo parametro l'oggetto corrente
 * 
 * @param handler l'handler da utilizzare in risposta all'url chiamato
 */
AjaxRequest.prototype.addHandler = function(handler) {
    this.handlers.push(handler) ;
}

/**
 * Richiesta singola
 * 
 * @param url l'indirizzo da invocare
 * @param handler l'handler da utilizzare per la gestione della risposta
 */
AjaxRequest.prototype.send = function(url,handler) {
    var instance = this ;
    var ajax = this.xmlhttp ;
    if(!handler && this.handlers.length)
        handler = this.handlers[0] ;
    ajax.open("POST", url, true) ;
    ajax.setRequestHeader("Content-Type", "plain/text; charset=utf-8") ;
    ajax.setRequestHeader("Accept-Charset", "utf-8") ;
    ajax.onreadystatechange = function() {
        if(handler) {
            if(ajax.readyState==4) {
                window.status = "" ;
                handler(instance) ;
            } else
                window.status = "Async: "+ajax.readyState+"/4" ;
        } else
            alert("Nessun handler AJAX definito") ;
    }
    ajax.send(null) ;
}

/**
 * Richiesta multipla. Gli handler vengono invocati in sequenza (ricorsione asincrona).
 * 
 * All'uscita di un handler si possono verificare 2 situazioni:
 * 1. si invoca un'altro URL (anche lo stesso?) con lo stesso handler (return true)
 * 2. non si invoca nessun URL e si passa all'handler successivo (return false)
 */
AjaxRequest.prototype.multisend = function() {
    
    var instance = this ;
    var ajax = this.xmlhttp ;
    
    //if(confirm("MULTISEND "+this.handlerIndex+"/"+this.handlers.length+" ("+this.retrig+")")) {
        
        //this.currentHandler = handlerIndex ;
    
        //Questa situazione si verifica solo con un'invocazione interna! o con un invocazione
        //esterna in stato di riposo (multisending=false)
        if(this.handlerIndex || this.retrig || !this.multisending) {

            this.multisending = true ;

            ajax.open("POST", this.url, true) ;
            ajax.setRequestHeader("Content-Type", "plain/text; charset=utf-8") ;
            ajax.setRequestHeader("Accept-Charset", "utf-8") ;
            ajax.onreadystatechange = function() {

                if(instance.handlers.length) {

                    if(ajax.readyState==4) {

                        while(instance.handlerIndex<instance.handlers.length) {
                            var retval = instance.handlers[instance.handlerIndex](instance) ;
                            if(!retval) {
                                instance.handlerIndex++ ;
                                instance.retrig = 0 ;
                            } else {
                                instance.retrig++ ;
                                break ;
                            }
                        }

                        if(this.retrig>instance.MAX_HANDLER_RETRIG) {

                            alert("Troppe ricorsioni AJAX") ;
                            instance.multisending = false ;

                        } else {

                            if(!instance.multiaborting && instance.handlerIndex<instance.handlers.length && ajax.status==200) {

                                //ricorsione
                                instance.multisend() ;

                            } else {

                                //alert("FINE RICHIESTA MULTIPLA") ;
                                instance.resetMultisend() ;
                                
                            }

                        }

                    } else
                        window.status = "Async: "+ajax.readyState+"/4" ;

                } else
                    alert("Nessun handler AJAX definito") ;

            }
            ajax.send(null) ;

        } else {
        
            alert("Richesta AJAX in corso...") ;
        
        }
        
//    } else {
//        
//        this.resetMultisend() ;
//        
//    }
    
}

AjaxRequest.prototype.changeURL = function(url) {
    this.url = url ;
}

AjaxRequest.prototype.multiabort = function() {
    this.multiaborting = true ;
}

AjaxRequest.prototype.getStatus = function() {
    return this.xmlhttp.status ;
}

AjaxRequest.prototype.getResponseXML = function() {
    return this.xmlhttp.responseXML ;
}

AjaxRequest.prototype.resetMultisend = function() {
    this.multisending = false ;
    this.multiaborting = false ;
    this.handlerIndex = 0 ;
    this.retrig = 0 ;
}

