// === Async request and response routines ============

// XMLHttpRequest object, used for direct (non-object) creation
var     gReqObject;    

// Request method types
var HTTP_GET                = 'GET';
var HTTP_POST               = 'POST';

// Object states
var HTTP_STATE_COMPLETE     = 4;
    
// HTTP status codes
var HTTP_STATUS_OK          = 200;

/*
** Non-object-based methods
*/
    
function do_http_get(url, sync)
{
    return do_http_request(url, null, HTTP_GET, sync)
}

function do_http_post(url, params, sync, is_file_upload)
{
    return do_http_request(url, params, HTTP_POST, sync, is_file_upload)
}

function do_http_request(url, params, method, sync, is_file_upload)
{
    //alert('do_http_req!');

    if (!method)
        method = HTTP_GET;
    if (!sync)
        sync = false;
    if (!is_file_upload)
        is_file_upload = false;
    
    //
    // Need to handle case of params being array
    //
    
    // Non-IE browsers
    if (window.XMLHttpRequest)
    {
        gReqObject = new XMLHttpRequest();
    }
    // IE only
    else if (window.ActiveXObject)
    {
        gReqObject = new ActiveXObject('Microsoft.XMLHTTP');
    }
    
    if (!gReqObject)
        return false;
    
    // alert('here we go: ' + url);
    
    // Async calls use a callback
    if (!sync)
        gReqObject.onreadystatechange = on_req_state_change;
        
    gReqObject.open(method, url, !sync);

    // Let the server know it's a form
    if (method == HTTP_POST)
    {
        var form_type;
        
        // Normal form submission vs. file upload submissions -
        // need different form encodings.  Sigh.
        form_type = is_file_upload ? 'multipart/form-data'
                                   : 'application/x-www-form-urlencoded';
                                   
        gReqObject.setRequestHeader("Content-Type", form_type);
    }

    gReqObject.send(params);
    
    return true;
}

function on_req_state_change()
{
    /* ** meanings ??? ** */

    // states are
    //
    // 0:   uninitialized
    // 1:   loading
    // 2:   loaded
    // 3:   interactive
    // 4:   complete
    
    if (gReqObject.readyState != HTTP_STATE_COMPLETE)
        return;
        
    if (gReqObject.status != HTTP_STATUS_OK)
    {
//        dprintln('HTTP req status = ' + gReqObject.status + 
//                  ' -- ' + gReqObject.statusText);
        return;
    }
    
    // Got data, do the do
    // do_update_page(gReqObject.responseText);
}

/*
** Object-based methods
*/

//
// Keep track of multiple requests
//
var gHTTPRequests;

function _make_http_req()
{
    var req;
    
    // Non-IE browsers
    if (window.XMLHttpRequest)
    {
        req = new XMLHttpRequest();
    }
    // IE only
    else if (window.ActiveXObject)
    {
        req = new ActiveXObject('Microsoft.XMLHTTP');
    }
    
    return req;
}    

function http_req(method, callback, sync)
{
    if (!method)
        method = HTTP_GET;
        
    this.method = method;
    
    // If async and no callback, we use our own
    if (callback)
        this.callback = callback;
    this.async = sync ? false : true;
    
    this.req = _make_http_req();

    // Add to our list of requests
    gHTTPRequests = this;
}    

////////////////// TEMP HACK //////////////////////////
function on_state_change()
{
    var r, req, callback;
    
    r = gHTTPRequests;
    req = r.req;

    if (req.readyState != HTTP_STATE_COMPLETE)
        return;
    if (req.status != HTTP_STATUS_OK)
    {
        return;
    }
    
    // user callback, if any, or our default one
    if (r.async && !r.callback)
        callback = r.gen_page;
    else
        callback = r.callback;
        
    if (!callback)
        return;
    
    callback(req.responseText);    
}

// Simplistic default page generation
// Expects a generated page
http_req.prototype.gen_page = function(text)
{
    // Make sure we've been set up correctly
    if (!this.doc)
        return;
    
    doc.open();
    doc.write(text);
    doc.close();    
}    

http_req.prototype.set = function(url, params, method, callback)
{
    if (url)
        this.url = url;
    if (params)    
        this.params = params;
    if (method)    
        this.method = method;
    if (callback)    
        this.callback = callback;
}    

http_req.prototype.send = function(dest_win, url, params)
{
    if (!this.req)
        return false;

    if (dest_win)
        this.doc = dest_win.document;
        
    if (url)
        this.url = url;
    if (params)
        this.params = params;
        
    if (!this.url)
        return false;
        
    // Async calls use a callback
    if (this.async)
        this.req.onreadystatechange = on_state_change;
        // this.req.onreadystatechange = http_req.prototype.on_state_change;
    
    // alert('sending ' + this.async + ' ' + this.method + ' ' + this.url);
    
    this.req.open(this.method, this.url, this.async);
    this.req.send(params);
    
    return true;
}

/*****************************************************************************
http_req.prototype.send = function(dest_win, url, params)
{
    if (!this.req)
        return false;

    if (dest_win)
        this.doc = dest_win.document;
        
    if (url)
        this.url = url;
    if (params)
        this.params = params;
        
    if (!this.url)
        return false;
        
    // Async calls use a callback
    var that, on_state_change;
    
    that = this;
    on_state_change = function()
    {
        var r, req, callback;
    
        r = that;
        req = r.req;

        // alert(req.readyState + ' : ' + req.status);

        if (req.readyState != HTTP_STATE_COMPLETE)
            return;
        if (req.status != HTTP_STATUS_OK)
        {
    //        dprintln('HTTP req status = ' + req.status + 
    //                  ' -- ' + req.statusText);
            return;
        }
    
        // user callback, if any, or our default one
        if (r.async && !r.callback)
            callback = r.gen_page;
        else
            callback = r.callback;
        
        if (!callback)
            return;
    
        callback(req.responseText);    
    }
        
    if (this.async)
        this.req.onreadystatechange = on_state_change;
    
    // alert('sending ' + this.async + ' ' + this.method + ' ' + this.url);
    
    this.req.open(this.method, this.url, this.async);
    this.req.send(params);
    
    return true;
}    
*****************************************************************************/

