/* -----------------------------------------------------------------------------
  Last Updated On:  02/20/08
  Procedural and OO interfaces to pipe-delimited AJAX communication.
----------------------------------------------------------------------------- */

// Global vars and method for both interfaces
var resultsToMethod = '';
var resultsToMethodQueue = new Array;
resultsToMethodQueue.length = 0;
var timerID;

function processReqChange() {
// Intermediary function that waits around for a response from the server.

    if (req.readyState == 4) {
    // only if req shows "complete"
        if (req.status == 200) {
        // If status is "ok" then process the results
            response = (req.responseText) ? req.responseText : 'NO RESPONSE';
            var escapedResponse = escape(response);
            clearTimeout(timerID);
            eval(resultsToMethod + '(\'' + escapedResponse + '\');');
            processReqQueue();
        }
        else {
            resultsToMethod = '';
            alert("There was a problem connecting to the server.  Please try again.");
            return false;
        }
    }
}


function processReqQueue() {
// In case there is a back-up of AJAX requests waiting to process, this will
// move the queue up one process, and execute it.

    if (resultsToMethodQueue.length > 0) {

        var nextProcess = resultsToMethodQueue[0];
        for (var i = 0; i <= resultsToMethodQueue.length - 2; i++) {
            resultsToMethodQueue[i] = resultsToMethodQueue[i + 1];
        }
        resultsToMethodQueue.length--;
        resultsToMethod = '';
        eval(nextProcess + '(\'\')');

    }
    else {
        resultsToMethod = '';
    }
}



/* -----------------------------------------------------------------------------
  PROCEDURAL INTERFACE
----------------------------------------------------------------------------- */

function getXMLDoc(url) {
// Do a GET request.

    if (window.XMLHttpRequest) {
    // branch for native XMLHttpRequest object

        req = new XMLHttpRequest();
        req.onreadystatechange = processReqChange;
        req.open("GET", url, true);
        req.send(null);

    }
    else if (window.ActiveXObject) {
    // branch for IE/Windows ActiveX version

        req = new ActiveXObject("Microsoft.XMLHTTP");
        if (req) {
            req.onreadystatechange = processReqChange;
            req.open("GET", url, true);
            req.send();
        }
    }
}


function postXMLDoc(url, strSubmit) {
// Do a POST request.

        var xmlHttpReq = false;

        if (window.XMLHttpRequest) {
        // branch for native XMLHttpRequest object

            req = new XMLHttpRequest();
            req.overrideMimeType('text/xml');

        }
        else if (window.ActiveXObject) {
        // branch for IE/Windows ActiveX version
            req = new ActiveXObject("Microsoft.XMLHTTP");
        }

        req.open('POST', url, true);
        req.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
        req.onreadystatechange = processReqChange;
        req.send(strSubmit);

}



/* -----------------------------------------------------------------------------
  OO INTERFACE
----------------------------------------------------------------------------- */

function ajax(resultsToMethod) {

    // Basic vars
    this.queryString = '';
    this.resultsToMethod = resultsToMethod;

    // Methods
    this.requiredFields = requiredFields;
    this.verifySave = verifySave;
    this.verifyDelete = verifyDelete;
    this.setFields = setFields;
    this.setSession = setSession;
    this.setOption = setOption;
    this.postRequest = postRequest;
    this.getRequest = getRequest;

}


