/*  DepressedPress.com DP_HTTPRequestPool

Author: Jim Davis, the Depressed Press of Boston
Date: June 22, 2006
Contact: webmaster@depressedpress.com
Website: www.depressedpress.com

Full documentation can be found at:
http://www.depressedpress.com/Content/Development/JavaScript/Extensions/

DP_HTTPRequestPool regulates and manages multiple HTTP requests.

Copyright (c) 1996-2006, The Depressed Press of Boston (depressedpress.com)

All rights reserved.

Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:

+) Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 

+) Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 

+) Neither the name of the DEPRESSED PRESS OF BOSTON (DEPRESSEDPRESS.COM) nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. 

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

*/

	// Create the Pool
function DP_HTTPRequestPool(ObInstanceCount) {

		// Manage Arguments
	if ( typeof ObInstanceCount != "number" ) {
		ObInstanceCount = 5;
	};

		// Create a pool of Request Objects
	this.ObInstances = new Array();

	for (var cnt = 0; cnt < ObInstanceCount; cnt++) { 

		try{
			var CurInstance = new XMLHttpRequest();
		} catch(e){};
		try{
			var CurInstance = new ActiveXObject("Microsoft.XMLHTTP");
		} catch(e){};

		if ( CurInstance ) {
			this.ObInstances.push(CurInstance);
		};

	};

		// If we've been unable to create anything, throw an error
	if ( this.ObInstances.length == 0 ) {
		throw new Error("DP_HTTPRequestPool was unable to instantiate compatible HTTPRequest objects.");
	};

		// Create a Queue for Requests
	this.RequestQueue = new Array();
	
};

DP_HTTPRequestPool.prototype.isQueueEmpty = function() { 

	if ( this.RequestQueue.length == 0 ) {
		return true;
	} else {
		return false;
	};

};

DP_HTTPRequestPool.prototype.queueCount = function() { 

	return this.RequestQueue.length;

};

DP_HTTPRequestPool.prototype.clearQueue = function(AbortRunningRequests) { 

		// Manage Arguments
	if ( typeof AbortRunningRequests != "boolean" ) {
		AbortRunningRequests = false;
	};

		// Clear the current Queue
	this.RequestQueue = new Array();

		// Kill running requests
	if ( AbortRunningRequests ) {
		for ( var cnt = 0; cnt < this.ObInstances.length; cnt++ ) { 
			this.ObInstances[cnt].abort();
		};
	};

		// Return true
	return true;

};

DP_HTTPRequestPool.prototype.startInterval = function( IntervalCount ) { 

		// Manage Arguments
	if ( typeof IntervalCount != "number" ) {
		IntervalCount = 500;
	};

		// Set a proxy function to maintain scoping when called in the context of Window
	var ThisPool = this;
	var IntervalProxy = function() { ThisPool.doRequest() };
		// Start the Interval
	this.IntervalID = window.setInterval(IntervalProxy, IntervalCount);

};

DP_HTTPRequestPool.prototype.stopInterval = function() { 

	window.clearInterval(this.IntervalID);

};

DP_HTTPRequestPool.prototype.addRequest = function( Method, URL, Parameters, Handler) { 

		// Manage Arguments
	if ( Method.toLowerCase() != "get" && Method.toLowerCase() != "post" ) {
		var Method = "GET";
	};

	if ( typeof URL != "string" ) {
		var URL = "";
	};
		// If present turn the Parameters object into a string
	var ParametersList = "";
	if ( typeof Parameters == "object" ) {
		for ( var CurProp in Parameters ) {
			if ( typeof Parameters[CurProp] != "function" ) {
				ParametersList += CurProp + "=" + escape(Parameters[CurProp]) + "&";
			};
		};
	};
		// Deal with the Handler
	if ( typeof Handler != "function" ) {
		var Handler = null;
	};
		// Generate the Handler Arguments
	var HandlerArguments = [];
	if ( arguments.length > 4 ) {
		for ( var cnt = 4; cnt < arguments.length; cnt++ ) {
			HandlerArguments.push(arguments[cnt]);
		};
	};

		// Create a new Request
	var CurRequest = new Object();
	CurRequest.Method = Method;
	CurRequest.URL = URL;
	CurRequest.Parameters = ParametersList;
	CurRequest.Handler = Handler;
	CurRequest.HandlerArguments = HandlerArguments;

		// Add the Request to the Queue
	this.RequestQueue.push(CurRequest);
	
		// Return
	return true;

};

DP_HTTPRequestPool.prototype.doRequest = function() { 

		// See if there are any waiting requests
	if ( this.RequestQueue.length > 0 ) {

			// Try to get an Available ObInstance
		var CurObInstance = null;
		for ( var cnt = 0; cnt < this.ObInstances.length; cnt++ ) { 
			if ( this.ObInstances[cnt].readyState == 4 || this.ObInstances[cnt].readyState == 0 ) { 
				CurObInstance = this.ObInstances[cnt];
					// Call abort to "clear" the instance - don't know why it's needed, but it seems to be
				CurObInstance.abort();
			};
		};

			// If we have an available instance, use it
		if ( CurObInstance != null ) {

				// Get the Request
			var CurRequest = this.RequestQueue.shift();

			if ( typeof CurRequest.Handler == "function" ) {

					// Construct the onReadyStateChange handler
				var ArgString = [];
				for (var cnt = 0; cnt < CurRequest.HandlerArguments.length; cnt++) {
					ArgString[cnt] = "CurRequest.HandlerArguments[" + cnt + "]";
				};
				var HandlerString = "";
				HandlerString += "	if ( CurObInstance.readyState == 4 ) {";
				if ( ArgString.length == 0 ) {
					HandlerString += "		CurRequest.Handler(CurObInstance.responseText);";
				} else {
					HandlerString += "		CurRequest.Handler(CurObInstance.responseText, " + ArgString.join(", ") + ");";
				};
				HandlerString += "	};";

					// Set the onReadyStateChange handler
				CurObInstance.onreadystatechange = function() { eval(HandlerString) };

			} else {

					// Set the onReadyStateChange handler
				CurObInstance.onreadystatechange = function() { return true };

			};


				// Open the Request
			CurObInstance.open( CurRequest.Method, CurRequest.URL, true );
				// Set the encoding type, if needed
			if ( CurRequest.Method.toLowerCase() == "post" ) {
				CurObInstance.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
			};
				// Send the data
			CurObInstance.send(CurRequest.Parameters);

		};

			// Return
		return true;

	};

		// Return
	return false;

};