var aAjaxReqs = new Array(); // array of request objects
var singleXmlHttp = false;

function AjaxReq() {
    this.inUse = false;
    this.xmlHttp = false; 
    try { // Create a boolean variable to check for a valid Microsoft Active-X instance
        this.xmlHttp = new ActiveXObject("Msxml2.XMLHTTP"); // If the javascript version is greater than 5
    } catch (e) {
        try { // If not, then try the older IE Active-X object
            this.xmlHttp = new ActiveXObject("Microsoft.XMLHTTP"); 
        } catch (E) {
            this.xmlHttp = false; // Else we must be using a non-IE browser
        }
    }
    if (!this.xmlHttp && typeof XMLHttpRequest != 'undefined') { // If not IE, create a Javascript xmlhttp obj
        this.xmlHttp = new XMLHttpRequest();}
}

// Main Function to process an AJAX request
function processAjax(flagMultiRequest, getOrPost, serverPage, queryString, nodeNameForGraphic, responseTextHandlerFunction) {
    if (typeof flagMultiRequest            == 'undefined') {flagMultiRequest = true;}
    if (typeof responseTextHandlerFunction == 'undefined') {responseTextHandlerFunction = ajaxDefaultResponseTextHandler;}

    var index;
    var activeXmlHttp;
    if (flagMultiRequest) {
        index = -1;
        for (var i=0; i<aAjaxReqs.length; i++) { 
            if (aAjaxReqs[i].inUse == false) { 
                index = i; break;} 
        }
        if (index == -1) {
            index = aAjaxReqs.length;
            aAjaxReqs[index] = new AjaxReq();
        }
        activeXmlHttp = aAjaxReqs[index];
    } else {
        if (!singleXmlHttp) {
            singleXmlHttp = new AjaxReq();
        }
        //if (singleXmlHttp.inUse) {  // do not abort - causes bug in FF
        //    singleXmlHttp.onreadystatechange = function () {}
        //    singleXmlHttp.abort();
        //}
        activeXmlHttp = singleXmlHttp;
        index = -1;
    }

    activeXmlHttp.inUse = true;
    activeXmlHttp.nodeNameForGraphic = nodeNameForGraphic;
    activeXmlHttp.responseTextHandler = responseTextHandlerFunction;
    showAjaxGraphic(nodeNameForGraphic, true);

    if (getOrPost == 'get') {
        if (activeXmlHttp.xmlHttp) {
            activeXmlHttp.xmlHttp.open('GET', serverPage + '?' + queryString);
            activeXmlHttp.xmlHttp.onreadystatechange = function () {ajaxOnReadyStateChangedHandler(index);}
            activeXmlHttp.xmlHttp.send(null);
            //if (window.XMLHttpRequest) { 
            //    activeXmlHttp.xmlHttp.send(null); } 
            //else if (window.ActiveXObject) { 
            //    activeXmlHttp.xmlHttp.send(); } 
        } else { // no ajax with this browser->use script object.  Can only do a GET
            activeXmlHttp.inUse = false;
            var newScript = document.createElement('script');
            newScript.src = serverPage + '?no_ajax=1&img_ajax=' + (nodeNameForGraphic ? nodeNameForGraphic : '') + '&' + queryString;
            newScript.type = "text/javascript";
            document.body.appendChild(newScript); // execute script
        }
    } else {
        if (activeXmlHttp.xmlHttp) {
            activeXmlHttp.xmlHttp.open('POST', serverPage, true);
            activeXmlHttp.xmlHttp.setRequestHeader("Content-Type","application/x-www-form-urlencoded; charset=UTF-8");
            activeXmlHttp.xmlHttp.onreadystatechange = function () {ajaxOnReadyStateChangedHandler(index);}
            activeXmlHttp.xmlHttp.send(queryString);
        }
    }
    return;
}
function showAjaxGraphic(nodeNameForGraphic, show) {
    if (typeof show == 'undefined') show = false;
    if (nodeNameForGraphic && document.getElementById(nodeNameForGraphic)) {
        var img = document.getElementById(nodeNameForGraphic);
        img.style.visibility = (show ? 'visible' : 'hidden');
    }
}

function ajaxOnReadyStateChangedHandler(index) {
    if (index == -1) {
        activeXmlHttp = singleXmlHttp;
    } else {
        activeXmlHttp = aAjaxReqs[index];
    }
    if (activeXmlHttp.xmlHttp.readyState == 4) {
        if (activeXmlHttp.xmlHttp.status == 200) {
            activeXmlHttp.responseTextHandler(activeXmlHttp.xmlHttp.responseText);
            if (index == -1) { // for single req hide here because overridden requests will drop through with a status of zero
                showAjaxGraphic(activeXmlHttp.nodeNameForGraphic, false);
            }
        }
        if (index != -1) {
            showAjaxGraphic(activeXmlHttp.nodeNameForGraphic, false);
        }
        activeXmlHttp.inUse = false;
    }
}

