/**
 * Construct an HTTP Request object.
 *
 */
function getHTTPObject()
{
    var xmlhttp = null;
    if (typeof XMLHttpRequest != 'undefined') {
        try {
            xmlhttp = new XMLHttpRequest();
        }
        catch (e) {
            xmlhttp = null;
        }
    }
    else {
        var msxmlhttp = new Array(
            'Msxml2.XMLHTTP.5.0',
            'Msxml2.XMLHTTP.4.0',
            'Msxml2.XMLHTTP.3.0',
            'Msxml2.XMLHTTP',
            'Microsoft.XMLHTTP'
        );
        for (var i = 0; i < msxmlhttp.length; i++) {
            try {
                xmlhttp = new ActiveXObject(msxmlhttp[i]);
            }
            catch (e) {
                xmlhttp = null;
            }
        }
    }
    return xmlhttp ? xmlhttp : false;
}

var http = getHTTPObject(); // global http request object. @deprecated

/**
 * Print debugging information.
 * This will be appended to the element with id="debug", if such an element exists.
 */
function printDebug(s)
{
    var debug = getElement('debug');
    if (debug) debug.innerHTML += '<div class="debug">' + s + '</div>';
}


/**
 * Get a query string for POSTing or GETting a form.
 *
 * @param string formId The id of the form to construct a query string for
 * @return string The query string for the form. If formId is false, the empty string will be returned.
 */
function getQueryString(formId, isCommandForm)
{
    var post = '';
    var nParams = 0;

    if (!formId) return post;

    if (!isCommandForm) {
        isCommandForm = false;
    }

    function addParam(name, value)
    {
        if (nParams>0) post += '&';
        post += encodeURIComponent(name) + '=' + encodeURIComponent(value);
        nParams++;

        if (isCommandForm) {
            if (nParams>0) post += '&';
            post += encodeURIComponent('p_' + name) + '=' + encodeURIComponent(value);
            nParams++;
        }
    }

    var form = getElement(formId);
    if (!form || !form.elements) return post;

    // iterate through form elements to construct the query string
    for (var i=0; i<form.length; ++i) {
        var e = form.elements[i];
        if (e.name.length == 0) {
            continue;
        }
        switch (e.type) {
            case 'select-multiple': {
                for (var j=0; j<e.length; ++j) {
                    if (e.options[j].selected) {
                        addParam(e.name, e.options[j].value);
                    }
                }
                break;
            }
            case 'radio':
            case 'checkbox': {
                if (e.checked) {
                    addParam(e.name, e.value);
                }
                break;
            }
            default: {
                addParam(e.name, e.value);
                break;
            }
        }
    }
    return post;
}


function RequestCallbackProcessor(http, target, callback) {
    if (http) {
    this.http     = http;
    this.target   = target;
    this.callback = callback;
    }
    else handleEvent();
}

RequestCallbackProcessor.prototype.handleEvent = function() {
    alert(this.http);
    if (this.http.readyState == 4) {
        //          printDebug('RESPONSE='+escape(http.responseText));
        if (this.http.status == 200) {
            // ...processing statements go here...
            response = this.http.responseText
            if (this.target && response) {
                this.target.innerHTML = response;
            }
            if (this.callback) callback(response);
        } else {
            alert("There was a problem retrieving the XML data:\n" +
            this.http.statusText);
        }
    }
}

/**
 * This function provides a crude form of AJAX.
 * It asynchronously sends an HTTP request and
 * replaces a specified DOM element with the response text of the request.
 *
 * @param elementId The responseText of the request will replace the innerHTML of the element with this id.
 * @param page The page name to send the request to.
 * @param action The name of the command that should be executed.
 * @param params GET parameters for the query string, e.g. '&type=12' (note the initial &, which is neccesary unless params is the empty string).
 * @param callback If specified, this function will be called if the request succeeds. The http.responseText will be passed to the callback function.
 * @param formId If specified, the contents of the form with this id will be POSTed with the request.
 * @param asynchronous If specified the http object sends data asynchronous
 * @param postParams If this querystring parameter is specified the POST values are taken from this querystring
 * @param widgetFormId If specified, the contents of the form with this id will be POSTed with the request.
 */
