
function ajaxRequestor() { this.clearAll(); }

ajaxRequestor.prototype.__defaultError = function(sender)
{
	var tempStr = "ajaxRequestor Error:\n" +
                  "status: " + this.requestor.status + "\n" +
	 	          "headers: " + this.requestor.getAllResponseHeaders();
	alert(tempStr);
}
ajaxRequestor.prototype.__defaultSuccess = function(sender)
{
	alert("ajaxRequestor successfully returned from a request - but there is no handler assigned to receive it");
}
ajaxRequestor.prototype.__decodeString = function(inputStr)
{
	var decoded = unescape(inputStr);
	decoded = decoded.replace(/\%2F/g, "/"); 
	decoded = decoded.replace(/\%3F/g, "?");
	decoded = decoded.replace(/\%3D/g, "=");
	decoded = decoded.replace(/\%26/g, "&");
	decoded = decoded.replace(/\%40/g, "@");
	return decoded;
}
ajaxRequestor.prototype.__encodeString = function(inputStr)
{
	var encoded = escape(inputStr);
	encoded = encoded.replace(/\//g,"%2F");
	encoded = encoded.replace(/\?/g,"%3F");
	encoded = encoded.replace(/=/g,"%3D");
	encoded = encoded.replace(/&/g,"%26");
	encoded = encoded.replace(/@/g,"%40");
	return encoded;
}
ajaxRequestor.prototype.__getParams = function()
{
	if (this.getNames.length == 0) { return ""; }
	var out = (this.url.indexOf('?') == -1) ? '?' : '&';
	for (var i=0; i<this.getNames.length; i++)
	{
		out += this.getNames[i] + '=' + this.getValues[i];
		if (i < (this.getNames.length - 1)) { out += '&'; }
	}
	return out;
}
ajaxRequestor.prototype.__getRequestor = function()
{
	if ((this.requestor != null) && (!this.reqIsIE)) { return true; }
	
	try {
		this.requestor = new XMLHttpRequest();
		this.reqIsIE = false;
		return; true;
	} catch(e) {}
	
	try {
		this.requestor = new ActiveXObject("Msxml2.XMLHTTP.6.0");
		this.reqIsIE = true;
		return; true;
	} catch(e) {}

	try {
		this.requestor = new ActiveXObject("Msxml2.XMLHTTP.3.0");
		this.reqIsIE = true;
		return; true;
	} catch(e) {}

	try {
		this.requestor = new ActiveXObject("Msxml2.XMLHTTP");
		this.reqIsIE = true;
		return; true;
	} catch(e) {}

	try {
		this.requestor = new ActiveXObject("Microsoft.XMLHTTP");
		this.reqIsIE = true;
		return; true;
	} catch(e) {}
	
	alert('ajaxRequestor Fatal Error: Cannot instantiate an XMLHTTP Object');
}
ajaxRequestor.prototype.__xmitLog = function(theMsg)
{
	var bodyArr = document.getElementsByTagName('body');
	var theBody = bodyArr[0];
	theBody.appendChild(document.createTextNode(theMsg));
	theBody.appendChild(document.createElement('br'));
}
ajaxRequestor.prototype.__onRTS = function()
{
	if ((this.requestor.readyState >= 2) && (this.timeoutHandle))
	{
		clearTimeout(this.timeoutHandle);
		this.timeoutHandle = false;
	}
	
    if (this.requestor.readyState == 4)
	{
		if (this.masterStatus) { this.masterStatus.handleChange(false); }
		if ((this.requestor.status==200) || (this.requestor.status==0) )
		{
			this.lastResponse = this.__decodeString(this.requestor.responseText);
			if (!this.lastResponse) 
			{
				return false;
			}
			if (this.xmlHandler) 
			{
				this.xmlHandler.importXML(this.lastResponse); 
			}
			this.onSuccess(this);
		} else {
			switch(this.requestor.status)
			{
				case 12029:
				case 12030:
				case 12031:
				case 12152:
				case 12159:
					alert('Untrapped error: ' + this.request.status);
/*
					var loader = this;
					setTimeout( function() { loader.execute.call(loader); }, 10);
*/
					break;
					
				default:
					this.onError(this);
			}
		}
		this.busy = false;
	}
}
ajaxRequestor.prototype.__postParams = function()
{
	var out = "";
	var varNames = '';
	for (var i=0; i<this.postNames.length; i++)
	{
		if (i > 0) { varNames += '|'; }
		varNames += this.postNames[i];
		if (i > 0) { out += '&'; }
		out += this.postNames[i] + '=' + this.__encodeString(this.postValues[i]);
	}
	if (out) { out += '&' + 'ajax_var_names=' + varNames; }
	return out;
}
ajaxRequestor.prototype.abort = function()
{
	if (this.busy)
	{
		// clear timeout as well
		this.requestor.abort();
		clearTimeout(this.timeoutHandle);
		this.timeoutHandle = false;
		this.busy = false;
	}
}

ajaxRequestor.prototype.clear = function()
{
	this.methodPost = true;
	this.__transStatus = 0;
	this.__transBusy = false;
    this.lastResponse = new String();
	this.selfReference = null;
    this.newRequest();
	this.timeoutHandle = false;
	this.timeoutMS = 20000;
}
ajaxRequestor.prototype.clearAll = function()
{
    this.xmlHandler = null;
    this.masterStatus = null;
    this.onUnrecognized = new String();

    this.onError = this.__defaultError;
    this.onSuccess = this.__defaultSuccess;
    
    this.clear();
}
ajaxRequestor.prototype.execute = function(timeoutVal)
{
	if (this.busy)
	{
		// clear timeout as well
		this.requestor.abort();
		this.busy = false;
	}
	
	var thisTimeoutVal = this.timeoutMS;
	if (timeoutVal != undefined) { thisTimeoutVal = timeoutVal; }
	
	this.__getRequestor();

	if (!this.requestor) {
		alert("You cannot dispatch a request on this machine (no viable XMLHTTPRequestor)");
		return "";
	}
	if (!this.url) {
		alert("You must supply a URL to ajaxRequestor to process a request");
		return "";
	}

	this.busy = true;
	var httpMethod = (this.methodPost) ? 'POST' : 'GET';

	var theURL = this.url;
	theURL += this.__getParams();
	this.lastRequest = theURL;
	
	var loader = this;
	this.requestor.onreadystatechange = function() { loader.__onRTS.call(loader); }
	if (this.masterStatus) { this.masterStatus.handleChange(true); }

	// Set a callback to <me> in case the request takes to long...
	this.timeoutHandle = setTimeout( function() { loader.__handleTimeout.call(loader); }, this.timeoutMS);

    this.requestor.open('POST', theURL, true);
    this.requestor.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
  	if ((document.all) && (document.getElementById))
  	{ 
  		// IE
  		setTimeout( function() { loader.__executeSend.call(loader)} , 10);
  	} else {
		this.requestor.send(this.__postParams());  	
	}
}
ajaxRequestor.prototype.__executeSend = function() { this.requestor.send(this.__postParams()); }

ajaxRequestor.prototype.__handleAbort = function()
{
	if (this.masterStatus) { this.masterStatus.handleChange(false); }
	this.requestor.abort();
}
ajaxRequestor.prototype.__handleTimeout = function()
{
	this.__handleAbort();
	var loader = this;
	setTimeout(function() { loader.execute.call(loader); }, 100);
}
ajaxRequestor.prototype.getParam = function(key, value)
{
	var ptr = this.getNames.length;
	for (var i=0; i<this.getNames.length; i++)
	{
		if (this.getNames[i] == key) { ptr = i; }
	}
	this.getNames[ptr] = key;
	this.getValues[ptr] = value;
}
ajaxRequestor.prototype.method = function(doPost)
{
	this.methodPost = (doPost);
}
ajaxRequestor.prototype.newRequest = function()
{
	this.getNames = new Array();
	this.getValues = new Array();
	this.postNames = new Array();
	this.postValues = new Array();
	this.url = '';
}
ajaxRequestor.prototype.postParam = function(key, value)
{
	var ptr = this.postNames.length;
	for (var i=0; i<this.postNames.length; i++)
	{
		if (this.postNames[i] == key) { ptr = i; }
	}
	this.postNames[ptr] = key;
	this.postValues[ptr] = value;
}
