/**
 * Send an AJAX request.
 *
 * Inspiration: http://saloon.javaranch.com/cgi-bin/ubb/ultimatebb.cgi?ubb=get_topic&f=20&t=005211
 *
 * Param url - URL to request
 * Param callBackFunction - function to call when the request has returned from
 *     the server
 * Param async - true if the call is asynchronous, false otherwise
 * Param get - true if this is a GET request, false if it is a POST
 * Param postPayload - post data. Ignore if get is true.
 */
function sendAjaxRequest(url, callBackFunction, async, get, postPayload)
{
    var method = "GET";

    if (get)
    {
        // Prevent browser caching by sending always sending a unique url.
        url += "&randomnumber=" + new Date().getTime();
        postPayload = null;
    }
    else
    {
        method = "POST"
    }

  // Obtain an XMLHttpRequest instance
    var req = newXMLHttpRequest();
  // Set handler function to receive callback notifications from request.
    var handlerFunction = getReadyStateHandler(req, callBackFunction);
    req.onreadystatechange = handlerFunction;
    req.open(method, url, async);

    if (!get)
    {
        req.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
        req.setRequestHeader("Content-length", postPayload.length);
        req.setRequestHeader("Connection", "close");
    }

    req.send(postPayload);
}

/**
 *  Return: a new XMLHttpRequest object, or false if this browser doesn't
 *    support it
 */
function newXMLHttpRequest()
{
    var xmlreq = false;

    if (window.XMLHttpRequest)
    {
        // Create XMLHttpRequest object in non-Microsoft browsers
        xmlreq = new XMLHttpRequest();
    }
    else if (window.ActiveXObject)
    {
        var avers = ["Microsoft.XmlHttp", "MSXML2.XmlHttp", "MSXML2.XmlHttp.3.0", "MSXML2.XmlHttp.4.0", "MSXML2.XmlHttp.5.0"];

        for (var i = avers.length -1; i >= 0; i--)
        {
            try
            {
                xmlreq = new ActiveXObject(avers[i]);
            }
            catch(e)
            {
            }
        }

        if (!xmlreq)
        {
            alert("Unable to create AJAX request object.");
        }
    }

    return xmlreq;
}

/**
 * Create and return a call back function that checks for server
 * success/failure.
 *
 * Param req - The XMLHttpRequest whose state is changing
 * Param responseHandler - Function to pass the response to
 * Return: a function that waits for the specified XMLHttpRequest
 *     to complete, then passes its XML response to the given handler function.
 */
function getReadyStateHandler(req, responseHandler)
{
    // Return an anonymous function that listens to the XMLHttpRequest instance
    return function ()
    {
        // If the request's status is "complete"
        if (req.readyState == 4)
        {
            var message = req.getResponseHeader("status");
            // Check that a successful server response was received
            if (req.status == 200) //todo: catch 404 error.
            {
                // Pass the payload of the response to the handler function
                responseHandler(req);
            }
            else if (message != undefined && message != null && message.length > 0)
            {
                alert("Error status  [" + req.status + "] with message [" + message + "].");
            }
        }
    }
}