/**
 * Class to stack a number of common HttpRequests queued for execution.
 * Each request will process directly after the previous has completed
 * unless manually halted.
 *
 * @version 1.0
 */
function HttpRequestStack() {
	this.httpRequest = null;
	this.url = null;
	this.method = null;
	this.stack = new Array();
	this.active = false;
	this.callee = null;
	this.handleResponse = null;
	this.handleError = null;

	/**
	 * Starts the processing of the request stack by activating the
	 * looping stack processor.
	 */
	this.start = function() {
		if((!this.active) && (this.stack.length > 0)) {
			this.active = true;
			this.onProcessStack();
		}
	}

	/**
	 * Halts the processing of the request stack. The active request
	 * processing when the stack is stopped will continue to execute.
	 */
	this.stop = function() {
		this.active = false;
	}

	/**
	 * Adds another queued item to the stack with the inputted data string.
	 *
	 * @param data The data string to query the page with.
	 */
	this.addRequest = function(data) {
		this.stack[this.stack.length] = data
	}

	/**
	 * Clears the stack array of all queued requests.
	 */
	this.clearRequests = function() {
		if(this.active) {
			this.active = false;
		}

		this.stack = new Array();
	}

	/**
	 * Processes the next item in the request stack using a common
	 * HttpRequest object and private data string.  The request method
	 * for requests is determined by a global method variable.  This method
	 * should not be called directly external to this class.
	 */
	this.onProcessStack = function() {
		if(this.active) {
			if(this.stack[0]) {
				if(this.method == 'POST') {
					this.httpRequest.post(this.url, this.stack[0]);
				}
				else if(this.method == 'GET') {
					this.httpRequest.get(this.url, this.stack[0]);
				}

				this.stack.splice(0, 1);
			}
			else {
				this.stop();
			}
		}
	}

	/**
	 * Handles successful HttpRequest responses from the server and calls
	 * the appropriate response function.
	 *
	 * @param resp The response test from the requested page.
	 * @param code The response code from the requested page.
	 * @param status The response status text binded to the reponse code.
	 */
	this.onHttpRequestResponse = function(resp, code, status) {
		if(this.callee) {
			this.callee.onHttpRequestResponse(resp, code, status);
		}
		else if(this.handleResponse) {
			this.handleResponse(resp, code, status);
		}

		this.onProcessStack();
	}

	/**
	 * Handles failed HttpRequest responses from the server and calls
	 * the appropriate error function.
	 *
	 * @param resp The response test from the requested page.
	 * @param code The response code from the requested page.
	 * @param status The response status text binded to the reponse code.
	 */
	this.onHttpRequestError = function(resp, code, status) {
		if(this.callee) {
			this.callee.onHttpRequestError(resp, code, status);
		}
		else if(this.handleError) {
			this.handleError(resp, code, status);
		}

		this.onProcessStack();
	}

	/**
	 * Sets the global HttpRequest object used for queued requests from
	 * this stack.  The completion of each request is caught by the
	 * onHttpRequestResponse and onHttpRequestError methods through setting
	 * the callee.
	 *
	 * @param httpRequest The HttpRequest object for sending XmlHttpRequests.
	 */
	this.setHttpRequest = function(httpRequest) {
		this.httpRequest = httpRequest;
		this.httpRequest.setCallee(this);
	}

	/**
	 * Sets the URL of the page to request for this stack.
	 *
	 * @param url The URL of the page to request.
	 */
	this.setURL = function(url) {
		this.url = url;
	}

	/**
	 * Sets the method of the HttpRequest calls.
	 *
	 * @param method The method of the HttpRequest call.
	 */
	this.setMethod = function(method) {
		this.method = method;
	}

	/**
	 * Sets the callee object which has reference to this request stack.
	 * Callees handle successful and failed responses by their uniquely
	 * identifiable request handler functions.
	 *
	 * @param callee The object referencing this request stack.
	 */
	this.setCallee = function(callee) {
		this.callee = callee;
	}

	/**
	 * Sets the function to handle successful XmlHttpRequest responses
	 * from the server.
	 *
	 * @param handler The function to handle the response from the server.
	 */
	this.setHandlerResponse = function(handler) {
		this.handleResponse = handler;
	}

	/**
	 * Sets the function to handle unsuccessful XmlHttpRequest responses
	 * from the server.
	 *
	 * @param handler The function to handle the response from the server.
	 */
	this.setHandlerError = function(handler) {
		this.handleError = handler;
	}

	/**
	 * Sets the function to handle successful and unsuccessful
	 * XmlHttpRequest responses from the server.
	 *
	 * @param handler The function to handle the response from the server.
	 */
	this.setHandlerBoth = function(handler) {
		this.handleResponse = handler;
		this.handleError = handler;
	}

	/**
	 * Returns true if the request stack is processing.
	 *
	 * @return True if the stack is being processed.
	 */
	this.isActive = function() {
		return this.active;
	}
}