/**
* MikuMikuDance VMD形式の再生制御
*
* @author b2ox
*/
package org.b2ox.pv3d.MikuMikuDance
{
	import org.b2ox.betweenas3.FuncTween;
	import org.libspark.betweenas3.BetweenAS3;
	import org.libspark.betweenas3.tweens.ITween;

	/**
	 * 再生制御
	 */
	public class VMDControllerRandom implements IVMDController
	{
		private var _ctr1:IVMDController;
		private var _ctr2:IVMDController;
		private var _tween:ITween;
		private var _counterTween:ITween;
		private var _updaterTween:FuncTween;
		private var _rate:Number;
		private var _ctr:IVMDController;

		/**
		 * IVMDControllerを2つ取り、ランダムにctr1かctr2を再生する。
		 * 基本的にループ再生で使用。ctr1とctr2の再生時間は揃えておくのが望ましい。
		 * @param	ctr1
		 * @param	ctr2
		 * @param	rate ctr1の確率(0.0～1.0)
		 */
		public function VMDControllerRandom(ctr1:IVMDController, ctr2:IVMDController, rate:Number):void
		{
			_rate = rate;
			this._ctr1 = ctr1;
			this._ctr2 = ctr2;
			if ( ctr1.counterTween == null ) throw new Error("引数ctrl1が不正です。");
			if ( ctr2.counterTween == null ) throw new Error("引数ctrl2が不正です。");
			_counterTween = BetweenAS3.serial(
				BetweenAS3.func(randomChoose),
				BetweenAS3.parallel(ctr1.counterTween.clone(), ctr2.counterTween.clone())
			);

			_updaterTween = FuncTween.create(function (time:Number):void { applyCurrent(); }, _counterTween);

			var _reseterTween:FuncTween = FuncTween.create(function (time:Number):void { resetParams(); }, _counterTween);
			var _applyerTween:FuncTween = FuncTween.create(function (time:Number):void { applyPose(); }, _counterTween);

			_tween = BetweenAS3.parallel(_reseterTween, _counterTween, _updaterTween, _applyerTween);
			randomChoose();
		}

		private function randomChoose():void
		{
			//trace("[DEBUG] VMDControllerRandom.randomChoose");
			_ctr = (Math.random() <= _rate) ? _ctr1 : _ctr2;
		}

		//-------------------------------------------------
		// 再生用のAPI

		public function get tween():ITween { return _tween; }
		public function get counterTween():ITween { return _counterTween; }
		public function get updaterTween():ITween { return _updaterTween; }

		public function get looping():Boolean { return ! _tween.stopOnComplete; }
		public function set looping(loop:Boolean):void { _tween.stopOnComplete = ! loop; }

		public function play():void { _tween.play(); }
		public function stop():void { _tween.stop(); }
		public function togglePause():void { _tween.togglePause(); }
		public function gotoAndPlay(pos:Number):void { _tween.gotoAndPlay(pos); }
		public function gotoAndStop(pos:Number):void { _tween.gotoAndStop(pos); }

		public function get playing():Boolean { return _tween.isPlaying; }

		public function update():void
		{
			resetParams();
			applyCurrent();
			applyPose();
		}

		public function resetParams():void { _ctr.resetParams(); }
		public function applyPose():void { _ctr.applyPose(); }
		public function applyCurrent():void { _ctr.applyCurrent(); }
	}
}
