//Base AJAX Class
//TODO: lots!
function Ajax()
{
	this.isLocal = true;
	this.request = null;
	this.url = null;
	this.method = 'GET';
	this.async = true;
	this.status = null;
	this.statusText = '';
	this.postData = null;
	this,readyState = null;
	this.responseText = null;
	this.responseXML = null;
	this.handleResponse = null;
	this.handleErr = null;
	this.responseFormat = 'text';
	this.mimeType = null;
	
	this.forceFailure = false;	//Used for debugging, cause makeRequest to return false; TODO: extend to return specified error.


	//Creates the XMLHttpRequest object for the client browser
	//TODO: use browser detection and switch, less execution
	this.init = function()
	{
		if(!this.request)
		{
			try
			{
				//Try to create object for later versions of IE.
				this.request = new ActiveXObject('MSXML2.XMLHTTP');
			}
			catch(e)
			{
				try
				{
					//Try to create object for Firefox, Safari, IE7, etc.
					this.request = new XMLHttpRequest();
					
				}
				catch(e)
				{
					try
					{
						//Try to create object for early versions of IE.
						this.request = new ActiveXObject('Microsoft.XMLHTTP');
					}
					catch(e)
					{
						//Could not create an XMLHttpRequest object.
						return false;
					}
				}
			}
		}

		return this.request;
	};

	//Executes a request
	this.doRequest = function()
	{
		if(!this.init())
		{
			return false;
		}

		this.request.open(this.method, this.url, this.async);

		//Override MIME Type incase we're requesting XML from a dozy server (not our own obviously!)
		if(this.mimeType)
		{
			try
			{
				request.overrideMimeType(this.mimeType);
			}
			catch(e)
			{
				//Couldn't override the MIME Type, discard the exception (bad boy)
			}
		} 

		//Assign this to self as onreadystatechange is a callback that will be called from a remote class and we'll lose our scope
		var self = this;

		//Define the callback function for handling XMLHTTPRequest state change
		this.request.onreadystatechange = function()
		{
			var response = null;

			if(4 == self.request.readyState)
			{
				switch(self.responseFormat)
				{
					//Assign the correct response depending on requested format
					//TODO: handle changing formats specified from client code
					case 'text':
					response = self.request.responseText;
					break;
					case 'xml':
					response = self.request.responseXML;
					break;
					case 'object':
					response = request;
					break;
				}

				//Response is successful
				//TODO: check response data is actually valid
				if(self.isLocal || (self.request.status >= 200 && self.request.status <= 299))
				{
					//callback the response handler from the client code
					self.handleResponse(response);
				}
				else //An error occured
				{
					self.handleErr(response);
				}
			}
		};
		
		//Free up the request on abort (timeout or user abort) so that it can be 
		//reinitialized upon reuse.
		this.abort = function()
		{
			if(this.request)
			{
				//remove the callback incase we get any XMLHTTPRequest calls from the deadside
				this.request.onreadystatechange = function(){};
				
				//abort the existing request
				this.request.abort();
				
				//remove the request so it will be reinitialized
				this.request = null;
			}
		}

		//Send the request
		this.request.send(this.postData);

		return true;
	};
	
	
	//Makes the request.
	//This is the entry point.
	//TODO: Specify the error handler or return a code.  We shouldn't do final error handling in the util class.
	this.makeRequest = function(url, responsehandler, errorhandler, format)
	{
		if(this.forceFailure)
		{
			//TODO: will extend once error handling is extended
			return false;
		}
			
		//Set the url
		this.url = url;
			
		//Set the response handler
		this.handleResponse = responsehandler;
		
		//Set the error handler
		this.handleErr = errorhandler;
		
		//Set the request format
		this.responseFormat = format || 'text';
			
		//Execute the request
		return this.doRequest();
	};
};	