/**
 * HTTP request/response management
 *
 * Copyright: (c)2007 CK Web Technologies - http://www.ckweb.com.au/
 * Author:    Chris Knowles <chris.knowles@ckweb.com.au>
 * Version:   $Id: HTTP.js 34 2007-10-12 01:16:17Z Chris $
 */

if (!CKW) {
    var CKW = function(){};
}

CKW.XHRObject = function()
{
    var xhr, xhrType, xhrArg;

    try {
        xhr = new XMLHttpRequest();
        xhrType = XMLHttpRequest;
        
    } catch(e) {
        var msXhrs = [
            "MSXML2.XMLHTTP.3.0",
            "MSXML2.XMLHTTP",
            "Microsoft.XMLHTTP"
        ];
        for (var i = 0; i < msXhrs.length; i++) {
            try {
                xhr = new ActiveXObject(msXhrs[i]);
                xhrType = ActiveXObject;
                xhrArg = msXhrs[i];
                break;
                
            } catch (e) {
                alert("ERROR!\n\nAction Performed - trying to create an HTTP Request Object\n\nProblem - Your browser doesn't support HTTP Requests in Javascript\n\nSolution - contact the administrator of the site with the details of this problem and the browser type and version that you are using\n\nYour Browser Details - " + navigator.userAgent);
                return false;
            }
        }
    }
    return function()
    {
        return new xhrType(xhrArg);
    }
}();


CKW.HTTP = function()
{
    this.xhr = CKW.XHRObject();
    this.text = null;
    this.cancelled = null;
    this.cancellable = null;
    this.async = true;
    this.callback = null;
    this.callbackVars = null;

    var self = this;
    
    this.setAsync = function(val)
    {
        self.async = val;
    };
    
    this.get = function(url, vars, callback, callbackVars) {
        self.callback = callback;
        self.callbackVars = callbackVars;
        self.cancellable = true;
        if (vars) {
            url = url + '?' + vars;
        }
        self.xhr.open('GET', url, self.async);
        self.xhr.onreadystatechange = self.executeCallback;
        self.xhr.setRequestHeader('XHR', 'TRUE');
        self.xhr.send(null);
    };
    
    this.executeCallback = function()
    {
        if (self.cancellable && self.cancelled) {
            return;
        }
        if (self.ok()) {
            self.callback(self.callbackVars);
        }
    };

    this.post = function(url, vars, callback, callbackVars) {
        self.callback = callback;
        self.callbackVars = callbackVars;
        self.cancellable = false;
        self.xhr.abort();
    	self.xhr.open('POST', url, this.async);
        self.xhr.onreadystatechange = self.executeCallback;
        self.xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
        self.xhr.setRequestHeader('XHR', 'TRUE');
    	self.xhr.send(vars);
    };

    this.cancel = function() {
        self.cancelled = true;
    };

    this.ok = function()
    {   
        if (self.xhr.readyState == 4) {
            if(self.xhr.status == 200) {
                if (self.cancellable && self.cancelled) {
                    return false;
                }
                self.text = self.xhr.responseText;
                return true;
            }
        }
        return false;
    };

    this.postUpdate = function(elm, url, vars, callback)
    {
        var http = self;
        var update = function()
        {
            if (http.ok()) {
                CKW.DOM.setContent(elm, http.text);
                if (callback) {
                    callback();
                }
            }
        };
        self.post(url, vars, update);
    };

    this.getUpdate = function(elm, url, vars, callback)
    {
        var http = self;
        var update = function()
        {
            if (http.ok()) {
                CKW.DOM.setContent(elm, http.text);
                callback();
            }
        };
        self.get(url, vars, update);
    };
};

CKW.HTTP.udGetInstance = function()
{
    this.instance = null;
    if (this.instance == null) {
        this.instance = new CKW.HTTP.Updater(Math.PI);
    }
    return this.instance;
}

CKW.HTTP.Updater = function(check)
{
    if (check != Math.PI) {
        throw Error("Trying to instantiate new CKW.HTTP.Updater - this is not an allowable public action");
    }
    this.updates = new CKW.AssocArray;
    var self = this;
    
    this.post = function(elm, url, vars, callback)
    {
        var remove = this.remove(elm);
        var http = new CKW.HTTP;
        http.postUpdate(elm, url, vars, remove);
        this.updates.set(elm, http);
    };

    this.get = function(elm, url, vars, callback)
    {
        var remove = this.remove(elm);
        var http = new CKW.HTTP;
        http.getUpdate(elm, url, vars, remove);
        this.updates.set(elm, http);
    };

    this.remove = function(id)
    {
        var self  = this;
        return function()
        {
            self.updates.remove(id);
        };
    };
    
    this.cancel = function(id)
    {
        this.updates.vals[id].cancel();
    };
};

CKW.HTTP.updater = CKW.HTTP.udGetInstance();

var $H = CKW.HTTP;
var $UD = CKW.HTTP.updater;


/*
$H.post();


$H = function()
{

}

$H.prototype = 
{
    post: function()
    {
        var http = new CKW.HTTP;
        http.post();
    }
}

*/

