/**
 *=--------------------------------------------------------------------------=
 * swajax.js
 *=--------------------------------------------------------------------------=
 * This file contains a number of routines to help us with Ajax in SWiK.
 * We have written a nifty little class called FormSwajax, whose submitFormData
 * method takes all the data in a particular form and sends those
 * asynchronously to the given URL, waiting for the response, evaluating the
 * expected JavaScript code returned, adn then calls a function specified by
 * the caller ...
 *
 * Author: Marc Wandschneider, 2005-10-07
 */

/**
 *=--------------------------------------------------------------------------=
 * getNewHTTPObject
 *=--------------------------------------------------------------------------=
 * Creates a new instance of an XmlHttpRequest and returns it to the caller.
 */
function getNewHTTPObject()
{
        var xmlhttp;

        /** Special IE only code ... */
        /*@cc_on
          @if (@_jscript_version >= 5)
              try
              {
                  xmlhttp = new ActiveXObject("Msxml2.XMLHTTP");
              }
              catch (e)
              {
                  try
                  {
                      xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
                  }
                  catch (E)
                  {
                      xmlhttp = false;
                  }
             }
          @else
             xmlhttp = false;
        @end @*/

        /** Every other browser on the planet */
        if (!xmlhttp && typeof XMLHttpRequest != 'undefined')
        {
            try
            {
                xmlhttp = new XMLHttpRequest();
            }
            catch (e)
            {
                xmlhttp = false;
            }
        }

        return xmlhttp;
}


/**
 *=--------------------------------------------------------------------------=
 * FormSwajax
 *=--------------------------------------------------------------------------=
 * This 'class' will be used to perform Ajax requests on forms.  It will take
 * a reference to a JavaScript form object and pass all of the data in that
 * form to the specified URL.  It will then redirect the reply, once the
 * readyState is 4 (completed) to the specified function in code.
 *
 * @param HTMLForm     The form element whose contents we want to get and
 *                      send to the server.
 * @param string       The URL to which the data should be sent.
 * @param function     Which function to call when the full response has been
 *                      retrieved.
 */
function FormSwajax(formElement, sendUrl, responseFunction)
{
    this.formElement = formElement;
    this.url = sendUrl;
    this.responseFunction = responseFunction;
}

/**
 *=--------------------------------------------------------------------------=
 * FormSwajax.xmlHttpObject
 *=--------------------------------------------------------------------------=
 * Class variable to hold the XmlHtpRequest object we create.
 */
FormSwajax.xmlHttpObject = null;
FormSwajax.lastObject = null;


/**
 *=--------------------------------------------------------------------------=
 * FormSwajax.submitFormData
 *=--------------------------------------------------------------------------=
 * Instance member function that actuall goes and submits the form data to
 * server based on the data we have so far ...
 */
FormSwajax.prototype.submitFormData = function()
{
    var formData = '';

    //
    // for each of the elements on the form, add them to the list of
    // parameters we pass via the form data.
    //
    for (var x = 0; x < this.formElement.elements.length; x++)
    {
        if (formData != '')
            formData += '&';

        formData += this.formElement.elements[x].name;
        formData += '=';
        if (this.formElement.elements[x].type == 'checkbox')
        {
            if (this.formElement.elements[x].checked)
                formData += 'true';
            else
                formData += 'false';
        }
        else
        {
            formData += encodeURIComponent(this.formElement.elements[x].value);
        }
    }

    return this.finalSend(formData);
}


FormSwajax.prototype.finalSend = function(formData)
{
    //
    // get an XmlHttpRequest object and put it in our global array of
    // request objects ...
    //
    var xmlHttp = getNewHTTPObject();
    FormSwajax.xmlHttpObject = xmlHttp;
    FormSwajax.lastObject = this;

    xmlHttp.onreadystatechange = function() {
        if (FormSwajax.xmlHttpObject.readyState != 4)
            return;

        hideThrobber();

        //
        // evaluate the response text, and send it on to the user's
        // callback when we're ready for them ...
        //
        eval(FormSwajax.xmlHttpObject.responseText);

        if (document.getElementById('anonymous_changes'))
        {
            document.getElementById('changecount_holder').style.display = 'inline';
            document.getElementById('anonymous_changes').innerHTML = responseArray['uncredited_changes'];
        }
        FormSwajax.lastObject.responseFunction(responseArray);
    }

    xmlHttp.open("POST", this.url, true);
    xmlHttp.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
    xmlHttp.send(formData);

    showThrobber();
    return false;
}






