package com.guru.component.pagination
{
	import caurina.transitions.Tweener;
	import com.guru.call.FunctionCall;
	import com.guru.call.ICall;
	import com.guru.display.button.LabelButton;
	import com.guru.display.button.LabelDragButton;
	import com.guru.display.Text;
	import com.guru.utils.Delegate;
	import flash.display.MovieClip;
	import flash.geom.Rectangle;
	/**
	 * ...
	 * @author Eddy Lee
	 */
	public class SlidingPagination implements IPagination
	{
		private var mTimeline_mc:MovieClip;
		private var mPrevBtn:LabelButton;
		private var mNextBtn:LabelButton;
		private var mDragBtn:LabelDragButton;
		private var mDragTrackBtn:LabelButton;
		private var mCurrentPage:Text;
		private var mTotalPage:Text;
		private var mTotalPage_num:Number;
		private var mCurrentPage_num:Number;
		private var mSlideDuration_num:Number;
		private var mChangePageCall:ICall;
		
		public function SlidingPagination(pTimeline_mc:MovieClip, pSlideDuration_num:Number = 10)
		{
			mTimeline_mc = pTimeline_mc;
			mSlideDuration_num = pSlideDuration_num;
			
			mDragTrackBtn = new LabelButton(mTimeline_mc.dragTrackBtn_mc);
			mPrevBtn = new LabelButton(mTimeline_mc.prevBtn_mc);
			mNextBtn = new LabelButton(mTimeline_mc.nextBtn_mc);
			mDragBtn = new LabelDragButton(mTimeline_mc.dragBtn_mc);
			mCurrentPage = new Text(mTimeline_mc.currentPage_mc);
			mTotalPage = new Text(mTimeline_mc.totalPage_mc);
			
			mDragBtn.setDragableArea(new Rectangle(mDragTrackBtn.getTimeline().x, mDragTrackBtn.getTimeline().y, mDragTrackBtn.getTimeline().width, 0));
			mDragBtn.setDragStopCall(new FunctionCall(this, onDragStop));
			mDragBtn.setDraggingCall(new FunctionCall(this, onDragging));
			
			mDragTrackBtn.setPressCall(new FunctionCall(this, onDragTrackBtnPress));
			
			mNextBtn.setPressCall(new FunctionCall(this, onNextBtnPress));
			mPrevBtn.setPressCall(new FunctionCall(this, onPrevBtnPress));
			
			this.tweenDragBtnTo(mDragTrackBtn.getTimeline().x, null, true);
			this.reset();
		}
		
		public function dispose():void
		{
			mPrevBtn.dispose();
			mNextBtn.dispose();
			mDragBtn.dispose();
			mDragTrackBtn.dispose();
			mCurrentPage.dispose();
			mTotalPage.dispose();
		}
		
		public function getTotalPage():Number
		{
			return mTotalPage_num;
		}
		
		public function getCurrentPage():Number
		{
			return mCurrentPage_num;
		}
		
		public function setChangePageCall(pCall:ICall):void
		{
			mChangePageCall = pCall;
		}
		
		public function setTotalPage(pValue_num:Number):void
		{
			mTotalPage_num = pValue_num;
		}
		
		public function gotoPage(pValue_num:Number, pDoneCall:ICall = null):void
		{
			if (mTotalPage_num > 0)
			{
				var targetPage_num:Number = Math.min(Math.max(pValue_num, 1), mTotalPage_num);
				if (targetPage_num != mCurrentPage_num)
				{
					mCurrentPage_num = targetPage_num;
					this.refresh(pDoneCall);
				}
				else
				{
					this.tweenDragBtnTo(this.getCoordinateFromPage(mCurrentPage_num), new FunctionCall(this, onRefreshDone, pDoneCall));
				}
			}
			else
			{
				this.reset();
				
				if(pDoneCall)
					pDoneCall.execute();
			}
		}
		
		public function reset():void
		{
			mTotalPage_num = 0;
			mCurrentPage_num = 0;
			mTotalPage.setText(mTotalPage_num);
			mCurrentPage.setText(mCurrentPage_num);
			this.tweenDragBtnTo(mDragTrackBtn.getTimeline().x, null, false);
			this.enable(false);
		}
		
		public function nextPage():void
		{
			this.onNextBtnPress();
		}
		
		public function prevPage():void
		{
			this.onPrevBtnPress();
		}
		
		public function enable(pEnable_bol:Boolean):void
		{
			mNextBtn.enabled = pEnable_bol;
			mPrevBtn.enabled = pEnable_bol;
			mDragBtn.enabled = pEnable_bol;
			mDragTrackBtn.enabled = pEnable_bol;
			
			if (pEnable_bol)
			{
				mNextBtn.reset();
				mPrevBtn.reset();
				mDragTrackBtn.reset();
			}
			
			if (mCurrentPage_num == 1)
			{
				mPrevBtn.enabled = false;
			}
			
			if (mCurrentPage_num == mTotalPage_num)
			{
				mNextBtn.enabled = false;
			}
		}
		
		private function onDragging():void
		{
			mCurrentPage.setText(this.getPageFromCoordinate(mDragBtn.getTimeline().x));
		}
		
		private function onDragStop():void
		{
			this.gotoPage(this.getPageFromCoordinate(mDragBtn.getTimeline().x));
		}
		
		private function onDragTrackBtnPress():void
		{
			this.enable(false);
			this.tweenDragBtnTo(mTimeline_mc.mouseX, new FunctionCall(this, gotoPage, this.getPageFromCoordinate(mTimeline_mc.mouseX)));
		}
		
		private function onNextBtnPress():void
		{
			this.gotoPage(Math.min(mCurrentPage_num + 1, mTotalPage_num));
		}
		
		private function onPrevBtnPress():void
		{
			this.gotoPage(Math.max(mCurrentPage_num - 1, 1));
		}
		
		private function refresh(pDoneCall:ICall = null):void
		{
			this.enable(false);
			
			mCurrentPage.setText(mCurrentPage_num);
			mTotalPage.setText(mTotalPage_num);
			
			if (mChangePageCall)
				mChangePageCall.execute();
				
			this.tweenDragBtnTo(this.getCoordinateFromPage(mCurrentPage_num), new FunctionCall(this, onRefreshDone, pDoneCall));
		}
		
		private function onRefreshDone(pDoneCall:ICall = null):void
		{
			this.enable(true);
			
			if(pDoneCall)
				pDoneCall.execute();
		}
		
		private function getPageFromCoordinate(pX_num:Number):Number
		{
			var page_num:Number = Math.min(Math.floor((pX_num - mDragTrackBtn.getTimeline().x)/(mDragTrackBtn.getTimeline().width/mTotalPage_num)) + 1, mTotalPage_num);
			
			return page_num;
		}
		
		private function getCoordinateFromPage(pPage_num):Number
		{
			var x_num:Number = Math.floor(mDragTrackBtn.getTimeline().x + (mDragTrackBtn.getTimeline().width/mTotalPage_num)*(pPage_num - 1));
			
			return x_num;
		}
		
		private function tweenDragBtnTo(pX_num:Number, pDoneCall:ICall = null, pJump_bol:Boolean = false):void
		{
			Tweener.addTween(mDragBtn.getTimeline(), {
				x:pX_num,
				time:(pJump_bol)?0:mSlideDuration_num,
				useFrames:true,
				onComplete:new Delegate(this, onTweenDragBtnComplete, pDoneCall).getFunction()
			});
		}
		
		private function onTweenDragBtnComplete(e:*, pDoneCall:ICall = null):void
		{
			if (pDoneCall)
				pDoneCall.execute();
		}
	}
}