Ext.namespace("MicroPacific.Util");

var MpAsynchExecQueue = function()
{
	var mpaeq;
	
	return {
		GetAsynchExecQueue:function()
		{
			if (mpaeq == null) { mpaeq = new MicroPacific.Util.MpAsynchExecQueue(); }
			
			return mpaeq;
		}
	}
}();

MicroPacific.Util.MpAsynchExecQueue = function()
{
	// MDR 30/08/2007 - ExecObject: { ScopeObject, fnCallback, fnErrorCallback }
	this.dsqExecObjects = new MicroPacific.Data.DelayedShiftQueue();
	this.bExecInProgress = false;
	
	this.oCalleeScope = null;
	this.fnCalleeCallback = null;
	this.fnErrorCallback = null;
	
	this.ProcessQueue = function()
	{
		//console.log("Process Queue: " + this.Length() + ", " + this.bExecInProgress);
		
		if (this.bExecInProgress) return;
		
		this.bExecInProgress = true;
		
		if (this.dsqExecObjects.Length() == 0) { this.bExecInProgress = false; return; }
		
		var eoExecObject = this.dsqExecObjects.Dequeue();
		
		//console.log("Exec: " + eoExecObject.Scope.op);
		
		// MDR - 30/08/2007 - We assume that ScopeObject.fnCallback accepts us as the callback, if not things will freeze
		var _mpaeq = this;
		
		// MDR 30/08/2007 - Set the callee's callback function, we will call it once we are called (AsyncCallCallback)
		this.oCalleeScope = eoExecObject.CalleeScope;
		this.fnCalleeCallback = eoExecObject.fnCallback;
		this.fnErrorCallback = eoExecObject.fnErrorCallback;
		
		// MDR 30/08/2007 - Now get the process running
		eoExecObject.fnAsyncFunction.call(eoExecObject.Scope, _mpaeq, this.AsyncCallCallback, this.ErrorCallback);
	}
	
	this.AsyncCallCallback = function()
	{
		 // MDR 30/08/2007 - Caller will provide null for all but last operation
		if (this.fnCalleeCallback)
		{
			this.fnCalleeCallback.call(this.oCalleeScope, false);
		}
		this.bExecInProgress = false;
		this.ProcessQueue();
	}
	
	this.ErrorCallback = function(error)
	{
		//alert("MpAsynchExecQueue, someerror: " + error.ToString());
		// MDR 06/09/2007 - Not sure why this works different to AsyncCallCallback, but it seems as if this function
		//					is called with an initial scope of oCalleeScope
		this.fnErrorCallback.call(this.oCalleeScope, error);
		this.bExecInProgress = false;
		this.ProcessQueue();
	}
	
	this.Append = function(eoExecObject)
	{
		// MDR 30/08/2007 - ExecObject: { Scope, fnAsyncFunction, CalleeScope, fnCallback, fnErrorCallback }
		//console.log("Append: " + eoExecObject.Scope.op);
		this.dsqExecObjects.Enqueue(eoExecObject);
		this.ProcessQueue();
	}
	
	this.Length = function()
	{
		return this.dsqExecObjects.Length();
	}
};