function updateElement(elementId, page, action, params, callback, formId, asynchronous, postParams, widgetFormId, isCommandForm, noUpdateContent)
{
    var target = getElement(elementId);
    if (asynchronous !== false) asynchronous=true;
    // set up and send request
    var http = getHTTPObject();
    var url = '?page=' + page + '&ajax=' + action + params;
    http.open('POST', url, asynchronous);

    var requestHandler = function()
    {
        if (http.readyState == 4) {
            //printDebug('RESPONSE='+escape(http.responseText));
            if (http.status == 200) {
                if (target && http.responseText && noUpdateContent != 1) {
                    target.innerHTML = http.responseText;
                }
                else {
                    //alert("There was a problem retrieving the data:\n" +
                    //        http.statusText);
                }
                if (callback) callback(http.responseText);
            }
            else {
                //alert("There was a problem retrieving the data:\n" +
                //        http.statusText);
            }
        }
    };
    if (asynchronous) {
        http.onreadystatechange = requestHandler;
    }
    http.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
    var postData = '';
    // User Form
    if (formId) {
        postData = getQueryString(formId, isCommandForm);
    }
    // AjaxWidget generated form
    if (widgetFormId) {
        data = getQueryString(widgetFormId);
        if (formId) {
            postData += '&' + data;
        }
        else {
            postData = data;
        }
    }
    if (postParams) {
        if (formId || widgetFormId) {
            postData += '&' + postParams;
        }
        else {
            postData = postParams;
        }
    }
    http.send(postData);
    if (!asynchronous) {
        while(1) {
            if (http.readyState == 4) {
                requestHandler();
                return;
            }
        }
    }
}

/**
 * Special AjaxWidget update method that calls updateElement with appropriate parameters
 * @param elementId The responseText of the request will replace the innerHTML of the element with this id.
 * @param callback If specified, this function will be called if the request succeeds. The http.responseText will be passed to the callback function.
 * @param formId If specified, the contents of the form with this id will be POSTed with the request.
 * @param params GET parameters for the query string, e.g. '&type=12' (note the initial &, which is neccesary unless params is the empty string).
 * @param postParams If this querystring parameter is specified the POST values are taken from this querystring
 */
function ajaxWidgetUpdate(elementId, callback, formId, params, postParams, isCommandForm, noUpdateContent) {
    var widgetFormId = elementId + 'ajaxwidgetform';
    postParams = 'ajaxwidgetuid=' + elementId + '&' + postParams;
    //alert(elementId + "\n" + widgetFormId);
    updateElement(elementId, 'ajax', 'ajax', params, callback, formId, true, postParams, widgetFormId, isCommandForm, noUpdateContent);
}

/*
var ajaxWidgetLoaderDivName = 'ajaxwidgetloader'; // div that is to follow the mouse (must be position:absolute)
var ajaxWidgetLoaderOffX = 15;          // X offset from mouse position
var ajaxWidgetLoaderOffY = 15;          // Y offset from mouse position
var ajaxWidgetLoaderRunning = false;
var ajaxWidgetMouseX = 0;
var ajaxWidgetMouseY = 0;
function ajaxWidgetLoaderMouseX(evt) {if (!evt) evt = window.event; if (evt.pageX) return evt.pageX; else if (evt.clientX)return evt.clientX + (document.documentElement.scrollLeft ?  document.documentElement.scrollLeft : document.body.scrollLeft); else return 0;}
function ajaxWidgetLoaderMouseY(evt) {if (!evt) evt = window.event; if (evt.pageY) return evt.pageY; else if (evt.clientY)return evt.clientY + (document.documentElement.scrollTop ? document.documentElement.scrollTop : document.body.scrollTop); else return 0;}
function ajaxWidgetLoaderUpdate() {
    if (ajaxWidgetLoaderRunning) {
        if (document.getElementById) {
            var obj = document.getElementById(ajaxWidgetLoaderDivName).style;
            obj.left = ajaxWidgetMouseX;
            obj.top = ajaxWidgetMouseY;
        }
    }
}
function ajaxWidgetLoaderFollowMouse(evt) {
    ajaxWidgetMouseX = (parseInt(ajaxWidgetLoaderMouseX(evt)) + ajaxWidgetLoaderOffX) + 'px';
    ajaxWidgetMouseY = (parseInt(ajaxWidgetLoaderMouseY(evt)) + ajaxWidgetLoaderOffY) + 'px';
    ajaxWidgetLoaderUpdate();
}
function ajaxWidgetLoaderStart() {
    ajaxWidgetLoaderRunning = true;
    if (document.getElementById) {
        var obj = document.getElementById(ajaxWidgetLoaderDivName).style;
        //obj.visibility = 'visible';
        var obj = document.images['ajaxwidgetloaderimg'];
        obj.src = 'images/ajax-loader.gif';
    }
}
function ajaxWidgetLoaderStop() {
    ajaxWidgetLoaderRunning = false;
    if (document.getElementById) {
        var obj = document.getElementById(ajaxWidgetLoaderDivName).style;
        //obj.visibility = 'hidden';
        var obj = document.images['ajaxwidgetloaderimg'];
        obj.src = 'images/ajax-loader-blank.gif';
    }
}
//document.onmousemove = follow;
//addMouseMoveEvent(ajaxWidgetLoaderFollowMouse);
*/
