/**
 * Singleton object responsible for the invocation and of data requests.
 * The requests are added to a FIFO and executed sequencially one at a time.
 * May be useful to allow paralelism.
 */
DataRequester = function () {}

//The list with the current request (at 0) and all pending requests.
DataRequester.pending = new Array();

//A flag to indicate if the requester is processing a request.
DataRequester.busy = false;

//Timeout used to check if the request has been satisfied.
DataRequester.timerInterval = 100;

//Number of request completion tests to execute before fail.
DataRequester.maxAttempts = 600;

//Current request completion test number.
DataRequester.currentAttempt = 0;

/**
 * Returns the request being executed or the next request to execute
 * (if there is no request being executed)
 */
DataRequester.getCurrentRequest = function ()
{
	var request = null;
	if (DataRequester.pending.length > 0)
	{
		request = DataRequester.pending[0];
	}
	return request;
}

/**
 * Pops the first request of the pending request list.
 */
DataRequester.popCurrentRequest = function ()
{
	DataRequester.pending = DataRequester.pending.slice(1);
}

/**
 * Adds a request to the pending list. If this request is the the first of the
 * list and the requester is not busy, the service is executed.
 */
DataRequester.execute = function (request)
{
	DataRequester.pending.push(request);
	if (DataRequester.getCurrentRequest() == request
		&& DataRequester.busy == false)
	{
		DataRequester.executeFirst();
	}
}

/**
 * Executes the first service of the list.
 */
DataRequester.executeFirst = function()
{
	DataRequester.busy = true;
	DataRequester.currentAttempt = 0;
	var request = DataRequester.getCurrentRequest();
	
	//alert(request.getUrl());
	
	document.getElementById("dataReq_dataRequester").src = request.getUrl();
	var message = document.getElementById("dataReq_dataRequesterMessageBox");
	message.style.display = "block";
	
	setTimeout("DataRequester.checkLoadState();", DataRequester.timerInterval);
}

/**
 * Check if the current request has been satisfied. If it hasn't and we haven't
 * reached the maximum number of tests, we set a timeout to check later. If we
 * have reached the maximum number of tests, the request is canceled and the
 * user notified. If we have a result, the onDone function of the request is
 * invoked and the next request is executed.
 */
DataRequester.checkLoadState = function ()
{
	if (DataRequester.getCurrentRequest().getResult() == null)
	{
		if (DataRequester.currentAttempt > DataRequester.maxAttempts)
		{
			var request = DataRequester.getCurrentRequest();
			DataRequester.popCurrentRequest();
			var message = document.getElementById("dataReq_dataRequesterMessageBox");
			message.style.display = "none";
			DataRequester.busy = false;
			//alert("Request timed out. URL: " + request.getUrl());
			alert ("Problem loading page. Please try refresh");
			
			DataRequester.onError(request);
		}
		else
		{
			DataRequester.currentAttempt += 1;
			setTimeout("DataRequester.checkLoadState();", DataRequester.timerInterval);
			return;
		}
	}
	else
	{
		var request = DataRequester.getCurrentRequest();
		var message = document.getElementById("dataReq_dataRequesterMessageBox");
		
		//alert(request.getResult());
		
		DataRequester.onDone(request);
		message.style.display = "none";
		DataRequester.popCurrentRequest();
		DataRequester.busy = false;
	}
	if (DataRequester.getCurrentRequest() != null)
	{
		DataRequester.executeFirst();
	}
}

/**
 * Invokes the onDone function of the request.
 */
DataRequester.onDone = function (request)
{
	var invokeFunction = request.getOnDoneFunction();
	if (invokeFunction != null)
	{
		invokeFunction.run();
	}
}

/**
 * Invokes the onError function of the request.
 */
DataRequester.onError = function (request)
{
	var invokeFunction = request.getOnErrorFunction();
	if (invokeFunction != null)
	{
		invokeFunction.run();
	}
}