function requiredFields(fieldPairs) {

    for (var i = 0; i < fieldPairs.length; i++) {

        var keyData = fieldPairs[i].split('=>');
        var key = keyData[0];
        var label = keyData[1];

        if (document.forms[0].elements[key]) {
            switch (document.forms[0].elements[key].type) {
            case 'text':
                if (document.forms[0].elements[key].value == '') {
                    alert("Please respond to the '" + label + "' question before continuing.");
                    return false;
                }
                break;

            case 'checkbox':
                if (document.forms[0].elements[key].checked == false) {
                    alert("Please respond to the '" + label + "' question before continuing.");
                    return false;
                }
                break;

            case 'select-one':
                if ((document.forms[0].elements[key].selectedIndex < 0) ||
                    (document.forms[0].elements[key][document.forms[0].elements[key].selectedIndex].value == '')) {
                    alert("Please respond to the '" + label + "' question before continuing.");
                    return false;
                }
                break;

            case 'select-multiple':
                if ((document.forms[0].elements[key].selectedIndex) ||
                    (document.forms[0].elements[key][document.forms[0].elements[key].selectedIndex].value == '')) {
                    alert("Please respond to the '" + label + "' question before continuing.");
                    return false;
                }
                break;

            case 'textarea':
                if (document.forms[0].elements[key].value == '') {
                    alert("Please respond to the '" + label + "' question before continuing.");
                    return false;
                }
                break;

            default:
                if (document.forms[0].elements[fields[i]][0].type == 'radio') {
                    radioSet = fields[i];
                    var radioChecked = 0;
                    for (var radioIndex = 0; radioIndex <= document.forms[0].elements[fields[i]].length - 1; radioIndex++) {
                        if (document.forms[0].elements[fields[i]][radioIndex].checked == true) {
                            radioChecked = 1;
                        }
                    }
                    if (radioChecked == 0) {
                        alert("Please respond to the '" + label + "' question before continuing.");
                        return false;
                    }
                    break;
                }
                else {
                    alert("Error in displayResults()\n" +
                        'Could not determine field type of "' + key + '.' + "\n" +
                        'Possibly two fields called ' + key);
                }
            }
        }
    }
    return true;
}


function verifySave(fieldName, fieldText) {

    if ((document.forms[0].elements[fieldName].selectedIndex > -1 &&
        document.forms[0].elements[fieldName][document.forms[0].elements[fieldName].selectedIndex].value == '') ||
        (document.forms[0].elements[fieldName].selectedIndex < 0)) {
    // Saving a new record
        if (confirm('Are you sure you want to create a new ' + fieldText +
            '?  To save this record, press the "Ok" button; otherwise, ' +
            'press "Cancel."')) {
            return true;
        }
        else {
            return false;
        }
    }
    else {
    // Something is selected

        if (confirm('Are you sure you want to edit the selected ' + fieldText +
            '?  To change this record, press the "Ok" button; otherwise, ' +
            'press "Cancel."')) {
            return true;
        }
        else {
            return false;
        }
    }
}


function verifyDelete(fieldName, fieldText) {

    if (((document.forms[0].elements[fieldName].type == 'select-one' || document.forms[0].elements[fieldName].type == 'select-multiple') &&
          document.forms[0].elements[fieldName][document.forms[0].elements[fieldName].selectedIndex].value) ||
          (document.forms[0].elements[fieldName].type == 'text' && document.forms[0].elements[fieldName].value) ||
          (document.forms[0].elements[fieldName].type == 'hidden' && document.forms[0].elements[fieldName].value)) {
        // Delete the selected record

        if (confirm('Are you sure you want to delete the selected ' + fieldText +
                    '?  To permanently delete this record, press the "Ok" button; ' +
                    'otherwise, press "Cancel."')) {
            return true;
        }
        else {
            return false;
        }
    }
    else {
    // Nothing selected
        return false;
    }
}


