var browser = 0;

if (navigator.appName.indexOf("Netscape") != -1)
    browser = 0;
if (navigator.appName.indexOf("Explorer") != -1)
    browser = 1;
else
    browser = 0;

var remXHRs = new Array();

function rememberXHR(xhr)
{
    xhr.setUniqueId(remXHRs.length);
    
    remXHRs[xhr.unique_id] = xhr;
}

function getRememberedXHR(onReadyStateChanged)
{
    for (var i = 0; i < remXHRs.length; i++)
    {
        if (remXHRs[i].onReadyStateChanged == onReadyStateChanged)
            return(remXHRs[i]);
    }
    
    return(null);
}

function forgetXHR(xhr)
{
    if ((xhr.unique_id != null) && (xhr.unique_id < remXHRs.length))
        remXHRs[xhr.unique_id] = null;
}

function XHR()
{
    this.req = null;
    this.xml_requested = true;
    this.callback_func = null;
    this.unique_id = null;
    
    this.getUniqueId = function() { return(this.unique_id); }
    this.setUniqueId = function(newUniqueId)
    {
        this.unique_id = newUniqueId;
        if (this.req != null)
            this.req.unique_id = this.unique_id;
    }
    
    this.onReadyStateChanged = function()
    {
        if (navigator.userAgent.indexOf('MSIE') >= 0)
            this_ = remXHRs[remXHRs.length - 1];
        else
            this_ = getRememberedXHR(this);
        
        switch (this_.req.readyState)
        {
            case (0): // uninitialized
            {
                break;
            }
            case (1): // loading
            {
                break;
            }
            case (2): // loaded
            {
                break;
            }
            case (3): // interactive
            {
                if (! this_.xml_requested)
                    this_.callback_func(this_.req.responseText, this_);
                break;
            }
            case (4): // complete
            {
                if ((this_.xml_requested) && (this_.req.responseXML != null))
                    this_.callback_func(new DomDocument(this_.req.responseXML), this_);
                
                this_.req = null;
                
                break;
            }
        }
    }
    
    this.onError = function()
    {
        this_ = getRememberedXHR(this);
        
        alert('ERROR: ' + this_.req.statusText);
        
        this_.req = null;
    }
    
    this.getNewXHR = function()
    {
        if (browser == 1) // Explorer
            this.req = new ActiveXObject("Microsoft.XMLHTTP");
        else
            this.req = new XMLHttpRequest();
        
        //this.req.unique_id = this.unique_id;
        
        return(this.req);
    }
    
    this.getNewAsync = function(callback_func)
    {
        this.getNewXHR();
        
        if ((callback_func != undefined) && (callback_func != null))
        {
            this.callback_func = callback_func;
            this.req.onreadystatechange = this.onReadyStateChanged;
        }
        
        if (browser != 1) // !Explorer
            this.req.onerror = this.onError;
        
        return(this.req);
    }

    this.loadXML = function(url, callback_func, xml, meth)
    {
        if ((meth == undefined) || (meth == null))
        {
            if (xml == null)
                var meth = 'GET';
            else
                var meth = 'POST';
        }
        
        if ((callback_func != undefined) && (callback_func != null))
            this.getNewAsync(callback_func).open(meth, url, true);
        else
            this.getNewXHR().open(meth, url, false);
        
        this.req.setRequestHeader("Cache-Control", "no-cache");
        
        if (xml == null)
        {
            if (browser == 1) // Explorer
                this.req.send();
            else
                this.req.send(null);
        }
        else
            this.req.send(xml);
        
        if (callback_func == undefined)
        {
            if (this.xml_requested)
                var rXML = this.req.responseXML;
            else
                var rXML = this.req.responseText;
            
            this.req = null;
            
            return(rXML);
        }
    }

    this.loadURL = function(url, callback_func, xml)
    {
        this.xml_requested = false;
        return(this.loadXML(url, callback_func, xml));
    }

    this.sendXML = function(url, xml, async)
    {
        if (async == null)
            async = true;
        
        var meth = 'POST';
        
        if (async)
            this.getNewAsync(this, null).open(meth, url, true);
        else
            this.getNewXHR(this).open(meth, url, false);
        
        this.req.send(xml);
    }
    
    this.stopAsyncXMLLoading = function()
    {
        this.req.abort();
    }
    
    rememberXHR(this);
}

