package com.guru.event
{
	import com.guru.call.*;
	import com.guru.utils.*;
	import com.guru.event.*;

	public class SimpleEventDispatcher
	{
		private var mAllEvent_array:Array = null;
		private var mEventAddCallback_array:Array = null;
		private var mEventRemoveCallback_array:Array = null;

		public function SimpleEventDispatcher()
		{
			mAllEvent_array = new Array();
			mEventAddCallback_array = new Array();
			mEventRemoveCallback_array = new Array();
		}
		
		public function dispose():void
		{
			mAllEvent_array = null;
			mEventAddCallback_array = null;
			mEventRemoveCallback_array = null;
		}

		public function addEventListener(pType_str:String, pListener:EventCall):void
		{
			if ( !isValidEventType(pType_str) )
			{
				//trace("error on event type");
				return ;
			}

			if ( !isValidEventCall(pListener) )
			{
				//trace("error on event listener");
				return ;
			}
			
			if ( mAllEvent_array[pType_str] === undefined )
			{
				mAllEvent_array[pType_str] = new Array();
				if(mEventAddCallback_array[pType_str] != null)
				{
					mEventAddCallback_array[pType_str].execute();
				}
			}
			if( !ArrayUtil.contains(mAllEvent_array[pType_str],pListener) )
			{
				mAllEvent_array[pType_str].push(pListener);
			}
		}

		public function removeEventListener(pType_str:String,pListener:EventCall):void
		{
			if ( !isValidEventType(pType_str) )
			{
				//trace("error on event type");
				return ;
			}

			if ( !isValidEventCall(pListener) )
			{
				//trace("error on event listener");
				return ;
			}
			ArrayUtil.remove(mAllEvent_array[pType_str],pListener);
			
			try{
				if ( mAllEvent_array[pType_str].length == 0 )
				{
					mAllEvent_array[pType_str] = null;
					delete mAllEvent_array[pType_str];
					if(mEventRemoveCallback_array[pType_str] != null)
					{
						mEventRemoveCallback_array[pType_str].execute();
					}
				}
			}
			catch(pError:TypeError) {}
		}
		
		public function removeListener(pScope_obj:Object):void
		{
			for ( var eventType_str:String in mAllEvent_array)
			{
				var event_array:Array = mAllEvent_array[eventType_str].concat();

				for ( var i in event_array )
				{
					if ( event_array[i].isScore(pScope_obj) )
					{
						removeEventListener(eventType_str,event_array[i]);
					}
				}
			}
		}
		
		public function removeAllListener():void
		{
			mAllEvent_array = new Array();
		}
		
		public function addEventCallback(pType_str:String,pAddCall:ICall = null,pRemoveCall:ICall = null):void
		{
			if ( !isValidEventType(pType_str) )
			{
				//trace("error on event type");
				return ;
			}

			mEventAddCallback_array[pType_str] = pAddCall;
			mEventRemoveCallback_array[pType_str] = pRemoveCall;
		}

		public function dispatchEvent(pEvent:CusEvent = null):void
		{
			if (pEvent.getTarget() == null)
			{
				pEvent.setTarget(this);
			}
			var event_array:Array = mAllEvent_array[pEvent.getType()];

			for ( var i in event_array )
			{
				event_array[i].setEvent(pEvent);
				if(event_array[i] != null)
				{
					event_array[i].execute();
				}
			}
		}

		public function dispatchEventLater(pEvent:CusEvent):void
		{
			TimerUtil.setDelay(0.01, new FunctionCall(this, dispatchEvent, pEvent));
		}

		public function hasEventListener(pType_str:String):Boolean
		{
			var event_array:Array = mAllEvent_array[pType_str];

			if ( event_array.length > 0 )
			{
				return true;
			}
			return false;
		}

		public function toString():String
		{
			return "SimpleEventDispatcher";
		}
		
		private function isValidEventCall(pListener:EventCall = null):Boolean
		{
			if ( pListener == null )
			{
				return false;
			}

			return true;
		}
		
		private function isValidEventType(pType_str:String = null):Boolean
		{
			if ( pType_str == null )
			{
				return false;
			}
			
			if (pType_str.length <= 0)
			{
				return false;
			}

			return true;
		}
	}
}