package com.guru.display.button
{
	import com.guru.call.FunctionCall;
	import com.guru.call.ICall;
	import com.guru.component.clickngrowMenu.ClicknGrowMenu;
	import com.guru.display.LabelMovieClip;
	import flash.display.MovieClip;
	import flash.events.Event;
	import flash.events.MouseEvent;
	
	/**
	 * ...
	 * @author Eddy Lee
	 */
	public class LabelCheckButton
	{
		protected static const LABEL_ENABLE:String = "enable";
		protected static const LABEL_DISABLE:String = "disable";
		protected static const LABEL_NORMAL:String = "normal";
		protected static const LABEL_OVER:String = "over";
		protected static const LABEL_SELECT:String = "select";
		
		protected static const LABEL_ON_NORMAL:String = "onNormal";
		protected static const LABEL_ON_OVER:String = "onOver";
		protected static const LABEL_ON_SELECT:String = "onSelect";
		protected static const LABEL_OFF_NORMAL:String = "offNormal";
		protected static const LABEL_OFF_OVER:String = "offOver";
		protected static const LABEL_OFF_SELECT:String = "offSelect";
		
		protected var mTimeline:MovieClip;
		protected var mIsSelect:Boolean;
		protected var mIsEnable:Boolean;
		protected var mIsVisualDisable:Boolean;
		protected var mDisableControl:LabelMovieClip;
		protected var mContentControl:LabelMovieClip;
		
		protected var mOnCall:ICall;
		protected var mOffCall:ICall;
		
		protected var mPressCall:ICall;
		protected var mPressDoneCall:ICall;
		protected var mOverCall:ICall;
		protected var mOverDoneCall:ICall;
		protected var mOutCall:ICall;
		protected var mOutDoneCall:ICall;
		
		protected var mHitArea:MovieClip;
		protected var mHitDummy:MovieClip;
		
		public function LabelCheckButton(pTimeline:MovieClip) 
		{
			mTimeline = pTimeline;
			var mc:MovieClip = mTimeline.getChildByName("btn_mc") as MovieClip || mTimeline;
			
			if (mc != mTimeline) 
			{
				mDisableControl = new LabelMovieClip(mTimeline, LABEL_ENABLE);
			}
			
			mIsSelect = false;
			
			mContentControl = new LabelMovieClip(mc, LABEL_OFF_NORMAL);
			
			mHitArea = mc.getChildByName("hitArea_mc") as MovieClip || mTimeline.getChildByName("hitArea_mc") as MovieClip || mTimeline;
			mHitArea.addEventListener(MouseEvent.CLICK, onPress, false, 0, true);
			mHitArea.addEventListener(MouseEvent.ROLL_OVER, onOver, false, 0, true);
			mHitArea.addEventListener(MouseEvent.ROLL_OUT, onOut, false, 0, true);
			mHitArea.buttonMode = true;
			addHitDummy();
			
			try 
			{
				enabled = (mDisableControl.getTimeline().currentLabel == LABEL_ENABLE);
			}
			catch (e:Error)
			{
				enabled = true;
			}
			visualDisable = true;
		}
		
		public function check():void
		{
			if (!mIsSelect)
			{
				setSelect(true);
				playToSelect(new FunctionCall(this, onPressDone, mPressDoneCall));
				try 
				{
					mPressCall.execute();
				} catch (e:Error) { }
				
				if(mOnCall != null)
					mOnCall.execute();
			}
		}
		
		public function uncheck():void
		{
			if (mIsSelect)
			{
				setSelect(false);
				playToSelect(new FunctionCall(this, onPressDone, mPressDoneCall));
				try 
				{
					mPressCall.execute();
				} catch (e:Error) { }
				
				if(mOffCall != null)
					mOffCall.execute();
			}
		}
		
		public function setOnCall(pCall:ICall):void
		{
			mOnCall = pCall;
		}
		
		public function setOffCall(pCall:ICall):void
		{
			mOffCall = pCall;
		}
		
		public function getTimeline():MovieClip 
		{
			return (mDisableControl)? mDisableControl.getTimeline() : getInnerTimeline();
		}
		
		public function getInnerTimeline():MovieClip 
		{
			return mContentControl.getTimeline();
		}
		
		public function get enabled():Boolean 
		{
			return mIsEnable;
		}
		
		public function set enabled(pValue:Boolean):void 
		{
			mIsEnable = pValue;
			updateHitArea();
			updateVisualDisable();
		}
		
		public function set visualDisable(pValue:Boolean):void 
		{
			mIsVisualDisable = pValue;
			updateVisualDisable();
		}
		
		public function set useHandCursor(pValue:Boolean):void 
		{
			mHitArea.useHandCursor = pValue;
		}
		
		public function setPressCall(pCall:ICall):void 
		{
			mPressCall = pCall;
		}
		
		public function setPressDoneCall(pCall:ICall):void 
		{
			mPressDoneCall = pCall;
		}
		
		public function setOverCall(pCall:ICall):void 
		{
			mOverCall = pCall;
		}
		
		public function setOverDoneCall(pCall:ICall):void 
		{
			mOverDoneCall = pCall;
		}
		
		public function setOutCall(pCall:ICall):void 
		{
			mOutCall = pCall;
		}
		
		public function setOutDoneCall(pCall:ICall):void 
		{
			mOutDoneCall = pCall;
		}
		
		public function select():void 
		{
			setSelect(true);
			playToSelect();
		}
		
		public function normal():void 
		{
			setSelect(false);
			playToNormal();
		}
		
		public function reset():void 
		{
			enabled = true;
			normal();
		}
		
		public function isChecked():Boolean
		{
			return mIsSelect;
		}
		
		public function onPress(pEvent:MouseEvent = null):void 
		{
			if (mHitArea.mouseEnabled) 
			{
				if (mIsSelect)
					this.uncheck();
				else
					this.check();
			}
		}
		
		public function onOver(pEvent:MouseEvent = null):void 
		{
			if(ClicknGrowMenu.getInstance())
				ClicknGrowMenu.getInstance().enable(false);
			
			if (mHitArea.mouseEnabled) 
			{
				playToOver(mOverDoneCall);
				try 
				{
					mOverCall.execute();
				} catch (e:Error) { }
			}
		}
		
		public function onOut(pEvent:MouseEvent = null):void 
		{
			if(ClicknGrowMenu.getInstance())
				ClicknGrowMenu.getInstance().enable(true);
			
			if (mHitArea.mouseEnabled) 
			{
				playToNormal(mOutDoneCall);
				try 
				{
					mOutCall.execute();
				} catch (e:Error) { }
			}
		}
		
		public function dispose():void 
		{
			removeHitDummy();
			mHitArea.buttonMode = false;
			mHitArea.removeEventListener(MouseEvent.CLICK, onPress);
			mHitArea.removeEventListener(MouseEvent.ROLL_OUT, onOut);
			mHitArea.removeEventListener(MouseEvent.ROLL_OVER, onOver);
			mHitArea = null;
			mTimeline = null;
			
			try 
			{
				mDisableControl.dispose();
			} catch (e:Error) { }
			mDisableControl = null;
			mContentControl.dispose();
			mContentControl = null;
			
			mPressCall = null;
			mPressDoneCall = null;
			mOverCall = null;
			mOverDoneCall = null;
			mOutCall = null;
			mOutDoneCall = null;
			mOnCall = null;
			mOffCall = null;
		}
		
		protected function setSelect(pIsSelect:Boolean):void 
		{
			mIsSelect = pIsSelect;
			updateHitArea();
		}
		
		protected function updateHitArea():void 
		{
			mHitArea.mouseEnabled = mIsEnable;
			mHitArea.mouseChildren = mHitArea.mouseEnabled;
		}
		
		protected function updateVisualDisable():void 
		{
			try 
			{
				mDisableControl.playTo((mIsVisualDisable && !enabled)? LABEL_DISABLE : LABEL_ENABLE);
			} catch (e:Error) { }
		}
		
		protected function playToNormal(pCall:ICall = null):void 
		{
			if(mIsSelect)
				mContentControl.playTo(LABEL_ON_NORMAL, pCall);
			else
				mContentControl.playTo(LABEL_OFF_NORMAL, pCall);
		}
		
		protected function playToOver(pCall:ICall = null):void 
		{
			if(mIsSelect)
				mContentControl.playTo(LABEL_ON_OVER, pCall);
			else
				mContentControl.playTo(LABEL_OFF_OVER, pCall);
		}
		
		protected function playToSelect(pCall:ICall = null):void 
		{
			if(!mIsSelect)
				mContentControl.playTo(LABEL_ON_SELECT, pCall);
			else
				mContentControl.playTo(LABEL_OFF_SELECT, pCall);
		}
		
		protected function onPressDone(pDoneCall:ICall):void
		{
			if(!mIsSelect)
				mContentControl.jumpTo(LABEL_OFF_NORMAL);
			else
				mContentControl.jumpTo(LABEL_ON_NORMAL);
			
			try 
			{
				pDoneCall.execute();
			} catch (e:Error) { }
		}
		
		protected function addHitDummy():void 
		{
			if (mHitArea.stage) 
			{
				mHitArea.addEventListener(Event.ENTER_FRAME, removeHitDummy, false, 0, true);
				mHitDummy = new mHitArea.constructor();
				mHitDummy.transform.matrix = mHitArea.transform.matrix;
				mHitDummy.alpha = 0;
				mHitArea.parent.addChild(mHitDummy);
			}
		}
		
		protected function removeHitDummy(pEvent:Event = null):void 
		{
			try 
			{
				mHitArea.removeEventListener(Event.ENTER_FRAME, removeHitDummy);
				mHitDummy.parent.removeChild(mHitDummy);
				mHitDummy = null;
			} catch (e:Error) { }
		}
	}
}