var Ajax = {
	state      : ['uninitialized', 'loading', 'loaded', 'interactive', 'complete'],
	httpStack  : new Array(),
	canProcess : true,
	obj        : null,
	timeout    : 500000, //Seconds
	timer      : 0,
	
	setTimeOut : function (pTimer) {
		Ajax.timeout = pTimer;
	},
	
	loadObject : function () {
		try { Ajax.obj = new ActiveXObject("Msxml2.XMLHTTP"); }
		catch (e)
		{
			try {Ajax.obj = new ActiveXObject("Microsoft.XMLHTTP"); }
			catch (oc) { Ajax.obj = null; }
		}
		if(!Ajax.obj && typeof XMLHttpRequest != "undefined")
			Ajax.obj = new XMLHttpRequest();
		
		return;
	},
	
	processResponse : function () {
		if(Ajax.httpStack.length==0) {
			Ajax.canProcess = true;
			return;
		}
		//try {
			if(typeof Ajax.httpStack[0] != 'undefined' &&
			   typeof Ajax.httpStack[0]['waiting'] != 'undefined' &&
					  Ajax.httpStack[0]['waiting'] != null &&
					  Ajax.httpStack[0]['waiting'] != '')
			{
				if(Ajax.httpStack[0]['waiting'].fn)
					eval(Ajax.httpStack[0]['waiting'].fn+"(Ajax.obj.readyState, Ajax.httpStack[0]['waiting'].params)");
			}
			
			if (Ajax.state[Ajax.obj.readyState] != 'complete') 
				return;
			
			if(typeof Ajax.httpStack[0] != 'undefined' &&
			   typeof Ajax.httpStack[0]['callback'] != 'undefined' &&
					  Ajax.httpStack[0]['callback'] != null &&
					  Ajax.httpStack[0]['callback'] != '')
			{			
				if(Ajax.httpStack[0]['callback'].fn)
					eval(Ajax.httpStack[0]['callback'].fn+"((Ajax.obj.responseXML ? Ajax.obj.responseXML.documentElement : null), Ajax.obj.responseText, Ajax.obj.status, Ajax.httpStack[0]['callback'].params)")
			}
			
			Ajax.httpStack.shift();
			Ajax.clearTimer();
			
			if (Ajax.httpStack.length > 0) Ajax.processNextRequest();
			else Ajax.canProcess = true;
		/*}
		catch (o) { 
			jsLog("Catch: "+o)
			Ajax.httpStack.shift();
			Ajax.clearTimer();
		}*/
	},
	
	clearTimer : function () {
		clearTimeout(Ajax.timer);
		Ajax.timer = 0;
	},
	
	abortProcess : function () {
		Ajax.obj.abort();
		if(typeof Ajax.httpStack[0] != 'undefined' &&
		   typeof Ajax.httpStack[0]['callback'] != 'undefined' &&
				  Ajax.httpStack[0]['callback'] != null &&
				  Ajax.httpStack[0]['callback'] != '')
		{
			eval(Ajax.httpStack[0]['callback'].fn+"(null, '', 408, Ajax.httpStack[0]['callback'].params)");
		}
		Ajax.httpStack.shift();
	},
	
	processNextRequest : function () {
		Ajax.loadObject();

		var request = Ajax.httpStack[0];
		Ajax.obj.onreadystatechange = Ajax.processResponse;

		try {
			Ajax.obj.open(request['method'], request['url'], request['async']);

			if(request['ha']) 
				Ajax.obj.setRequestHeader(request['ha'], request['hv']);
			
			if (!request['content'] || request['content'] == null || request['content'].length == 0) 
				Ajax.obj.send(null);
			else {
				if(request['xml']) 
					Ajax.obj.setRequestHeader('Content-Type', 'text/xml');
				else 
					Ajax.obj.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
					
				Ajax.obj.send(request['content']);
			}
			
			if(Ajax.timer == 0)
				Ajax.timer = setTimeout('Ajax.abortProcess()', Ajax.timeout);
		}
		catch(o) {
			Ajax.httpStack.shift();
			Ajax.clearTimer();
			
		}
	},
	
	loadXMLDoc : function (pUrl, pContent, pMethod, pCallback, pAsync, pWaiting, pXML, pHa, pHv) {
		Ajax.canProcess = false;
		
		if (!pAsync) {
			Ajax.processSyncRequest(pUrl, pContent, pMethod);
			return;
		}
		
		var request         = new Array;
		request['url']      = pUrl;
		request['content']  = pContent;
		request['method']   = pMethod;
		request['callback'] = pCallback;
		request['waiting']  = pWaiting;
		request['async']    = pAsync;
		
		request['xml']      = pXML;
		request['ha']       = pHa; // Header Attribute
		request['hv']       = pHv; // Header Value

		
		Ajax.httpStack.push(request);
		request = null;
		if (Ajax.httpStack.length == 1)
			Ajax.processNextRequest();
	}
}