// callChain contains a sequence of statements that need to be
// evaluated in order. Processing starts by calling the
// function runNextChain();
var callChain = new Array();

// Add a command to the chain
addCallChain = function(call) {
    callChain.push(call);
}

// Take the next scheduled command if any
runNextChain = function() {
    if (callChain.length==0) {
        return;
    }
    call = callChain.shift();
    debug('calling: ' + call);
    //try {
        eval(call);
    //} catch(err) {
    //    alert('A JavaScript error occured executing: ' + call + '\n\n' + err.description);
    //}
}

createRequestObject = function() {
    var request;

    if(window.XMLHttpRequest) { 
        request = new XMLHttpRequest(); 
    } else if(window.ActiveXObject) { 
        var ie_versions = ["MSXML2.XMLHttp.5.0", "MSXML2.XMLHttp.4.0", 
        "MSXML2.XMLHttp.3.0", "MSXML2.XMLHttp",
        "Microsoft.XMLHttp"];
        for(var i=0; i <ie_versions.length; i++) {
            try {
                request = new ActiveXObject(ie_versions[i]);
            } catch (error) {}
        }
    }
    return request;
} 

// Target is where the response from the server should be stored.
// It can be either the name of an object id, or a global variable.
// For a variable, prefix the name with "var:".
// target = 'name_of_id'; target = 'var:target';
var target = "";

xmlHttpPost = function(strURL,strSubmit,target) {
    var xmlHttpReq = false;
    var self = this;
    debug('xmlHttpPost: ' + strURL + '?' + strSubmit);
    
    self.xmlHttpReq = createRequestObject();
    this.target = target;
    
    self.xmlHttpReq.open('POST', strURL, true);

    self.xmlHttpReq.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded; charset=UTF-8');
    self.xmlHttpReq.onreadystatechange = function() {
        if (self.xmlHttpReq.readyState == 4) { // Done
            updatePage(self.xmlHttpReq.responseText, target);
        }
    }
    self.xmlHttpReq.send(strSubmit);
}

xmlHttpGet = function(strURL,strSubmit,target) {
    var xmlHttpReq = false;
    var self = this;
    debug('xmlHttpGet: ' + strURL + '?' + strSubmit);

    self.xmlHttpReq = createRequestObject();
    this.target = target;
    self.xmlHttpReq.open('GET', strURL, true);

    self.xmlHttpReq.onreadystatechange = function() {
        if (self.xmlHttpReq.readyState == 4) { // Done
            updatePage(self.xmlHttpReq.responseText, target);
        }
    }
    self.xmlHttpReq.send(strSubmit);
}

updatePage = function(str,target){
    if(target.substring(0,4)=='var:') {
        str = target.substring(4) + "='" + 
        str.replace(/^\s+/,'').replace(/\s+$/,'') + "'";
        eval(str);
    } else if(target.substring(0,5)=='xvar:') {
        str = target.substring(5) + "=unescape('" + 
        escape(str.replace(/^\s+/,'').replace(/\s+$/,'')) + "')";
        eval(str);
    } else {
        document.getElementById(target).innerHTML = str;
    }

    // call next in chain
    runNextChain();
}

// This function only operates when an element with id 'ajaxDebug' is present
debug = function(msg) {
    obj = document.getElementById('ajaxDebug');
    if (obj) obj.innerHTML += msg + "<br>";
}

// Show/hide AJAX activity animation
showAjaxLoader = function(status) { 
    try {
        if (status) {
            document.getElementById('ajaxloader').style.display='';  
        } else {
            document.getElementById('ajaxloader').style.display='none';  
        }
    } catch(e) {}
    runNextChain();
}

sendAjaxForm = function(frm_id) {
    var frm = document.getElementById(frm_id);
    var sQuery = '';
    for(i=0; i<frm.elements.length; i++) {
        var name = frm.elements[i].name;
        var value = frm.elements[i].value; // .replace(/'/gi, "\\'")
        if (frm.elements[i].disabled ||
        name == '' || name.toLowerCase().substr(0,3) == 'ro_' || 
        name.substr(0,4) == 'ajax' ||
        (frm.elements[i].type == 'checkbox' && 
        frm.elements[i].checked == false) ||
        (frm.elements[i].type == 'radio' && 
        frm.elements[i].checked == false)) {
            /*
            if (value=='') value = 'empty';
            value = '(' + value + ')';
            */
            continue;
        }
        if (sQuery!='') sQuery += '&';
        sQuery += name + '=' + Url.encode(value);
    }
    var target = frm.elements['ajaxTarget'].value;
    
    if (target!=null && target!='') {
        if (!(target.substring(0,4)=='var:' || target.substring(0,5)=='xvar:')) {
            addCallChain("document.getElementById('" + target + "').className='ajaxLoading';runNextChain();");
        }
    }
    
    sQuery = sQuery.replace(/\+/g,"%2B");
    
    addCallChain("xmlHttpPost('" + frm.elements["ajaxSource"].value + 
        "','" + sQuery + "','" + frm.elements["ajaxTarget"].value + "')");

    if (frm.elements['rows']) addCallChain(
        "obj=document.getElementById('"+frm_id+"_RowCount');" +
        "if(obj)document.getElementById('"+frm_id+"').elements['rows'].value=obj.value;" +
        "runNextChain();"
    );
    
    if (target!=null && target!='') {
        if (!(target.substring(0,4)=='var:' || target.substring(0,5)=='xvar:')) {
            addCallChain("document.getElementById('" + target + "').className='';runNextChain();");
        }
        try {
            fnAfterUpdate = eval(target+"_AfterUpdate");
            if (fnAfterUpdate) {
                addCallChain(target+"_AfterUpdate('" + frm_id + "');runNextChain();");
            }
        } catch(e) {}
    }
    
    runNextChain();
    
    return false;
}

/**
*
* URL encode / decode
* http://www.webtoolkit.info/
*
**/
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) {
                string += String.fromCharCode(c);
                i++;
            }
            else if((c > 191) && (c < 224)) {
                c2 = utftext.charCodeAt(i+1);
                string += String.fromCharCode(((c & 31) << 6) | (c2 & 63));
                i += 2;
            }
            else {
                c2 = utftext.charCodeAt(i+1);
                c3 = utftext.charCodeAt(i+2);
                string += String.fromCharCode(((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63));
                i += 3;
            }
        }
        return string;
    }
}