//-------------------------------------------------------------------
//-------------------------------------------------------------------
//---------------------- GENERIC AJAX SCRIPT ------------------------
//-------------------------------------------------------------------
//-------------------------------------------------------------------

function CreateXHR()
{
   try { return new XMLHttpRequest(); } catch(e) {} 
   try { return new ActiveXObject("Msxml2.XMLHTTP.6.0"); } catch (e) {} 
   try { return new ActiveXObject("Msxml2.XMLHTTP.3.0"); } catch (e) {} 
   try { return new ActiveXObject("Msxml2.XMLHTTP"); } catch (e) {} 
   try { return new ActiveXObject("Microsoft.XMLHTTP"); } catch (e) {} 
   return null; 
}
        
var XHRList = new Array(15);
var XHRInitialized = false;
var sanity = 0;


function GetXHR(thecaller)
{

	return CreateXHR();

/*	if (!XHRInitialized)
		{
		XHRInitialized=true;
		for (i=0;i<10;i++)
				{
				x = CreateXHR();
				XHRList[i]=x;
				if (XHRList[i]==null)
					{
					alert("failed to create XHR");
					}
				else
					{
					out=out+"created XHR"+i+"    ";
					}
				XHRList[i].onreadystatechange = null;
				}
		}
	else
		{
		}

	// simple frst pass - issue first available XHR from list


	i=0;
	for (i=0;i<10;i++)
	{
		if (XHRList[i].onreadystatechange == null)	
		{
		return XHRList[i];
		}
	}
	alert("couldn't find a prealloc");
	*/
}


nAjaxCallsQueued = 0;
var xmlArray = new Array();
var xmlIDS = new Array();
AjaxCallsRunning = 0;

function PriorityQueueAjaxCall(xmlHttp, theID)
{
	for (i=nAjaxCallsQueued; i>0;i--)
		{
		xmlIDS[i]=xmlIDS[i-1];
		xmlArray[i]=xmlArray[i-1];	
		}
	xmlIDS[0]=theID;
	xmlArray[0]=xmlHttp;	
	nAjaxCallsQueued++;
	PopAjaxQueue();	
}

function QueueAjaxCall(xmlHttp, theID)
{
//	console.log("(QueueAjaxCall) Queueing..."+nAjaxCallsQueued+" items in queue before call");
	xmlIDS[nAjaxCallsQueued]=theID;
	xmlArray[nAjaxCallsQueued++]=xmlHttp;	// Assumes this implementation of Javascript is not multithreaded.  Safe in 3/09.
//	console.log("(QueueAjaxCall) Queued..."+nAjaxCallsQueued+" items in queue after addition");
//	console.log("(QueueAjaxCall) Attempting to pop the queue");	
//	console.log("Queue is "+nAjaxCallsQueued+" deep.");
	PopAjaxQueue();							// try to run the top of queue item
}

function AjaxCallComplete()					// Assumes this implementation of Javascript is not multithreaded.  Safe in 3/09.
{
	AjaxCallsRunning--;
//	console.log("(AjaxCallComplete) A call completed.  I think there are currently "+AjaxCallsRunning+" call(s) running");
//	console.log("(AjaxCallComplete) I think there are currently "+nAjaxCallsQueued+" call(s) in the Queue");
	PopAjaxQueue();							// Launch someone waiting - if they are
}

function PopAjaxQueue()						// Assumes this implementation of Javascript is not multithreaded.  Safe in 3/09.
{
//	console.log("(PopAjax) PopAjax queue sees "+nAjaxCallsQueued+" calls in the queue");
//	console.log("(PopAjax) PopAjax queue sees "+AjaxCallsRunning+" call(s) currently running");
	if (AjaxCallsRunning==0)
		{
		if (nAjaxCallsQueued>0)
			{
//			if (nAjaxCallsQueued>1)
//				console.log("PopQueue sees multiple queue entries!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
			AjaxCallsRunning++;
//			console.log("PopQueue is launching a task");
			xmlArray[0].send(null);
			for (i=0;i<nAjaxCallsQueued-1; i++)		// slide all of the pending requests down the queue
				{
				xmlArray[i]=xmlArray[i+1];
				xmlIDS[i]=xmlIDS[i+1];
				}
			nAjaxCallsQueued--;
			}
		}
	else
		{
//		console.log("(PopAjax) PopAjax is exiting without launching a task");
		}
}


function CallAjax(theScript,theReturnFunc,maxInQueue,isPriority)
{
	var xmlHttp;
//	alert(document.location);
	
	if(theScript.indexOf("?") == -1)
	{
		theScript += "?c="+(parseInt(10000*Math.random()));
	}
	else
	{
		theScript += "&c="+(parseInt(10000*Math.random()));
	}
	
	if (maxInQueue>0)
		{		// dont queue up calls greater than their maximum
		for (i=0;i<nAjaxCallsQueued; i++)
			{
			if (xmlIDS[i]==theReturnFunc)
				{								// this function is already queued up
//				console.log("discard!");
				return;
				}
			}
		}

	xmlHttp = GetXHR(theScript);
	if (!xmlHttp) 
		{
		alert("failed to allocate xml Header");
		return;
		}
	//alert("calling "+theScript);
	
	xmlHttp.open("GET",theScript,true);		// this must appear before the function assignment
	xmlHttp.onreadystatechange=function()	// or the xmlHttp header can not be recycled :(
    {
		if(xmlHttp.readyState==4)
		{
			theReturnFunc(xmlHttp);
			AjaxCallComplete();
			if(!window.XMLHttpRequest=="undefined")
			{
				xmlHttp.onreadystatechange=null;
			}
			xmlHttp=null;
		}
    }
	if (isPriority)
		{
		PriorityQueueAjaxCall(xmlHttp, theReturnFunc);
		}
	else
		{
		QueueAjaxCall(xmlHttp, theReturnFunc);
		}
}