/**
 *=--------------------------------------------------------------------------=
 * SimpleSwajax
 *=--------------------------------------------------------------------------=
 * This 'class' will be used to perform simple Ajax requests. It will send a
 * request to the server and then it will then redirect the reply, once the
 * readyState is 4 (completed) to the specified function in code.
 * We have a ghetto system in place to support up to 10 simultaneous requests.
 * If this is not sufficient, there is something SERIOUSLY wrong with the
 * design of the application.
 *
 * @param string       The URL to which the request should be sent.
 * @param function     Which function to call when the full response has been
 *                      retrieved.
 */
function SimpleSwajax(sendUrl, responseFunction)
{
    var x;

    for (x = 0; x < SimpleSwajax.outstanding.length; x++)
    {
        if (SimpleSwajax.outstanding[x] == null)
            break;
    }

    //
    // too many requests.
    //
    if (x == SimpleSwajax.outstanding.length)
    {
        alert('Too many requests!');
        return;
    }

    SimpleSwajax.outstanding[x] = { requestObject: this, xmlHttp: null };

    this.requestNumber = x;
    this.url = sendUrl;
    this.responseFunction = responseFunction;
    this.throb = true;
}

/**
 *=--------------------------------------------------------------------------=
 * SimpleSwajax.xmlHttpObject
 *=--------------------------------------------------------------------------=
 * Class variable to hold the XmlHtpRequest object we create.
 */
SimpleSwajax.outstanding = new Array(10);

/**
 *=--------------------------------------------------------------------------=
 * SimpleSwajax.go
 *=--------------------------------------------------------------------------=
 * Instance member function that actually sends the requests and waits for the
 * response.
 */
SimpleSwajax.prototype.go = function()
{
    return this.innerGo('');
}


SimpleSwajax.prototype.innerGo = function(formData)
{
    var req = this.requestNumber;

    //
    // get an XmlHttpRequest object and put it in our global array of
    // request objects ...
    //
    var xmlHttp = getNewHTTPObject();
    SimpleSwajax.outstanding[req].xmlHttp = xmlHttp;

    switch (req)
    {
        case 0:
            xmlHttp.onreadystatechange = handleSS0;
            break;
        case 1:
            xmlHttp.onreadystatechange = handleSS1;
            break;
        case 2:
            xmlHttp.onreadystatechange = handleSS2;
            break;
        case 3:
            xmlHttp.onreadystatechange = handleSS3;
            break;
        case 4:
            xmlHttp.onreadystatechange = handleSS4;
            break;
        case 5:
            xmlHttp.onreadystatechange = handleSS5
            break;
        case 6:
            xmlHttp.onreadystatechange = handleSS6
            break;
        case 7:
            xmlHttp.onreadystatechange = handleSS7
            break;
        case 8:
            xmlHttp.onreadystatechange = handleSS8;
            break;
        case 9:
            xmlHttp.onreadystatechange = handleSS9;
            break;
    }


    if (formData != '')
    {
        xmlHttp.open("POST", this.url, true);
        xmlHttp.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
        xmlHttp.send(formData);
    }
    else
    {
        xmlHttp.open("GET", this.url, true);
        xmlHttp.send('');
    }

    if (this.throb)
        showThrobber();

    return false;
}

SimpleSwajax.prototype.sendWFormData = function(formData)
{
    return this.innerGo(formData);
}

function handleSS0() { handleSimpleSwajaxResponse(0); }
function handleSS1() { handleSimpleSwajaxResponse(1); }
function handleSS2() { handleSimpleSwajaxResponse(2); }
function handleSS3() { handleSimpleSwajaxResponse(3); }
function handleSS4() { handleSimpleSwajaxResponse(4); }
function handleSS5() { handleSimpleSwajaxResponse(5); }
function handleSS6() { handleSimpleSwajaxResponse(6); }
function handleSS7() { handleSimpleSwajaxResponse(7); }
function handleSS8() { handleSimpleSwajaxResponse(8); }
function handleSS9() { handleSimpleSwajaxResponse(9); }


function handleSimpleSwajaxResponse(req) {

    if (SimpleSwajax.outstanding[req].xmlHttp.readyState != 4)
        return;

    hideThrobber();

    //
    // evaluate the response text, and send it on to the user's
    // callback when we're ready for them ...
    //
    eval(SimpleSwajax.outstanding[req].xmlHttp.responseText);
    if (SimpleSwajax.outstanding[req].xmlHttp.responseText.indexOf('responseArray') != -1)
        SimpleSwajax.outstanding[req].requestObject.responseFunction(responseArray);

    SimpleSwajax.outstanding[req] = null;
}
