/**
* PMDSkin for MikuMikuDance Model+Motion
*
* @author b2ox
*/
package org.b2ox.pv3d.MikuMikuDance
{
	//import flash.events.*;
	import org.papervision3d.core.geom.renderables.Vertex3D;

	/**
	 * PMDの表情を保持するためのクラス
	 */
	public class PMDSkin
	{
		public static const TYPE_BASE:int = 0;
		public static const TYPE_EYEBROW:int = 1;
		public static const TYPE_EYE:int = 2;
		public static const TYPE_LIP:int = 3;
		public static const TYPE_OTHER:int = 4;

		private var _name:String;
		private var _type:int;
		private var _vertex:Array;
		private var _size:int;
		private var _weight:Number;

		public function get name():String { return _name; }
		public function get type():int { return _type; }
		public function get size():int { return _size; }
		public function get weight():Number { return _weight; }
		public function set weight(w:Number):void { _weight = (w < 0) ? 0 : ((w > 1) ? 1 : w); }

		public function PMDSkin(name:String, vcount:int, type:int):void
		{
			_name = name;
			_type = (type < 0 || 4 < type) ? 4 : type;
			_size = vcount;
			_vertex = new Array(vcount);
			_weight = 0;
		}

		public function setVertex(i:int, bi:int, x:Number, y:Number, z:Number):void
		{
			_vertex[i] = { index: bi, x: x, y: y, z: z };
		}

		public function calcTargetIndices(baseSkin:PMDSkin):void
		{
			if (_type == TYPE_BASE) return;
			for each(var v:Object in _vertex) v.target_index = baseSkin._vertex[v.index].index;
		}

		public function effect(target:Array, baseSkin:PMDSkin):void
		{
			var t:Vertex3D, v:Object;
			if (_type == TYPE_BASE)
			{
				for each(v in _vertex)
				{
					t = target[v.index];
					t.x = v.x;
					t.y = v.y;
					t.z = v.z;
				}
			} else {
				for each(v in _vertex)
				{
					var w:Object = baseSkin._vertex[v.index];
					t = target[w.index];
					t.x = w.x + v.x * _weight;
					t.y = w.y + v.y * _weight;
					t.z = w.z + v.z * _weight;
				}
			}
		}

		/**
		 * これを使う前には必ずcalcTargetIndicesを実行すること(PMDController.addSkinの時に実行するのでユーザーは気にしなくて良い)
		 * @param	target
		 */
		public function effectPlus(target:Array):void
		{
			var t:Vertex3D, v:Object;
			if (_weight == 0 || _type == TYPE_BASE) return;
			for each(v in _vertex)
			{
				t = target[v.target_index];
				t.x += v.x * _weight;
				t.y += v.y * _weight;
				t.z += v.z * _weight;
			}
		}
	}
}

