package
{
	import flash.display.*;
	import flash.geom.*;

	public class AnimatedSpriteGenerator implements IFramesSource
	{
		private var src:MovieClip;
		private var def:GraphicExportDef;
		private var sequences:Array = new Array();	// [[AnimatedSpriteFrame]]
		private var callback;
		public function GetFrames():Array
		{
			var ret:Array = [];
			for (var i in sequences)
			{
				ret = ret.concat(sequences[i].map(function(frame:AnimatedSpriteFrame, i, arr) { return frame.info; }));
			}
			return ret;
		}
		
		public function GetData()
		{
			return {
						sequences:sequences.map(
							function(s:Array, i, sArr)
							{
								return {
									frames: s.map(
										function(f:AnimatedSpriteFrame, i, fArr)
										{
											return {rect:f.info.rect, center:f.offset, scale:def.scale};
										}
									)
								};
							}
						)
					};
		}
		
		public function AnimatedSpriteGenerator(src:MovieClip, def:GraphicExportDef)
		{
			this.src = src;
			this.def = def;
		}
		
		public function Go(callback)
		{
			this.callback = callback;
			for (var i = 0; i < src.totalFrames; i++)
			{
				Utils.WeirdGotoFrame(src, i + 1);
				Utils.RecursivelyStop(src);
				
				for (var j = 0; j < src.numChildren; j++)
				{
					var c = src.getChildAt(j);
					if (c is MovieClip)
					{
						sequences.push(GetAnimation(c, i));
						break;
					}
				}
			}
			
			callback(true);
		}
		
		private function GetAnimation(m:MovieClip, seq:int):Array
		{
			var ret:Array = new Array();
			for (var i = 0; i < m.totalFrames; i++)
			{
				Utils.WeirdGotoFrame(m, i + 1);
				Utils.RecursivelyStop(m);	
				
				var bounds:Rectangle = Utils.GetAccurateBounds(m, new Matrix(def.scale, 0, 0, def.scale));
				var frameBounds:Rectangle = new Rectangle(def.padding, def.padding, bounds.width, bounds.height);
				
				var drawMatrix:Matrix = new Matrix(def.scale, 0, 0, def.scale, -bounds.left + def.padding, -bounds.top + def.padding);
				
				var b:BitmapData = new BitmapData(bounds.width + def.padding * 2, bounds.height + def.padding * 2, true, 0x0);
				b.drawWithQuality(m, drawMatrix, null, null, frameBounds, false, StageQuality.BEST);
				
				var info:FrameInfo = new FrameInfo(b, drawMatrix, bounds);
				
				var frame:AnimatedSpriteFrame = new AnimatedSpriteFrame();
				frame.info = info;
				frame.sequence = seq;
				frame.frame = i;
				frame.offset = new Point(-bounds.left + def.padding, -bounds.right + def.padding);
				
				ret.push(frame);
			}
			
			return ret;
		}
	}
}

class AnimatedSpriteFrame
{
	import flash.display.*;
	import flash.geom.*;
	
	public var info:FrameInfo;
	public var sequence:int = 0;
	public var frame:int = 0;
	public var offset:Point = new Point();
}