
//////////////////////////////////////////////////////////////////////
//
// AJAX Infrastructure
//
//////////////////////////////////////////////////////////////////////

//----------------------------------------------------------------------
// XmlHttpRequest Constants 
//----------------------------------------------------------------------
var READYSTATE_UNINITIALIZED = 0;
var READYSTATE_LOADING       = 1;
var READYSTATE_LOADED        = 2;
var READYSTATE_INTERACTIVE   = 3;
var READYSTATE_COMPLETE      = 4;

var HTTP_STATUS_ABORTED  =   0;
var HTTP_STATUS_OK       = 200;
var HTTP_STATUS_NOTFOUND = 404;

var XMLHttpRequest, ActiveXObject;
if (typeof XMLHttpRequest === "undefined" && ActiveXObject) {
    XMLHttpRequest = function() {
        try { return new ActiveXObject("Msxml2.XMLHTTP.6.0"); }
        catch (e1) { }
        try { return new ActiveXObject("Msxml2.XMLHTTP.3.0"); }
        catch (e2) { }
        try { return new ActiveXObject("Msxml2.XMLHTTP"); }
        catch (e3) { }
        throw new Error("This browser does not support XMLHttpRequest.");
    };
}


// Not as secure as http://json.org/json2.js
if (!this.JSON) {
    this.JSON = {};
}
if (typeof this.JSON.parse !== 'function') {
    /*jslint evil: true */
    this.JSON.parse = function(json) { return eval('(' + json + ')'); };
    /*jslint evil: false */
}

//----------------------------------------------------------------------
// Object Constructor for async request wrapper
//----------------------------------------------------------------------
function AsyncHttpRequest() 
//----------------------------------------------------------------------
{
    this.xhr = new XMLHttpRequest();    
    
    this.headers = {};

    this.setRequestHeader = function( header, value ) {
        this.headers[header] = value;
    };

    this.invoke = function(url, callback, errorCallback) {
        var xhr = this.xhr; // For referencing within closures

        if (typeof xhr.abort !== 'undefined') { xhr.abort(); }

        xhr.open("GET", url, true);
        for (var header in this.headers) {
            if (this.headers.hasOwnProperty(header)) {
                xhr.setRequestHeader(header, this.headers[header]);
            }
        }

        xhr.onreadystatechange = function() {
            if (xhr.readyState !== READYSTATE_COMPLETE) {
                return;
            }
            else if (xhr.status === HTTP_STATUS_ABORTED) {
                return;
            }
            else if (callback && 200 <= xhr.status && xhr.status <= 299) {
                var parsedData = null;
                if (xhr.getResponseHeader('content-type') === 'application/json') {
                    try {
                        parsedData = JSON.parse(xhr.responseText);
                    }
                    catch (e) {
                    }
                }
                callback(xhr, parsedData);
            }
            else if (errorCallback && 400 <= xhr.status) {
                errorCallback(xhr);
            }
        };


        this.xhr.send(null);
    };

    this.cancel = function()
    {
        this.xhr.abort();
    };
    
} // AsyncHttpRequest

