// Global Variable
var _ms_XMLHttpRequest_ActiveX;

function Ajax()
{
	this._Queue = new Queue();

	this.openFunction = this.Nothing;
	this.sentFunction = this.Nothing;
	this.receivingFunction = this.Nothing;
	this.receivedFunction = this.Nothing;
	this.failedFunction = this.Nothing;
	this._Sending = false;
	this._MultiSend = "C";
	this._Xml = false;
	//"A" abort first send if second send is called
	//"B" abort second send if second send is called
	//"C" allow all calls to go through
	
	if (window.XMLHttpRequest)
	{
		// Not IE
		this._Object = new XMLHttpRequest();
	}
	else if(window.ActiveXObject)
	{
		// IE
		// Instantiate the latest MS ActiveX Objects
		if (_ms_XMLHttpRequest_ActiveX)
		{
			this._Object = new ActiveXObject(_ms_XMLHttpRequest_ActiveX);
		}
		else
		{
			// loops through the various versions of XMLHTTP to ensure we're using the latest
			var versions = ["Msxml2.XMLHTTP.7.0", "Msxml2.XMLHTTP.6.0", "Msxml2.XMLHTTP.5.0", "Msxml2.XMLHTTP.4.0", "MSXML2.XMLHTTP.3.0", "MSXML2.XMLHTTP", "Microsoft.XMLHTTP"];

			for(var i = 0; i < versions.length ; i++)
			{
				try
				{
					// try to create the object
					// if it doesn't work, we'll try again
					// if it does work, we'll save a reference to the proper one to speed up future instantiations
					this._Object = new ActiveXObject(versions[i]);

					if (this._Object)
					{
						_ms_XMLHttpRequest_ActiveX = versions[i];
						break;
					}
				}
				catch(objException)
				{
					// trap; try next one
				}
			}
		}
	}
}

Ajax.prototype._Object;
Ajax.prototype.openFunction;
Ajax.prototype.sentFunction;
Ajax.prototype.receivingFunction;
Ajax.prototype.receivedFunction;
Ajax.prototype.failedFunction;

Ajax.prototype.setXml = function(xml)
{
	this._Xml = xml;
}

Ajax.prototype.setOpenFunction = function(func)
{
	this.openFunction = func;
}

Ajax.prototype.setSentFunction = function(func)
{
	this.sentFunction = func;
}

Ajax.prototype.setReceivingFunction = function(func)
{
	this.receivingFunction = func;
}

Ajax.prototype.setReceivedFunction = function(func)
{
	this.receivedFunction = func;
}

Ajax.prototype.setFailedFunction = function(func)
{
	this.failedFunction = func;
}

Ajax.prototype.executeReturn = function(obj)
{
	if(obj._Object.readyState == 1)
	{
		this.openFunction(obj._Object);
	}
	else if(obj._Object.readyState == 2)
	{
		this.sentFunction(obj._Object);
	}
	else if(obj._Object.readyState == 3)
	{
		this.receivingFunction(obj._Object);
	}
	else if(obj._Object.readyState == 4)
	{
		if(obj._Object.status == 200)
		{
			this.receivedFunction(obj._Object);
		}
		else
		{
			this.failedFunction(obj._Object);
		}
		this._Sending = false;
		if(obj._Queue.Length() > 0)
		{
			var runObj = obj._Queue.Pop();
			obj.runNow(runObj);
		}
	}
}

Ajax.prototype.Nothing = function(obj)
{
}

if (!window.Node || !window.Node.ELEMENT_NODE)
{
    var Node = { 	ELEMENT_NODE: 1, ATTRIBUTE_NODE: 2, TEXT_NODE: 3, CDATA_SECTION_NODE: 4, ENTITY_REFERENCE_NODE: 5,
                 	ENTITY_NODE: 6, PROCESSING_INSTRUCTION_NODE: 7, COMMENT_NODE: 8, DOCUMENT_NODE: 9, DOCUMENT_TYPE_NODE: 10, 
    		  		DOCUMENT_FRAGMENT_NODE: 11, NOTATION_NODE: 12 };
}

// Method to get text from an XML DOM object
function getTextFromXML( oNode, deep )
{
	var s = "";
	var nodes = oNode.childNodes;

	for (var i = 0; i < nodes.length; i++)
	{
		var node = nodes[i];

		if(node.nodeType == Node.TEXT_NODE)
		{
			s += node.data;
		}
		else if (deep == true && (node.nodeType == Node.ELEMENT_NODE || node.nodeType == Node.DOCUMENT_NODE || node.nodeType == Node.DOCUMENT_FRAGMENT_NODE))
		{
			s += getTextFromXML(node, true);
		}
	}
    return s;
}

Ajax.prototype.run = function(url, data, method, async, fresh)
{
	var runObj = Array();
	runObj['url'] = url;
	runObj['data'] = data;
	runObj['method'] = method;
	runObj['fresh'] = fresh;
	runObj['async'] = async;

	var obj = this;

	if(this._MultiSend == "A" && this._Sending)
	{
		this._Sending = false;
		this._Object.abort();
	}

	if(this._MultiSend == "B" && this._Sending)
	{
		runObj = null;
	}
	
	this.runNow(runObj);
}

Ajax.prototype.runNow = function(runObj)
{
	var _OpenUrl = runObj['url'];
	
	if (runObj['data'] == null)
		runObj['data'] = '';

	if (runObj != null && this._Sending)
	{
		this._Queue.Push(runObj);
	}
	else if(runObj != null)
	{
		this._Sending = true;

		if (runObj['method'] == "GET")
		{
			if (runObj['fresh'])
			{
				var session = new Date();
				
				if (runObj['data'].length > 0)
				{
					_OpenUrl += '?'+runObj['data'];
				}
				
				if (_OpenUrl.indexOf('?',0))
				{
					_OpenUrl += '&s='+session;
				}
				else
				{
					_OpenUrl += '?s='+session;
				}
			}
			else
			{
				_OpenUrl += '?'+runObj['data'];
			}
			//get rid of data for GET method
			runObj['data'] = '';
		}
		//method POST will always get fresh data
		
		this._Object.open(runObj['method'], _OpenUrl, runObj['async']);		
		
		if (runObj['method'] == 'POST')//set Headers for POST method
		{
			this._Object.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
		}
		
		var obj = this;
		this._Object.onreadystatechange = function()
		{
			obj.executeReturn(obj);
		};
		this._Object.send(runObj['data']);
	}
	else
	{
		alert( "Abort" );
	}
}

Ajax.prototype.setMultiSend = function(ms)
{
	this._MultiSend = ms;
}

function Queue()
{
	this._List = Array();
}
Queue.prototype._List;

Queue.prototype.Push = function(obj)
{
	this._List.push(obj);
}

Queue.prototype.Pop = function()
{
	var obj = null;
	
	if ( this._List.length > 0 )
	{
		var temp = this._List.splice(0,1);
		obj = temp[0];
	}
	return obj;
}

Queue.prototype.Length = function(obj)
{
	return this._List.length;
}

Array.prototype.show=function(header){
  var text = "** "+header+" **\n";
//  for (var i in this){
  for (var i=0;i<this.length;i++){
    text+="["+i+"] => "+this[i]+"\n";
  }
  alert(text);  
}