function ajaxDefaultResponseTextHandler(responseText) {
    // responseText: requires JSON obj with properties like: elemName: obj{elemPropName: propValue}
    if (responseText.length > 0) {
        var response = eval('(' + responseText + ')');
        for (var elem in response) {
            for (var prop in response[elem]) {
                elementName = elem.toString();
                if (elementName == 'js_variable') {
                    window[prop] = response[elem][prop];
                } else {
                    targetNode = document.getElementById(elementName);
                                ///// This is an alternate solution to the bug in IE setting innerHTML of <SELECT> elements
                                //if ( browserIsIE() && targetNode.nodeName.toLowerCase() == 'select' && prop=='innerHTML' ) {
                                //    response[elem][prop] = '<option>truncatethis</option>' + response[elem][prop];
                                //} 
                                //targetNode[prop] = response[elem][prop];
                                //if ( browserIsIE() && targetNode.nodeName.toLowerCase() == 'select' && prop=='innerHTML' ) { 
                                //    targetNode.outerHTML = targetNode.outerHTML;
                                //} 
                    if ( (navigator.userAgent.indexOf("MSIE") != -1) && targetNode.nodeName.toLowerCase() == 'select' && prop=='innerHTML' ) {
                        select_innerHTML(targetNode, response[elem][prop]);
                    } else if (prop=='appendHTML') {
                        targetNode['innerHTML'] += response[elem][prop];
                    } else if (prop.substr(0,6)=='style.') {
                        targetNode['style'][prop.substr(6)] = response[elem][prop];
                    } else {
                        targetNode[prop] = response[elem][prop];
                    }
                }
            }
        }
    }
}
function select_innerHTML(objeto,innerHTML){  // for bug in IE setting innerHTML of <SELECT> elements
    /******
    * select_innerHTML - corrige o bug do InnerHTML em selects no IE
    * Veja o problema em: http://support.microsoft.com/default.aspx?scid=kb;en-us;276228
    * Versão: 2.1 - 04/09/2007
    * Autor: Micox - Náiron José C. Guimarães - micoxjcg@yahoo.com.br
    * @objeto(tipo HTMLobject): o select a ser alterado
    * @innerHTML(tipo string): o novo valor do innerHTML
    *******/
    objeto.innerHTML = ""
    var selTemp = document.createElement("micoxselect")
    var opt;
    selTemp.id="micoxselect1"
    document.body.appendChild(selTemp)
    selTemp = document.getElementById("micoxselect1")
    selTemp.style.display="none"
    if(innerHTML.toLowerCase().indexOf("<option")<0){//se não é option eu converto
        innerHTML = "<option>" + innerHTML + "</option>"
    }
    innerHTML = innerHTML.toLowerCase().replace(/<option/g,"<span").replace(/<\/option/g,"</span")
    selTemp.innerHTML = innerHTML
      
    
    for(var i=0;i<selTemp.childNodes.length;i++){
        var spantemp = selTemp.childNodes[i];
  
        if(spantemp.tagName){     
            opt = document.createElement("OPTION")
    
            if(document.all){ //IE
                objeto.add(opt)
            }else{
                objeto.appendChild(opt)
            }       
    
            //getting attributes
            for(var j=0; j<spantemp.attributes.length ; j++){
                var attrName = spantemp.attributes[j].nodeName;
                var attrVal = spantemp.attributes[j].nodeValue;
                if(attrVal){
                    try{
                        opt.setAttribute(attrName,attrVal);
                        opt.setAttributeNode(spantemp.attributes[j].cloneNode(true));
                    }catch(e){}
                }
            }
            //getting styles
            if(spantemp.style){
                for(var y in spantemp.style){
                    try{opt.style[y] = spantemp.style[y];}catch(e){}
                }
            }
            //value and text
            opt.value = spantemp.getAttribute("value")
            opt.text = spantemp.innerHTML
            //IE
            opt.selected = spantemp.getAttribute('selected');
            opt.className = spantemp.className;
        }
    }    
    document.body.removeChild(selTemp)
    selTemp = null
}
function ajaxSerializeForm(formName) { 
    var frm = document.getElementById(formName);
    var els = frm.elements; 
    var len = els.length; 
    var queryString = "ajax_request=1"; 
    this.addField = function(name,value) { 
        if (queryString.length>0) { 
            queryString += "&"; } 
        queryString += encodeURIComponent(name) + "=" + encodeURIComponent(value); 
    }; 
    for (var i=0; i<len; i++) { 
        var el = els[i]; 
        if (!el.disabled) { 
            switch(el.type) { 
                case 'text': 
                case 'password': 
                case 'hidden': 
                case 'textarea': 
                    this.addField(el.name,el.value); break; 
                case 'select-one': 
                    if (el.selectedIndex>=0) { 
                        this.addField(el.name,el.options[el.selectedIndex].value); } 
                    break; 
                case 'select-multiple': 
                    for (var j=0; j<el.options.length; j++) { 
                        if (el.options[j].selected) { 
                            this.addField(el.name,el.options[j].value); } 
                    } 
                    break; 
                case 'checkbox': 
                case 'radio': 
                    if (el.checked) { 
                        this.addField(el.name,el.value); } 
                    break; 
            } 
        } 
    } 
    return queryString; 
}; 
