/**
	Title: Ajax
	Purpose: Ajax class for making asynchronous HTTP requests
	Parameters: None
	Known Bugs: None
	Author: Tyler Heslinga
	Browsers Tested: IE, Firefox
	Revision History:
		* Tyler Heslinga 03/21/2010 - Created
*/
function Ajax() {

	var self = this; // Handle loss of 'this' scope

	this.request = null; // HTTP request object
	this.url = null; // Absolute or relative URL for the request
	this.method = null; // The HTTP method used to open the connection. 'GET' or 'POST'
	this.postData = null; // The body of the message being sent with the request
	this.handleResponse = null; // Function for handling a successful response
	this.responseFormat = null; // The format of the response. Either 'text', 'xml', or 'json'
	this.mimeType = null; // Can be used to override the MIME type in the response returned by the server
	this.handleError = null; // Function for handling an error in the request

	/**
		Title: init
		Purpose: Create HTTP request object
		Parameters: None
		Returns: HTTP request object
		Known Bugs: None
		Exceptions Thrown: None
		Assumptions: None
		Side Affects: None
		Revision History:
			* Tyler Heslinga 03/21/2010 - Created
	*/
	this.init = function() {

		if (!self.request) {
			try {
				self.request = new XMLHttpRequest(); // Firefox, Chrome, Safari, IE7 and later
			}
			catch (error) {
				try {
					self.request = new ActiveXObject('MSXML2.XMLHTTP'); // Later versions of IE
				}
				catch (error) {
					try {
						self.request = new ActiveXObject('Microsoft.XMLHTTP'); // Earlier versions of IE
					}
					catch (error) {
						return false;
					} // end try
				} // end try
			} // end try
		} // end if

		return self.request;

	};

	/**
		Title: doRequest
		Purpose: Opens and sends the asychronous HTTP request. Sets up functions for successful response or error.
		Parameters: None
		Returns: Nothing
		Known Bugs: None
		Exceptions Thrown: None
		Assumptions: None
		Side Affects: None
		Revision History:
			* Tyler Heslinga 03/21/2010 - Created
	*/
	this.doRequest = function() {

		if (!self.init()) {
			alert('Could not create XMLHttpRequest object.');
			return;
		} // end if

		self.request.open(self.method, self.url, true);

		if (self.method == "POST") {
			self.request.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
		} // end if

		if (self.mimeType) {
			try {
				self.request.overrideMimeType(self.mimeType);
			}
			catch (error) {

			} // end try
		} // end if

		self.request.onreadystatechange = function() {

			var response = null;

			// When the readyState = 4 (Completed), process the response
			if (self.request.readyState == 4) {
				switch (self.responseFormat) {
					case 'text':
						response = self.request.responseText;
						break;
					case 'xml':
						response = self.request.responseXML;
						break;
					case 'json':
						response = eval("(" + self.request.responseText + ")");
						break;
				} // end switch
				// The status is the HTTP result code. If it is between 200 and 299, it is successful
				if (self.request.status >= 200 && self.request.status <= 299) {
					self.handleResponse(response);
				}
				else {
					try {
						self.handleError(response, self.request.status, self.request.statusText);
					}
					catch (error) {

					} // end try
				} // end if
			} // end if
		};

		self.request.send(self.postData);

	};

	/**
		Title: abort
		Purpose: Aborts the HTTP request
		Parameters: None
		Returns: Nothing
		Known Bugs: None
		Exceptions Thrown: None
		Assumptions: None
		Side Affects: Changes the onreadystatechange event handler function so that it isn't used when calling the XMLHttpRequest abort method.
		Revision History:
			* Tyler Heslinga 03/21/2010 - Created
	*/
	this.abort = function() {

		if (self.request) {
			self.request.onreadystatechange = function() { };
			self.request.abort();
			self.request = null;
		} // end if

	};

	/**
		Title: doGet
		Purpose: Initiates a GET HTTP request
		Parameters: 1. url (REQUIRED) - Absolute or relative URL for the request
					2. hand (REQUIRED) - Function for handling a successful response
					3. format (REQUIRED) - The format of the response. Either 'text' or 'xml'
					4. errorfunc (REQUIRED) - Function for handling an error in the request
		Returns: Nothing
		Known Bugs: None
		Exceptions Thrown: None
		Assumptions: None
		Side Affects: None
		Revision History:
			* Tyler Heslinga 03/21/2010 - Created
	*/
	this.doGet = function(url, hand, format, errorfunc) {

		self.method = 'GET';
		self.url = url;
		self.handleResponse = hand;
		self.responseFormat = format;
		self.handleError = errorfunc;

		self.doRequest();

	};

	/**
		Title: doPost
		Purpose: Initiates a POST HTTP request
		Parameters: 1. url (REQUIRED) - Absolute or relative URL for the request
					2. postData (REQUIRED) - The body of the message being sent with the request
					3. hand (REQUIRED) - Function for handling a successful response
					4. format (REQUIRED) - The format of the response. Either 'text' or 'xml'
					5. errorfunc (REQUIRED) - Function for handling an error in the request
		Returns: Nothing
		Known Bugs: None
		Exceptions Thrown: None
		Assumptions: None
		Side Affects: None
		Revision History:
			* Tyler Heslinga 03/21/2010 - Created
	*/
	this.doPost = function(url, postData, hand, format, errorfunc) {

		self.method = 'POST';
		self.url = url;
		self.postData = postData;
		self.handleResponse = hand;
		self.responseFormat = format;
		self.handleError = errorfunc;

		self.doRequest();

	};

}
