/**
 * Browser Tier Messaging Framework - Sends an XML request to the server
 *
 * Usage:
 *      There are two types of Messages
 *   1) Generic Message  - An associative javascript array makes up the message
 *
 *      //Create the Message parameters to be sent
 *      msgParams = {
 *           username: "john",
 *           password: "doe"
 *      }
 *
 *      //Create the Message Object with the action to call and the parameters
 *      message = new GenericMessage(/full/path/to/action, msgParams);
 *
 *      //Define a method to handle the response
 *      message.onResponse = function(response) {
 *          //Process Response
 *          alert(response.responseText);
 *      }
 *      message.send();
 *
 *   2) Form Message  - An html form makes up the message
 *
 *      //Create the Message Object with the action to call and Id of the form to submit
 *      message = new FormMessage(/full/path/to/action, formId);
 *
 *      //Define a method to handle the response
 *      message.onResponse = function(response) {
 *          //Process Response
 *          alert(response.responseText);
 *      }
 *      message.send();
 *    
 * Note: - all messages are sent asyncronously. To send a syncronous message use 
 *          message.sendModal()
 *
**/

/**
* Cross-browser XMLHttpRequest instantiation.
*/
function XMLRequest() {
    if (window.XMLHttpRequest) {
        return new XMLHttpRequest();
    } else {
        var msxmls = ['MSXML3', 'MSXML2', 'MSXML', 'Microsoft'];
        for (var i=0; i < msxmls.length; i++) {
          try {
            return new ActiveXObject(msxmls[i]+'.XMLHTTP');
          } catch (e) { }
        }
        throw new Exception("No XML component installed!");
    }
}

function Message(url, message, object) {
    this.xmlhttp  = null
    this.url      = url;
    this.msg      = message;
    this.msgId    = null;
    this.obj      = object;
    if (object == null) {
        this.obj  = this;
    }
    this.messages = {};
    this.msgCount = 0;
}

/**
 * Send the Message to the server
 * Messages are sent via the XMLHttoRequest object.
 * This is preferable to form submits as it avoids page refreshes
**/
Message.prototype.sendRequest = function(method, modal) {
    this.xmlhttp= new XMLRequest();
    this.msgId  = window.MessageObject.msgCount;
    window.MessageObject.messages[window.MessageObject.msgCount] = this;

    str = "func = function() {"+
        " messg = window.MessageObject.messages["+window.MessageObject.msgCount+"];"+
        " messg.onload();"+
        " }";
    window.MessageObject.msgCount++;
    eval(str);
    this.xmlhttp.onreadystatechange = func;
    this.xmlhttp.open(method,this.getUrl(),modal);
    this.xmlhttp.send(null);
}

/**
 * Send an asyncronous Message 
**/
Message.prototype.send = function(method) {
    method="GET";
    this.sendRequest(method,true);
}

/**
 * Send an syncronous Message 
**/
Message.prototype.sendModal = function(method) {
    method="GET";
    this.sendRequest(method,false);
}

/**
 * Called after the message has been loaded
**/
Message.prototype.onload = function() {
    // if xmlhttp shows "loaded"
    if (this.xmlhttp.readyState==4) {
        // if "OK"
        if (this.xmlhttp.status==200) {
            this.obj.onResponse(this.xmlhttp);
        } else {
            // Error Handling here
//            alert("Problem retrieving XML data")
        }
    }
}

/**
 * Get the Url to send the request to
**/
Message.prototype.getUrl = function() {
    return this.url;
}


/**
 * MUST be Implemented by user of Message framework
**/
Message.prototype.onResponse = function() {
    
}


/**
 * A Generic Message that uses an associative array
 * to send
**/
function GenericMessage(url, message, object) {
    this.url   = url;
    this.msg   = message;
    this.msgId = null;
    this.obj   = object;
    if (object == null) {
        this.obj  = this;
    }
}

/**
 * Extends Base Message object
**/
GenericMessage.prototype = new Message();

/**
 * Convert the associative array to request parameters
**/
GenericMessage.prototype.getUrl = function() {
    var ret = this.url+"?messageId="+this.msgId;
    count = 0;
    for(var name in this.msg) {
        ret += "&"+name+"="+this.msg[name];
    }
    return ret;
}

/**
 * A Form Message that uses a form to send
**/
function FormMessage(url, message, object) {
    this.url   = url;
    this.msg   = message;
    this.msgId = null;
    this.obj   = object;
    if (object == null) {
        this.obj  = this;
    }
}

/**
 * Extends Base Message object
**/
FormMessage.prototype = new Message();

/**
 * Convert the form to request parameters
**/
FormMessage.prototype.getUrl = function() {
    var ret = this.url+"?messageId="+this.msgId;
    var frm = document.getElementById(this.msg);
    for(count=0;count < frm.elements.length; count++) {
        if (frm.elements[count].type == "checkbox") {
            ret += "&"+frm.elements[count].name+"="+frm.elements[count].checked;
        } else {
            ret += "&"+frm.elements[count].name+"="+frm.elements[count].value;
        }
    }
    return ret;
}

window.MessageObject = new Message();
