/******** Async Functionality ********/

/// Send Async Request Function
///
///	 Description: This is the function that is actually called by a developer's
///		code.  It accepts a target URL, some content to send to that URL via POST,
///		and a function to call when the response has been recieved.  The callback
///		function should be setup to accept two parameters:  the response text and 
///		the HTTP response status code.
///
function saxf_sendAsync(targetURL, xmlRequest, callback)
{
	newRequest = new saxf_Request(targetURL, xmlRequest, callback);
	saxf_AddRequest(newRequest);
	newRequest.Run();
}


/// Request Object Definition
///
///  Description:  This object represents a request.  It stores 
///		both the XMLHTTP object and a series of state
///		properties for the request.
///
function saxf_Request(targetURL, xmlRequest, callback)
{
	this.xmlHTTP = new ActiveXObject('Microsoft.XMLHTTP');
	this.xmlRequest = xmlRequest;
	this.callback = callback;
	this.targetURL = targetURL;
	this.status = 0;
	this.callbackStatus = 0;

	function Run()
	{
		this.xmlHTTP.open('POST',this.targetURL,true);
		this.xmlHTTP.onreadystatechange = saxf_CatchReturn;
		this.xmlHTTP.send(this.xmlRequest);
	}
	this.Run = Run;

}


/// Framework Callback Function
///
///	 Description: This is the function that all returning requests
///		use as their callback method.  It is basically a bit of a hack, because
///		the XMLHTTP readystatechange event does not provide any context for its
///		call into the onreadystatechange handler function.  To get around this,
///		I implemented a bit of a "let-us-see-what-request-is-complete"
///		logic approach.  The key to this is combining the readyState property 
///		of the XMLHTTP object with the custom saxf_Request.callbackStatus 
///		property.
///
function saxf_CatchReturn()
{
	// We need to loop through the request list to see if there is a request 
	// that is pending the callback processing.  We use both the xmlHTTP's 
	// readyState and the custom callbackStatus properties.
	for (request in requestList)
	{
		// readyState == 4 means the request has returned completely
		// callbackStatus == 0 means that the callback has not yet been processed
		if (requestList[request].xmlHTTP.readyState == 4 && 
			requestList[request].callbackStatus == 0)
		{
			// Mark this request as having been processed
			requestList[request].callbackStatus = 1;
			
			// Set the request status and response text
			requestList[request].status = requestList[request].xmlHTTP.status;
			
			// Call the requesting component's handler, passing the responseText 
			// and status of the call
			requestList[request].callback(requestList[request].xmlHTTP.ResponseText, 
				requestList[request].status);

			// Cleanup the request
			saxf_RemoveRequest(request);

		}
	}
}


/// Request Array and Request Management Functions

// This array stores all currently ongoing requests
requestList = new Array();

// adds a new request object to the list of ongoing requests
function saxf_AddRequest(RequestToAdd) 
{
	requestList[requestList.length] = RequestToAdd;
}

// removes a request from the list of ongoing requests
function saxf_RemoveRequest(LocationToRemove) 
{
	requestList.splice(LocationToRemove, 1);
}
