/**
 * @author John Schneider
 * @copyright 2009 Reservoir Creative Group, LLC
 */

/**
 * Does AJAX requests, and also calls the AJAX requests for a single child node if it exists.
 * @param {String} url The URL.
 * @param {String} method The method (GET or POST)
 * @param {Array} submitarray The key-value pair list to submit.
 * @param {Boolean} stoprequests If this is set to true, then this AJAX object cannot make requests, but its children still will make theirs.
 * @param {String} errormessage If this is set, it will alert the given error message.  If it is not, it will alert the default debug message.
 */
function Ajax(url, method, submitarray, stoprequests, errormessage){
	
	//The AJAX ajax to fire when this one is done firing.
	this._child;
	//the method (GET or POST)
	this._method = method;
	//whether or not to stop requests.
	this._stopRequests = stoprequests;
	//the value to submit.
	this._submitArray = submitarray;
	//the url of this object.
	this._url = url;
	//the custom error message
	this._errormessage = errormessage;
	
	/**
	 * The function to call when evaluating the response text
	 * from an AJAX call.
	 * @param {String} text The text to evaluate.
	 */
	this.CallbackFunction = function(text) { };
	
	/**
	 * Does the Ajax request.
	 */
    this.Request = function(){
        //declaring thisparent this is necessary for variable scope purposes.
		var thisparent = this;
		//if stop requests is set to true, then process the child and terminate the request.
		if (thisparent._stopRequests) {
			if (thisparent._child) {
				thisparent._child.Request();
			}
			return;
		}
		
		//now do the request.
		var xmlhttp = false;
        try {
            xmlhttp = new ActiveXObject("Msxml2.XMLHTTP");
        } 
        catch (e) {
            try {
                xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
            } 
            catch (E) {
                xmlhttp = false;
            }
        }
        if (!xmlhttp && typeof XMLHttpRequest != 'undefined') {
            try {
                xmlhttp = new XMLHttpRequest();
            } 
            catch (e) {
                xmlhttp = false;
            }
        }
        if (!xmlhttp && window.createRequest) {
            try {
                xmlhttp = window.createRequest();
            }
            catch (e) {
                xmlhttp = false;
            }
        }
        //set the url appropriately if this is a GET request.
		if (thisparent._method == "GET") {
			if (thisparent._submitArray) {
				thisparent._url += "?";
				for (var i in thisparent._submitArray) {
					thisparent._url += (i + "=" + thisparent._submitArray[i] + "&");
				}
				thisparent._url = thisparent._url.substr(0, thisparent._url.length - 1);
			}
		}
		xmlhttp.open(thisparent._method, thisparent._url, true);
		if (thisparent._method == "POST") {
            xmlhttp.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
        }
        xmlhttp.onreadystatechange = function(){
            if (xmlhttp.readyState == 4) {
                if (xmlhttp.status == 200) {
                    thisparent.CallbackFunction(xmlhttp.responseText); 
					//make it so that if a child exists, it will be processed
					//after this object.
					if (thisparent._child) {
						thisparent._child.Request();
						//clear this object.
						thisparent = null;
					}
                }
                else {
                    //now this is where we can set a custom error message
					if (thisparent._errormessage) {
						alert(thisparent._errormessage);
					}
					else {
						alert("Error " + xmlhttp.status + " requesting " + thisparent._url);
					}
                }
            }
        }
        if (thisparent._method == "POST") {
            var submitvalue = "";
			if (thisparent._submitArray) {
				for (var i in thisparent._submitArray) {
					submitvalue += (i + "=" + thisparent._submitArray[i] + "&");
				}
				submitvalue = submitvalue.substr(0, submitvalue.length - 1);
			}
			xmlhttp.send(submitvalue);
	    }
        else {
            xmlhttp.send(null);
        }
    }
    
	/**
	 * Adds a child ajax object to this one.
	 * @param {Ajax} ajaxobject The Ajax object to add as this one's child.
	 */
	this.SetChild = function(ajaxobject) {
		this._child = ajaxobject;
	}
}

/**
 * Does AJAX requests in a queue.
 */
function AjaxQueue() {
	//make it so that it gets the special case url.
	this._root = new Ajax("/", "GET", new Array(), true, null);
	//set the current request to the current one.
	this._currentRequest = this._root;
	
	/**
	 * Processes the queue of AJAX requests.
	 */
	this.ProcessQueue = function() {
		this._root.Request();
		//reset the queue.
		this._root = new Ajax("/", "GET", new Array(), true, null);
		this._currentRequest = this._root;
	}
	
	/**
	 * Adds an object to the queue of requests.
	 * @param {Ajax} ajaxobject The request object to add.
	 */
	this.AddToQueue = function(ajaxobject) {
		this._currentRequest.SetChild(ajaxobject);
		this._currentRequest = this._currentRequest._child;
	}
}

//create the new ajax queue object.
var AjaxQueue = new AjaxQueue();