/*
 *  Copyright 2008 tarotarorg
 * 
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 * 
 *      http://www.apache.org/licenses/LICENSE-2.0
 * 
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 */
package org.tarotaro.flash.pv3d 
{
	import flash.events.Event;
	import flash.events.IOErrorEvent;
	import flash.events.SecurityErrorEvent;
	import flash.events.TimerEvent;
	import flash.utils.Timer;
	import org.tarotaro.flash.pv3d.Metasequoia;
	import org.papervision3d.core.animation.AnimationKeyFrame3D;
	import org.papervision3d.events.FileLoadEvent;
	import org.papervision3d.objects.DisplayObject3D;
	
	/**
	* メタセコイアファイル名の配列を受け取り、全てロードしてパラパラ漫画のように表示を切り替える事によってアニメーションさせるクラス。
	* @author 太郎
	*/
	public class AnimationMetasequoia extends DisplayObject3D
	{
		
		private var _models:Array;
		
		private var _totalFrames:uint;
		private var _loadingFrames:uint;
		private var _loadingMaterials:uint;
		private var _currentFrame:uint;
		private var _materialComplete:Boolean;
		
		private var _timer:Timer;
		
		public function AnimationMetasequoia(speed:uint = 50) 
		{
			super();
			this._models = new Array();
			this._totalFrames = 0;
			this._loadingFrames = 0;
			this._loadingMaterials = 0;
			this.currentFrame = 0;
			this._materialComplete = false;
			
			this._timer = new Timer(speed, 0);
			this._timer.addEventListener(TimerEvent.TIMER , animation);
		}
		
		/**
		 * アニメーション再生
		 * @param	e
		 */
		private function animation(e:TimerEvent):void 
		{
			try {
				removeChild(this._models[this.currentFrame]);
			} catch (e:Error) {
				trace("アニメーション中のエラー", e);
			}
			this.currentFrame++;
			addChild(this._models[this.currentFrame]);
		}
		
		public function play():void
		{
			this._timer.start();
		}
		
		public function stop():void 
		{
			this._timer.stop();
		}
		/**
		 * アニメーションに使用する、連番mqoファイルをロードする
		 * @param	files ロードするファイル名の配列
		 * @param	scale 倍率
		 */
		public function load(files:Array,scale:Number = 1):void
		{
			this._totalFrames = files.length;
			this._loadingFrames = this._loadingMaterials = files.length;
			//１．1つ目のファイルをMetasequoiaクラスのインスタンスとしてロードする
			//２．2つ目以降のファイルをマテリアル無しのMetasequoiaクラスのインスタンスとしてロードする
			//３．1つ目のマテリアルを全部のマテリアルとして使う
			var firstMqo:Metasequoia = new Metasequoia();
			
			firstMqo.addEventListener(Event.COMPLETE, function(e:Event):void {
				for (var i:uint = 1; i < files.length; i++) {
					var mqo:Metasequoia = new Metasequoia();
					setMqoEventListeners(mqo);
					mqo.materialBase = firstMqo;
					mqo.load(files[i], scale,true);
					_models.push(mqo);
				}
			},false,int.MAX_VALUE);
			
			this.setMqoEventListeners(firstMqo);
			
			
			firstMqo.load(files[0], scale);
			this._models.push(firstMqo);
			
		}
		
		private function setMqoEventListeners(mqo:Metasequoia):void
		{
			mqo.addEventListener(FileLoadEvent.COLLADA_MATERIALS_DONE, materialLoadCompleteHandler);
			mqo.addEventListener(Event.COMPLETE, modelLoadCompleteHandler);
			mqo.addEventListener(IOErrorEvent.IO_ERROR, modelIOErrorHandelr);
			mqo.addEventListener(SecurityErrorEvent.SECURITY_ERROR, modelSecurityErrorHandler);
		}
		
		private function materialLoadCompleteHandler(e:FileLoadEvent):void 
		{
			this._loadingMaterials--;
		}
		
		/**
		 * モデルのロード中にセキュリティエラー発生
		 * @param	e
		 */
		private function modelSecurityErrorHandler(e:SecurityErrorEvent):void 
		{
			trace("[AnimationMetasequoia]セキュリティエラー発生：", e);
			dispatchEvent(e.clone());
		}
		
		/**
		 * モデルのロード中にIOエラー発生
		 * @param	e
		 */
		private function modelIOErrorHandelr(e:IOErrorEvent):void 
		{
			trace("[AnimationMetasequoia]IOエラー発生：", e);
			dispatchEvent(e.clone());
		}
		
		/**
		 * ロード完了
		 * @param	e
		 */
		private function modelLoadCompleteHandler(e:Event):void 
		{
			this._loadingFrames--;
			var evt:AnimationMetasequoiaEvent;
			if (this._loadingFrames == 0) {
				addChild(this._models[this.currentFrame]);
				evt = AnimationMetasequoiaEvent.createCompleteEvent(this._totalFrames);
			} else {
				evt = AnimationMetasequoiaEvent.createProgressEvent
													(this._totalFrames, (this._totalFrames - this._loadingFrames));
			}
			dispatchEvent(evt);
		}
		
		private function set currentFrame(value:uint):void 
		{
			this._currentFrame = value % (this._totalFrames || 1);
		}
		
		private function get currentFrame():uint { return this._currentFrame;}
		
	}
	
}