package laya.core.utils 
{
	import laya.core.display.Sprite;
	import laya.core.styles.SpriteStyle;
	import laya.maths.Matrix;
	/**
	 * ...
	 * @author laya
	 */
	public class CalculateTransformWithThread 
	{
		private static var _cache:* =/*[STATIC SAFE]*/ (_cache = [], _cache._length = 0, _cache);
		private static var _all:* =/*[STATIC SAFE]*/ (_all = [], _all._length = 0, _all);
		private static var _value:Float32Array = new Float32Array(600);
		private static var _data:* =/*[STATIC SAFE]*/ {_call:"CALCULATETRANSFORM",value:null,size:0 };
		
		public static var _top:CalculateTransformWithThread;
		public static var _cur:CalculateTransformWithThread;
		
		public static function __init__():void
		{
			Thread.MAIN.far("CALCULATETRANSFORM", _calculate);
			Thread.MAIN.calculateed = calculateed;
			_cur=_top = new CalculateTransformWithThread();
		}
		
		public static function _calculate(value:Float32Array,data:*):void
		{
			var sx:Number, sy:Number, rotation:Number, angle:Number, cos:Number, sin:Number;
			for (var i:int = 0, n:int = data.size; i < n; i+=6)
			{
				sx = value[i+1];
				sy = value[i+2];
				rotation = value[i+3];
				angle = rotation * 0.0174532922222222;// laya.CONST.PI180;
				cos = Math.cos(angle);
				sin = Math.sin(angle);
				value[i+1] = sx * cos;
				value[i+2] = sx * sin;
				value[i+3] = -sy * sin;
				value[i+4] = sy * cos;
			}
			data._call = "calculateed";
			__JS__("this.postMessage(data)");
		}
		
		public static function calculateed(value:Float32Array,data:*):void
		{
			for (var i:int = 0, n:int = data.size; i < n; i+=6)
			{
				var sprite:Sprite = _all[value[i]];
				if (sprite._tfChanged) continue;
				var m:Matrix = sprite._transform ? sprite._transform : (sprite._transform = new Matrix());
				sprite._tfChanged = true;
				m.a = value[i+1];
				m.b = value[i+2];
				m.c = value[i+3];
				m.d = value[i+4];
				m.tx = m.ty = 0;
			}
		}
		
		public static function run():void
		{
			if (_top.next)
			{
				_top.next.callByThread(0);
				_cur = _top;
				_top.next = null;
			}
		}
		
		public var next:CalculateTransformWithThread;
		public var sprite:Sprite;
		public var id:int;
		
		public function CalculateTransformWithThread() 
		{
			id = _all._length++;
			_all[id] = this;
		}
		
		public function callByThread(index:int):int
		{
			var style:SpriteStyle = sprite._style;
			var sx:Number = style.scaleX, sy:Number = style.scaleY;
			if (style.rotation)
			{
				var value:Float32Array = _value;
				value[index+0] =id;
				value[index+1] =sx;
				value[index+2] =sy;
				value[index+3] = style.rotation;
				index += 6;
				if (index ===600)
				{
					_data.size = 600;
					_data.value = _value;
					Thread.MAIN.worker.postMessage(_data);
					index = 0;
				}
			}
			release();
			if(next) return next.callByThread(index);
			return index;
		}
		
		public function release():void
		{
			_cache[_cache._length++] = this;
		}

		public static function create(sprite:Sprite):CalculateTransformWithThread
		{
			var cache:* = _cache;
			var o:CalculateTransformWithThread = cache._length > 0?cache[--cache._length]:(new CalculateTransformWithThread());
			_cur.next = o;
			o.next = null;
			o.sprite = sprite;
			_cur = o;
			return o;
		}
	}

}