package com.guru.section 
{
	import com.guru.call.FunctionCall;
	import com.guru.call.ICall;
	import com.guru.event.EventCall;
	import com.guru.event.SimpleEventDispatcher;
	import com.guru.utils.ArrayUtil;
	import com.guru.utils.TraceUtil;
	import flash.display.Loader;
	import flash.display.MovieClip;
	import flash.events.Event;
	import flash.events.EventDispatcher;
	import flash.net.URLRequest;
	/**
	 * ...
	 * @author Eddy Lee
	 */
	public class Section
	{
		private static var sInstance:Section
		private static var sStepFadeOutCall:ICall;
		
		private static function getInstance():Section
		{
			if(sInstance == null)
			{
				sInstance = new Section();
			}
			return sInstance;
		}
		
		public static function setStepFadeOutCall(pCall:ICall):void
		{
			sStepFadeOutCall = pCall;
		}
		
		public static function removeEventListener(pType_str:String, pListener:EventCall):void
		{
			getInstance().doRemoveEventListener(pType_str, pListener);
		}
		
		public static function addEventListener(pType_str:String, pListener:EventCall):void
		{
			getInstance().doAddEventListener(pType_str, pListener);
		}
		
		public static function changeSection(pIndex_str:String, pData_obj:Object = null):void
		{
			if (sStepFadeOutCall != null)
			{
				trace("EXECUTE stepFadeOutCall!");
				sStepFadeOutCall.execute(new FunctionCall(getInstance(), getInstance().doChangeSection, pIndex_str, pData_obj));
			}
			else
			{
				getInstance().doChangeSection(pIndex_str, pData_obj);
			}
		}
		
		public static function getSectionContent(pIndex_str:String):void
		{
			getInstance().doGetSectionContent(pIndex_str);
		}
		
		public static function createMovieClipSection(pIndex_str:String, pMovieClipSection_mc:MovieClip):void
		{
			getInstance().doCreateMovieClipSection(pIndex_str, pMovieClipSection_mc);
		}
		
		public static function createSwfSection(pIndex_str:String, pSwfName_str:String, pContainer_mc:MovieClip, pLoading_mc:MovieClip):void
		{
			getInstance().doCreateSwfSection(pIndex_str, pSwfName_str, pContainer_mc, pLoading_mc);
		}
		
		public static function getCurrentSectionName():String
		{
			return getInstance().doGetCurrentSectionName()
		}
		
		private var mSection_array:Array;
		private var mNextSectionName_str:String;
		private var mCurrentSectionName_str:String;
		private var mEventDispatcher:SimpleEventDispatcher;
		private var mBusy_bol:Boolean;
		private var mSectionLoader:Loader;
		
		public function Section()
		{
			mBusy_bol = false;
			mSection_array = new Array();
			mEventDispatcher = new SimpleEventDispatcher();
		}
		
		private function doGetCurrentSectionName():String
		{
			return mCurrentSectionName_str;
		}
		
		private function doCreateMovieClipSection(pIndex_str:String, pMovieClipSection_mc:MovieClip):void
		{
			if (!ArrayUtil.containsId(mSection_array, pIndex_str))
			{
				mSection_array[pIndex_str] = new MovieClipSection(pIndex_str, pMovieClipSection_mc);
			}
			else
			{
				trace("WARNING! Section \""+pIndex_str+"\" already exist!");
			}
		}
		
		private function doCreateSwfSection(pIndex_str:String, pSwfName_str:String, pContainer_mc:MovieClip, pLoading_mc:MovieClip):void
		{
			if (!ArrayUtil.containsId(mSection_array, pIndex_str))
			{
				mSection_array[pIndex_str] = new SwfSection(pIndex_str, pSwfName_str, pContainer_mc, pLoading_mc);
			}
			else
			{
				trace("WARNING! Section \""+pIndex_str+"\" already exist!");
			}
		}
		
		private function doChangeSection(pIndex_str:String, pData_obj:Object = null):void
		{
			//if (mCurrentSectionName_str != pIndex_str)
			{
				if (!mBusy_bol)
				{
					mBusy_bol = true;
					mNextSectionName_str = pIndex_str;
					mEventDispatcher.dispatchEvent(new SectionEvent(SectionEvent.DEACTIVE_START));
					
					if (mCurrentSectionName_str != null)
						SectionBase(this.getCurrentSection()).fadeOut(new FunctionCall(this, fadeOutCurrentSectionDone, pData_obj));
					else
						this.fadeOutCurrentSectionDone(pData_obj);
				}
			}
		}
		
		private function hasCurrentSection():Boolean
		{
			if (!ArrayUtil.containsId(mSection_array, mCurrentSectionName_str))
			{
				trace("WARNING! Section \""+mCurrentSectionName_str+"\" does not exist!");
				return false;
			}
			
			return true;
		}
		
		private function getCurrentSection():SectionBase
		{
			return mSection_array[mCurrentSectionName_str];
		}
		
		private function fadeOutCurrentSectionDone(pData_obj:Object = null):void
		{
			sStepFadeOutCall = null;
			
			if (mCurrentSectionName_str != null)
			{
				this.getCurrentSection().dispose();
				
				mEventDispatcher.dispatchEvent(new SectionEvent(SectionEvent.DEACTIVE_DONE));
			}
			
			mCurrentSectionName_str = mNextSectionName_str;
			mNextSectionName_str = null;
			
			if (this.hasCurrentSection())
				this.readyNextSection(new FunctionCall(this, activeNextSection, pData_obj));
		}
		
		private function readyNextSection(pDoneCall:ICall):void
		{
			if (this.getCurrentSection() is MovieClipSection)
			{
				pDoneCall.execute();
			}
			else if (this.getCurrentSection() is SwfSection)
			{
				SwfSection(this.getCurrentSection()).loadSwf(pDoneCall);
			}
		}
		
		private function activeNextSection(pData_obj:Object = null):void
		{
			try
			{
				SectionBase(this.getCurrentSection()).getTimeline().setDataObj(pData_obj);
			}
			catch (e)
			{
				trace("Section " + getCurrentSectionName() + " does not have SET_DATA_OBJ function");
			}
			SectionBase(this.getCurrentSection()).fadeIn(new FunctionCall(this, onActiveDone));
			mEventDispatcher.dispatchEvent(new SectionEvent(SectionEvent.ACTIVE_START));
		}
		
		private function onActiveDone():void
		{
			mEventDispatcher.dispatchEvent(new SectionEvent(SectionEvent.ACTIVE_DONE));
			mBusy_bol = false;
		}
		
		private function doGetSectionContent(pIndex_str:String):MovieClip
		{
			if (ArrayUtil.containsId(mSection_array, pIndex_str))
			{
				return mSection_array[pIndex_str];
			}
			else
			{
				trace("WARNING! Section does not exist!");
			}
			return null;
		}
		
		private function doRemoveEventListener(pType_str:String, pListener:EventCall):void
		{
			mEventDispatcher.removeEventListener(pType_str, pListener);
		}
		
		private function doAddEventListener(pType_str:String, pListener:EventCall):void
		{
			mEventDispatcher.addEventListener(pType_str, pListener);
		}
	}

}