/***************************************************************************
	List of member functions of the dataFrame object:
	
		setDataFrame(fraData) - sets the window object of the data frame
		getDataFrame() - gets the window object of the data frame
		addTask(url) - adds a URL to the data frame queue. It is executed when
					   the queue is idle.
		cancelTask(urlToken) - frees a task previously added to the queue.
		   			           The urlToken substring is searched for, and each matching
						       task is cancelled, including the current one, if matched.
						       However, it does not prevent the current page of the data
						       frame to be loaded in this case.
		releaseDataFrame() - must be called from each callback function of the data frame.
							 Notifies that the current task was completed. It passes
							 to the next task in the queue if there are any pending tasks.
****************************************************************************/
function dataFrame(fraData)
{
	// External functions
	this.setDataFrame = dataFrame_setDataFrame;
	this.getDataFrame = dataFrame_getDataFrame;
	this.addTask = dataFrame_addTask;
	this.cancelTask = dataFrame_cancelTask;
	this.release = dataFrame_release;
	this.setWaiting = dataFrame_setWaiting;
	this.clearWaiting = dataFrame_clearWaiting;
	
	// Internal functions
	this.executeTask = dataFrame_executeTask;
	
	// Callback functions
	this.onExecuteTask = null;

	// Member variables
	this.fraData = fraData;
	this.bAvail = true;
	this.curURL = "";
	this.URLQueue = new Array();
	
	this.busyStatusMsg = "";
	this.idleStatusMsg = "";
	this.waitingElement = null;
	this.waitingPrevCursor = null;
}

function dataFrame_setDataFrame(fraData)
{ this.fraData = fraData; }

function dataFrame_getDataFrame()
{ return this.fraData; }

function dataFrame_executeTask(url)
{
	if (typeof(this.onExecuteTask) == "function")
		this.onExecuteTask(url);
	else if (this.fraData != null)
		this.fraData.location.replace(url);
	// TODO: if the browser does not support location.replace, switch to location.href
}

function dataFrame_addTask(url)
{
	if( typeof(EP_NoCache) != "undefined" &&
		EP_NoCache != "" )
		url += "&NoCache=" + EP_NoCache ;
		
	if (this.bAvail) {
		this.bAvail = false;
		if (this.busyStatusMsg)
			window.status = this.busyStatusMsg;
		this.executeTask(url);
		this.curURL = url;
		//if (this.busyStatusMsg)
		//	window.status = this.busyStatusMsg;
	} else {
		this.URLQueue.push(url);
	}
}

function dataFrame_cancelTask(urlToken, idleURL)
{
	if (!this.bAvail) {
		for (i=0; i<=this.URLQueue.length-1; i++)
			if (this.URLQueue[i].indexOf(urlToken) != -1)
				this.URLQueue.splice(i, 1);
		
		if (this.curURL.indexOf(urlToken) != -1) {
			this.release();
			if (idleURL != null)
				this.executeTask(idleURL);
		}
	}
}

function dataFrame_release()
{
	this.clearWaiting();

	if (this.URLQueue.length > 0) {
		var newURL = this.URLQueue.shift();
		this.executeTask(newURL);
		this.curURL = newURL;
		this.bAvail = false;
	} else {
		this.bAvail = true;
		if (this.busyStatusMsg)
			window.status = this.idleStatusMsg;
	}
}

function dataFrame_setWaiting(elemContainer)
{
	this.waitingElement = elemContainer;
	if (this.waitingElement)
	{
		this.waitingPrevCursor = this.waitingElement.style.cursor;
		this.waitingElement.style.cursor = "wait";
	}
	else
		this.waitingPrevCursor = null;
}

function dataFrame_clearWaiting()
{
	if (this.waitingElement)
		this.waitingElement.style.cursor = this.waitingPrevCursor;
	this.waitingElement = null;
	this.waitingPrevCursor = null;
}