function setFields(fields) {

    this.queryString += '&template=bypass';
    for (var i = 0; i <= fields.length - 1; i++) {

        if (document.forms[0].elements[fields[i]]) {

            switch (document.forms[0].elements[fields[i]].type) {
            case 'text':
                this.queryString += '&' + fields[i] + '=' + escape(document.forms[0].elements[fields[i]].value);
                break;

            case 'checkbox':
                if (document.forms[0].elements[fields[i]].checked) {
                    this.queryString += '&' + fields[i] + '=' + escape(document.forms[0].elements[fields[i]].value);
                }
                break;

            case 'select-one':
                if (document.forms[0].elements[fields[i]].selectedIndex >= 0) {
                    this.queryString += '&' + fields[i] + '=' + escape(document.forms[0].elements[fields[i]][document.forms[0].elements[fields[i]].selectedIndex].value);
                }
                break;

            case 'select-multiple':
                var value = '';
                optionSet = fields[i];
                for (var optionIndex = 0; optionIndex <= document.forms[0].elements[fields[i]].length - 1; optionIndex++) {
                    if (document.forms[0].elements[fields[i]][optionIndex].selected) {
                        value += document.forms[0].elements[fields[i]][optionIndex].value + '|';
                    }
                }
                value = escape(value.substr(0, (value.length - 1)));
                this.queryString += '&' + fields[i] + '=' + escape(value);
                break;

            case 'textarea':
                this.queryString += '&' + fields[i] + '=' + escape(document.forms[0].elements[fields[i]].value);
                break;

            case 'hidden':
                this.queryString += '&' + fields[i] + '=' + escape(document.forms[0].elements[fields[i]].value);
                break;

            default:
            // This is either a radio button or a mistake
                if (document.forms[0].elements[fields[i]][0].type == 'radio') {

                    var value = '';
                    radioSet = fields[i];
                    for (var radioIndex = 0; radioIndex <= document.forms[0].elements[fields[i]].length - 1; radioIndex++) {
                        if (document.forms[0].elements[fields[i]][radioIndex].checked) {
                            value += escape(document.forms[0].elements[fields[i]][radioIndex].value);
                        }
                    }
                    this.queryString += '&' + fields[i] + '=' + escape(value);

                }
                else {

                    alert("Error in setFields()\n" +
                        'Could not read field "' + fields[i] + '" of type "' + fieldType + '"' + "\n" +
                        'Possibly two fields called ' + fields[i]);
                    return false;
                }
            }
        }
        else {
            alert("Error in setFields()\n" + 'Object not found: ' + fields[i] + "\n" +
                'Possible typo in ' + fields[i]);
            return false;
        }
    }
}


function setSession(userID, sessionID, request) {
// Set a queryString object's uid, sid, and req values

    if (userID && sessionID && request) {
        this.queryString += '&uid=' + escape(userID);
        this.queryString += '&sid=' + escape(sessionID);
        this.queryString += '&req=' + escape(request);
    }
    else {
        alert("Error:  Could not set session for queryString object.\n" +
            'userID, sessionID, and request values are required');
    }
}


function setOption(field, optionSelected, optionNotSelected) {
// Set a queryString object's option value

    if (field && optionSelected) {
        if (optionSelected && optionNotSelected) {
            if (document.forms[0].elements[field].value) {
                this.queryString += '&option=' + escape(optionSelected);
            }
            else {
                this.queryString += '&option=' + escape(optionNotSelected);
            }
        }
        else {
            this.queryString += '&option=' + escape(optionSelected);
        }
    }
    else {
        alert("Error:  Could not set option for queryString object.\n" +
            'key field and at least one option are required');
    }
}


function postRequest(url) {

    if (resultsToMethod == '') {

        resultsToMethod = this.resultsToMethod;
        var xmlHttpReq = false;

        if (window.XMLHttpRequest) {
        // native XMLHttpRequest object
            req = new XMLHttpRequest();
            if (req.overrideMimeType) {
            // Non-IE only
                req.overrideMimeType('text/xml');
            }
        }
        else if (window.ActiveXObject) {
        // IE/Windows ActiveX, pre-IE 7
            req = new ActiveXObject("Microsoft.XMLHTTP");
        }

        req.open('POST', url, true);
        req.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
        req.onreadystatechange = processReqChange;
        req.send(this.queryString);

    }
    else {
        resultsToMethodQueue.length++;
        resultsToMethodQueue[resultsToMethodQueue.length - 1] = this.resultsToMethod;
    }
}


function getRequest(url) {

    if (resultsToMethod == '') {

        resultsToMethod = this.resultsToMethod;
        var urlString = url + '?' + this.queryString;
        var xmlHttpReq = false;
        if (window.XMLHttpRequest) {
        // branch for native XMLHttpRequest object

            req = new XMLHttpRequest();
            req.onreadystatechange = processReqChange;
            req.open("GET", urlString, true);
            req.send(null);

        }
        else if (window.ActiveXObject) {
        // branch for IE/Windows ActiveX version, pre-IE 7

            req = new ActiveXObject("Microsoft.XMLHTTP");
            if (req) {
                req.onreadystatechange = processReqChange;
                req.open("GET", urlString, true);
                req.send();
            }
        }
    }
    else {
        resultsToMethodQueue.length++;
        resultsToMethodQueue[resultsToMethodQueue.length - 1] = this.resultsToMethod;
    }
}

