XHR = XHRequest.prototype;
function XHRequest(cbf,pcbf) {
    this.callback = cbf;
    this.postCallback = pcbf;
    this.cookies = null;
    this.init();
}
XHR.init = function() {
    var request = null;
    this.xhr = this.getObject();
    if(!this.xhr)
        return;
    request = this;

    this.xhr.onreadystatechange = function() {
        var obj = request.getObject();
        if(obj.readyState == 4) {
            if((obj.status == 200) || (obj.status == 304) || (obj.status == 403))
                request.oncomplete(obj.responseText, obj.responseXML);
            else 
                request.onerror(obj.status, obj.statusText);
            request.cleanup();
        }
    };
};
XHR.getObject = function() {
    if(this.xhr) {
        return this.xhr;
    } else if(window.XMLHttpRequest) {
        return new XMLHttpRequest();
    } else if (window.ActiveXObject) {
        this.getCookies();
        try {
            return new ActiveXObject("Msxml2.XMLHTTP");
        } catch (e) {
            try {
                return new ActiveXObject("Microsoft.XMLHTTP");
            } catch (e) {
                alert("Your browser must support XMLHttp in order to use this site.");
            }
        }
    } else { 
        return null;
    }
};
XHR.finalize = function() {
    if(!this.xhr)
        return;
    this.cleanup();
};
XHR.connect = function(method, url, params, async) {
    if(!this.xhr)
        return null;
    if(!async)
        async = false;
    var data = null;
    if(method == "POST") {
        this.xhr.open(method, url, async);
        data = params;
    } else if(method == "GET") {
        this.xhr.open(method, url + "?" + params, async);
    }
    if(this.cookies != null) {
        for(var i=0; i<this.cookies.length; i++) {
            this.xhr.setRequestHeader("Set-Cookie", this.cookies[i]);
        }
    }
    if(method == "POST") {
        this.xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
        this.xhr.setRequestHeader("Content-length", data.length);
        this.xhr.setRequestHeader("Connection", "close");
    }
    this.xhr.send(data);
};
XHR.abort = function() {
    if(this.xhr)
        this.xhr.abort();
    this.cleanup();
};
XHR.cleanup = function() {
    if(!this.xhr)
        return;
    delete this.callback;
    delete this.postCallback;
    delete this.cookies;
    delete this.xhr.onreadystatechange;
    this.xhr = null;
};
XHR.oncomplete = function(responseText, responseXML) {
    if(this.callback(responseText, responseXML) && (this.postCallback != null))
        this.postCallback();
};
XHR.onerror = function(status,statusText) {
    alert("XMLHttp Request error: " +  status + " " + statusText);
};
XHR.getCookies = function() {
    this.cookies = new Array();
    var jar = document.cookie.split(';');
    for(var i=0; i<jar.length; i++) {
        this.cookies[i] = jar[i];
    }
}
function post(url, params, callback, postCallback) {
    doRequest("POST", url, params, callback, postCallback);
}
function get(url, params, callback, postCallback) {
    doRequest("GET", url, params, callback, postCallback);
}
function doRequest(method, url, params, callback, postCallback) {
    var req = new XHRequest(callback, postCallback);
    req.connect(method, url, params, true);
}
