package CharacterExport
{
	import flash.display.*;
	import flash.geom.*;
	import djarts.core.*;

	public class Piece
	{
		protected var size:Point;
		protected var fullData:BitmapData;
		protected var compareData:BitmapData;
		
		protected var centerPoint:Point;
		public function get CenterPoint():Point { return centerPoint; }
		
		public function get FullData():BitmapData { return fullData; }
		
		protected var valid = false;
		public function get Valid() { return valid; }
		
		public var Name:String = null;
		
		protected var usesBySequence = {};
		public function AddUse(sequence)
		{
			if (!(sequence in usesBySequence))
			{
				usesBySequence[sequence] = 0;
			}
			usesBySequence[sequence]++;
		}
		
		public function RemoveUse(sequence)
		{
			if (sequence in usesBySequence && usesBySequence[sequence] > 0)
			{
				usesBySequence[sequence]--;
			}
		}
		
		public function GetUses(sequence)
		{
			return (sequence in usesBySequence) ? usesBySequence[sequence] : 0;
		}
		
		public function get TotalUses()
		{
			var count = 0;
			for (var s in usesBySequence)
			{
				count += usesBySequence[s];
			}
			return count;
		}
		
		// returns the center point
		public function InitFromClip(clip:DisplayObject, upscale:Number = 1):Point
		{
			var bounds:Rectangle = CacheManager.Instance().GetAccurateBounds(clip, 2048);			
			
			size = new Point(bounds.width, bounds.height);
			
			valid = bounds.width > 0 && bounds.height > 0;
			if (valid)
			{		
				var m:Matrix = clip is Shape ? clip.transform.matrix.clone() : new Matrix();
				m.scale(upscale, upscale);				
				
				CharacterExporter.TransformRect(bounds, m);
				CharacterExporter.RoundRect(bounds);
				
				m.translate(-bounds.left, -bounds.top);
				
				fullData = new BitmapData(bounds.width, bounds.height, true, 0x0);
				fullData.draw(clip, m, clip is Shape && clip.parent ? clip.parent.transform.colorTransform : clip.transform.colorTransform, null, null, true);
				
				compareData = GenerateCompareData(clip);
				
				centerPoint = new Point(-bounds.left, -bounds.top);
				return centerPoint;
			}
			return null;
		}
		
		public function InitFromBitmapData(bd:BitmapData, centerPoint:Point = null)
		{
			if (centerPoint == null) centerPoint = new Point(0, 0);
			valid = true;
			size = new Point(bd.width, bd.height);
			
			fullData = bd;
			
			compareData = bd.clone();
			
			this.centerPoint = centerPoint;
		}
		
		public function Matches(otherData:BitmapData, otherName)
		{
			
			if (false && otherName != null && Name != null)
			{
				//This whole section fails to match things properly... 
				
				var m = Name.match("^([^0-9]+)(\\d*)");
				var tempName = m ? m[1] : Name;
				
				var mo = otherName.match("^([^0-9]+)(\\d*)");
				var tempOtherName = mo ? mo[1] : otherName;
				
				return tempName == tempOtherName;
				
				
				if (m)
				{
					if (otherName != m[1]) return false;
					return true;
				}
				else
				{
					if (otherName != Name) return false;
					return true;
				}
			}
			
			var threshold = 3;
			var maxPixels = 0;
			var result = compareData.compare(otherData);
			if (result == 0) return true;
			if (result is BitmapData)
			{
				var histo:Vector.<Vector.<Number>> = (result as BitmapData).histogram();
				for (var i = 0; i < 4; i++)
				{
					var diff:Vector.<Number> = histo[i];
					// for some STUPID reason, if all the colors match but the alphas dont, it returns FFFFFF for the color portion...
					// so DON'T compare the histogram for color channels up to 255
					var max = i == 4 ? 255 : 254;
					for (var j = threshold; j < Math.min(max, diff.length); j++)
					{
						if (diff[j] > maxPixels)
						{
							return false;
						}
					}
				}
				return true;
			}
			return false;
		}
		
		public static function GenerateCompareData(clip:DisplayObject):BitmapData
		{
			var scale = 1;
			
			var quickBounds:Rectangle = clip.getBounds(clip);
			var orig:Rectangle = quickBounds.clone();
			if (quickBounds.width == 0 || quickBounds.height == 0) return null;
			CharacterExporter.ScaleRect(quickBounds, scale);
			CharacterExporter.RoundRect(quickBounds);
			
			var m:Matrix = clip is Shape ? clip.transform.matrix.clone() : new Matrix();
			m.scale(scale, scale);
			m.translate(-quickBounds.left, -quickBounds.top);
			
			var data:BitmapData = new BitmapData(quickBounds.width, quickBounds.height, true, 0x0);
			data.draw(clip, m, clip is Shape && clip.parent ? clip.parent.transform.colorTransform : clip.transform.colorTransform, null, null, true);
			
			return data;
		}
	}
}