package
{
	import flash.utils.*;
	import flash.geom.*;
	import flash.display.*;
	import com.adobe.images.PNGEncoderWithAlpha;
	public class Job
	{
		private var callback;
		
		private var id:int;
		private var name:String;
		
		private var details;
		
		private var graphics:Array = new Array();
		
		public function GetID():int { return this.id; }
		public function Job(id:int, graphicsDetails:Array)
		{
			this.id = id;
			for (var i in graphicsDetails)
			{
				var graphic:GraphicExportDef = new GraphicExportDef(this, graphicsDetails[i], i);
				if (graphic.valid)
				{
					graphics.push(graphic);
				}
			}
			Exporter.Instance.Trace("new job: " + id);
		}
		public function FailMessage(err:String)
		{
			Exporter.Instance.Print("Failure: job " + id + ": " + err);
		}
		
		public function WarnMessage(err:String)
		{
			Exporter.Instance.Print("Warning: job " + id + ": " + err);
		}
		
		private function Fail(err:String)
		{
			FailMessage(err);
			callback();
		}
		
		private var goIndex = -1;
		public function Go(callback)
		{
			this.callback = callback;
			
			goIndex = -1;
			
			CheckNextGraphic();
		}
		
		private function CheckNextGraphic()
		{
			goIndex++;
			if (goIndex < graphics.length)
			{
				graphics[goIndex].Go(CheckNextGraphic);
			}
			else				
			{
				Pack();
			}
		}
		
		private var allFrames:Array;	//[FrameInfo]
		private var packer:FramePacker;
		private function Pack()
		{
			allFrames = new Array();
			for (var i in graphics)
			{
				if (graphics[i].valid)
				{
					allFrames = allFrames.concat(graphics[i].GetFrames());
				}
			}
			packer = new FramePacker(allFrames);
			packer.Pack(PackDone);
		}
		
		private var sheets:Array;	//[BitmapData]
		private var sheetBytes:Array;	//[ByteArray]
		
		private function PackDone(success)
		{
			if (!success)
			{
				Fail("couldn't pack exported frames to sheets");
				return;
			}
			
			var i;
			var sheet:BitmapData;
			
			sheets = new Array();
			sheetBytes = new Array();
			var sheetAllocators:Array = packer.GetSheets();
			for (i in sheetAllocators)
			{
				var allocator:RectanglePacker = sheetAllocators[i];
				sheet = new BitmapData(allocator.width, allocator.height, true, 0x0);
				sheets.push(sheet);
			}
			for (i in allFrames)
			{
				var frame:FrameInfo = allFrames[i];
				sheet = sheets[frame.sheetIndex];
				sheet.copyPixels(frame.frame, frame.frame.rect, frame.rect.topLeft);
			}
			for (i in sheets)
			{
				sheetBytes[i] = PNGEncoderWithAlpha.encode(sheets[i]);
			}
			
			Done();
		}

		public function Done()
		{
			Exporter.Instance.Trace("Job.Done() " + id);
			this.callback();
		}
		
		public function GetResources():Array	//[ByteArray]
		{
			return sheetBytes;
		}
		
		public function GetData()
		{
			var ret = {};
			for (var i in graphics)
			{
				if (graphics[i].valid)
				{
					if (ret[graphics[i].name] !== undefined)
					{
						WarnMessage("two graphics with same name: " + graphics[i].name);
					}
					else
					{
						ret[graphics[i].name] = graphics[i].GetData();
					}
				}
			}
			return ret;
		}
	}
}