// Define a list of Microsoft XML HTTP ProgIDs.
HttpRequest.prototype.MS_PROGIDS = new Array(
	"Msxml2.XMLHTTP.7.0",
	"Msxml2.XMLHTTP.6.0",
	"Msxml2.XMLHTTP.5.0",
	"Msxml2.XMLHTTP.4.0",
	"MSXML2.XMLHTTP.3.0",
	"MSXML2.XMLHTTP",
	"Microsoft.XMLHTTP"
);

// Define constants.
HttpRequest.prototype.READY_STATE_UNINITIALIZED = 0;
HttpRequest.prototype.READY_STATE_LOADING       = 1;
HttpRequest.prototype.READY_STATE_LOADED        = 2;
HttpRequest.prototype.READY_STATE_INTERACTIVE   = 3;
HttpRequest.prototype.READY_STATE_COMPLETED     = 4;

// Define properties.
HttpRequest.prototype.successCallback = null;
HttpRequest.prototype.failureCallback = null;
HttpRequest.prototype.url             = null;
HttpRequest.prototype.username        = null;
HttpRequest.prototype.password        = null;
HttpRequest.prototype.requestHeaders  = new Array();
HttpRequest.prototype.status          = null;
HttpRequest.prototype.statusText      = null;
HttpRequest.prototype.responseXML     = null;
HttpRequest.prototype.responseText    = null;

// Define methods.
HttpRequest.prototype.abort                 = HttpRequestAbort;
HttpRequest.prototype.setRequestHeader      = HttpRequestSetRequestHeader;
HttpRequest.prototype.clearRequestHeaders   = HttpRequestClearRequestHeaders;
HttpRequest.prototype.get                   = HttpRequestGet;
HttpRequest.prototype.post                  = HttpRequestPost;
HttpRequest.prototype.initiateRequest       = HttpRequestInitiateRequest;
HttpRequest.prototype.getResponseHeader     = HttpRequestGetResponseHeader;
HttpRequest.prototype.getAllResponseHeaders = HttpRequestGetAllResponseHeaders;

//=============================================================================
// Contructor function.
//=============================================================================
function HttpRequest()
{
	// Create the appropriate HttpRequest object for the browser.
	this.xmlHttpRequest = null;

	if (window.XMLHttpRequest != null)
		this.xmlHttpRequest = new window.XMLHttpRequest();
	else if (window.ActiveXObject != null)
	{
		// Must be IE, find the right ActiveXObject.
		var success = false;
		for (var i = 0; i < HttpRequest.prototype.MS_PROGIDS.length && !success; i++)
		{
			try
			{
				this.xmlHttpRequest = new ActiveXObject(HttpRequest.prototype.MS_PROGIDS[i]);
				success = true;
			}
			catch (ex)
			{}
		}
	}

	// If we couldn't create one, display an error and exit
	if (this.xmlHttpRequest == null)
	{
		alert("Error in HttpRequest():\n\nCannot create an XMLHttpRequest object.");
		return;
	}
}

//=============================================================================
// Methods.
//=============================================================================

function HttpRequestAbort()
{
	this.xmlHttpRequest.abort();
}

function HttpRequestSetRequestHeader(name, value)
{
	// If the header name already exists, replace the value.
	for (var i = 0; i < this.requestHeaders.length; i++)
	{
		var pair = this.requestHeaders[i].split("\n");
		if (pair[0].toLowerCase() == name.toLowerCase())
		{
			this.requestHeaders[i] = name + "\n" + value;
			return;
		}
	}

	// Otherwise, add it as a new item.
	var n = this.requestHeaders.length;
	this.requestHeaders.push(name + "\n" + value);
}

function HttpRequestClearRequestHeaders()
{
	this.requestHeaders = new Array();
}

function HttpRequestGet()
{
	this.initiateRequest("GET", null);
}

function HttpRequestPost(data)
{
	this.initiateRequest("POST", data);
}

function HttpRequestGetResponseHeader(name)
{
	return this.xmlHttpRequest.getResponseHeader(name);
}

function HttpRequestGetAllResponseHeaders()
{
	return this.xmlHttpRequest.getAllResponseHeaders();
}

//=============================================================================
// Internal method to make the actual request.
//=============================================================================
function HttpRequestInitiateRequest(method, data)
{
	// Clear all response fields.
	this.status       = null;
	this.statusText   = null;
	this.responseText = null;
	this.responseXML  = null;

	// Set up the callback functions.
	var refObj = this;
	this.xmlHttpRequest.onreadystatechange =
		function()
		{
			refObj.readyState = refObj.xmlHttpRequest.readyState
			if (refObj.readyState == HttpRequest.prototype.READY_STATE_COMPLETED)
			{
				refObj.status       = refObj.xmlHttpRequest.status;
				refObj.statusText   = refObj.xmlHttpRequest.statusText;
				refObj.responseText = refObj.xmlHttpRequest.responseText;
				refObj.responseXML  = refObj.xmlHttpRequest.responseXML;
				if (refObj.status == 200)
				{
					if (refObj.successCallback != null)
						refObj.successCallback(refObj);
				}
				else
				{
					if (refObj.failureCallback != null)
						refObj.failureCallback(refObj);
				}
			}
		}

	// Initialize the request.
	var url = this.url;
	if (this.queryString != null)
		url = url + "?" + this.queryString;
	this.xmlHttpRequest.open(method, url, true, this.username, this.password);

	// Set request headers (this must be done after the request is opened).
	for (var i = 0; i < this.requestHeaders.length; i++)
	{
		var pair = this.requestHeaders[i].split("\n");	
		this.xmlHttpRequest.setRequestHeader(pair[0], pair[1]);
	}

	// Start the request, passing any POST data.
	this.xmlHttpRequest.send(data);
}

