package skeletal
{
import flash.display.*;
import flash.geom.*;
import frame.FrameInfo;
import util.*;
public class Piece
{
protected var size:Point;
protected var frameInfo:FrameInfo;
protected var compareData:BitmapData;
protected var centerPoint:Point;
public function get CenterPoint():Point { return centerPoint; }
public function get FullData():BitmapData { return frameInfo == null ? null : frameInfo.frameData; }
public function get Frame():FrameInfo { return frameInfo; }
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 = Utils.GetAccurateBounds(clip);
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);
Utils.TransformRect(bounds, m);
Utils.RoundRect(bounds);
m.translate(-bounds.left, -bounds.top);
var fullData:BitmapData = 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);
frameInfo = new FrameInfo(fullData, m, null);
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);
frameInfo = new FrameInfo(bd, null, null);
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;
Utils.ScaleRect(quickBounds, scale);
Utils.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;
}
}
}