package com.guru.display.externalLoader 
{
	import com.guru.call.FunctionCall;
	import com.guru.call.ICall;
	/**
	 * ...
	 * @author Eddy Lee
	 */
	public class LoaderQueue
	{
		private static var sInstance:LoaderQueue;
		
		public static function getInstance():LoaderQueue
		{
			if (sInstance == null)
			{
				sInstance = new LoaderQueue();
			}
			
			return sInstance;
		}
		
		private var mStack_array:Array;
		private var mStackSize_num:Number;
		private var mActiveDoneStackCounter_num:Number;
		private var mActiveStackCounter_num:Number;
		private var mActiveStackMaximum_num:Number = 3;
		private var mStackLoadDoneCall:ICall;
		
		public function LoaderQueue()
		{
			mStack_array = new Array();
			mActiveStackCounter_num = 0;
			mActiveDoneStackCounter_num = 0;
		}
		
		public function setDoneCall(pDoneCall:ICall):void
		{
			mStackLoadDoneCall = pDoneCall;
		}
		
		public function cutIntoStack(pLoader:ExternalLoader):void
		{
			for (var i:Number = 0; i < mStack_array.length; i++ )
			{
				if (mStack_array[i] == pLoader)
				{
					mStack_array.splice(i, 1);
					break;
				}
			}
			
			mStack_array.splice(0, 0, pLoader);
		}
		
		public function addToStack(pLoader:ExternalLoader):void
		{
			mStack_array.push(pLoader);
		}
		
		public function setMaxParallel(pMax_num:Number):void
		{
			mActiveStackMaximum_num = pMax_num;
		}
		
		public function reset():void
		{
			while (mStack_array.length > 0)
			{
				mStack_array.shift();
			}
			
			mStackSize_num = 0;
			mActiveStackCounter_num = 0;
			mActiveDoneStackCounter_num = 0;
		}
		
		public function start():void
		{
			mStackSize_num = mStack_array.length;
			
			while (mActiveStackCounter_num < mActiveStackMaximum_num && mStack_array.length > 0)
			{
				this.invokeNextLoaderInStack();
			}
		}
		
		private function invokeNextLoaderInStack():Boolean
		{
			//Logger.eddy("invokeNextLoaderInStack: " + mStack_array.length);
			if (mStack_array.length > 0)
			{
				mActiveStackCounter_num++;
				var loader:ExternalLoader = mStack_array.shift();
				loader.setStackLoadDone(new FunctionCall(this, onLoaderLoadDone, loader));
				loader.setStackLoadFail(new FunctionCall(this, onLoaderLoadDone, loader));
				if (PhotoCache.getInstance().hasBMPData(loader.getPath()))
				{
					loader.loadBitmapData(PhotoCache.getInstance().getBMPData(loader.getPath()));
				}
				else
				{
					loader.load();
				}
				
				return true;
			}
			
			return false;
		}
		
		private function onLoaderLoadDone(pLoader:ExternalLoader):void
		{
			mActiveStackCounter_num--;
			mActiveDoneStackCounter_num++;
			
			if(!this.invokeNextLoaderInStack())
			{
				if (mStackLoadDoneCall != null)
				{
					mStackLoadDoneCall.execute();
					mStackLoadDoneCall = null;
				}
				this.reset();
			}
		}
	}

}