//****************************************************************************
//  AJAX Core
//****************

// Written as a generic interface for XJAX style async requests.
// Wraps the XMLHTTPRequest in a container object, abstracting IE / W3C spec differences and
// allowing for javascript attributes in all cases.
// Provides support for tracking and cancelling calls through a naming system:
//  If a call is named, any new call of the same name will automatically cancel the original
// Nameless calls simply trigger concurrently and cannot be cancelled.
// Also provides support for different callback handlers for each request.

// Useful routines:
//    cancelXMLRequest() - cancel a previously created, named request
//    sendXMLRequest() - create a named or un-named request and trigger it asynchronously  




//array to hold active requests
var xmlResponderObjects = new Array();


//public, useful methods
//***************
function cancelXMLRequest(key)
{
	var foo;
	for(var i=0;i<xmlResponderObjects.length;i++)
	{
		if(xmlResponderObjects[i]["key"]==key)
		{
			//if an object is found
			requestObject=xmlResponderObjects[i];
			foo=requestObject.foo;
			//set it's event handler to an empty function - fixes IE bug
			requestObject.responder.onreadystatechange=function () {};
			//abort the request (fixes Firefox bug)
			requestObject.responder.abort();
			//and remove it
			xmlResponderObjects.splice(i,1);
		}
	}
	return foo;
}


//send a request of type 'get' with action 'action'
//handler is the callback routine to call on response
//foo is a string you may set to whatever you wish for your own uses (it's never touched internally)
function sendXMLRequest(url,action, handler, key, foo)
{
	//actually create the responder
	var XMLResponder = createRequestObject(key);
	//set the response handler
	XMLResponder["callbackHandler"]=handler;
	//set the user data
	XMLResponder["foo"]=foo;
	//set the action
	if(action.length>400)
	{
		alert('post mode ajax');
		XMLResponder.responder.open('post', url);
		XMLResponder.responder.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
		XMLResponder.responder.setRequestHeader("Content-length", action.length);
		XMLResponder.responder.setRequestHeader("Connection", "close");	
		//set callback dispatcher (which then calls the user-specified handler)
		XMLResponder.responder.onreadystatechange=handleResponse;
		//execute
		XMLResponder.responder.send(action);
	}
	else
	{
		XMLResponder.responder.open('get', url+"?"+action);
		//set callback dispatcher (which then calls the user-specified handler)
		XMLResponder.responder.onreadystatechange=handleResponse;
		//execute
		XMLResponder.responder.send(null);
	}
}


// Helper routines - not usually needed directly
//***********

//create the XMLHTTPRequest object for use on the page
//key is used to name a request (allowing a previous request to be aborted in favour of the new one)
function createRequestObject(key)
{	
	//if a key is passed, kill any pending requests with the same key
	if(key!="")
		{cancelXMLRequest(key);}
	var requestObject=new	XMLRequestWrapperObject();
	//record the key
	requestObject["key"]=key;
	xmlResponderObjects.push(requestObject);
	return requestObject;
}




//handle the reply to the xml request
//if everything went well and the reply completed
//find the relevent handler and call it with the
//reply xml document
function handleResponse()
{
	//check the responder array for any responders with a readystate of 4
	for(var i in xmlResponderObjects)
	{
		//if the current item is not null and has the 'completed' state
		if(xmlResponderObjects[i]!=null && xmlResponderObjects[i].responder.readyState == 4)
		{
			//call the designated handler
			xmlResponderObjects[i]["callbackHandler"](xmlResponderObjects[i]);
			//remove the element
			xmlResponderObjects.splice(i,1);
		}
	}
}


function XMLRequestWrapperObject()
{
	if(typeof(XMLHttpRequest)=='undefined')
	{
		this.mode='msie';
		this.responder = new ActiveXObject("Microsoft.XMLHTTP");
	}
	else
	{
		this.mode='w3c';
		this.responder = new XMLHttpRequest();
	}
}



