private void OnAnimationFinished(SpriterObjectAnimation animation)
 {
     Action<SpriterObjectAnimation> handler = AnimationFinished;
     if (handler != null) handler(animation);
 }
        private SpriterObject CreateSpriterObjectFromEntity(SpriterDataEntity entity)
        {
            var spriterObject = new SpriterObject(FlatRedBallServices.GlobalContentManager, false);

            IDictionary<string, string> filenames = new Dictionary<string, string>();
            IDictionary<int, ScaledSprite> persistentScaledSprites = new Dictionary<int, ScaledSprite>();
            IDictionary<int, SpriterBone> persistentBones = new Dictionary<int, SpriterBone>();
            IDictionary<string, Texture2D> textures = new Dictionary<string, Texture2D>();
            IDictionary<string, ObjectInfo> boxes = new Dictionary<string, ObjectInfo>();
            IDictionary<int, ScaledPositionedObject> boneRefDic = new Dictionary<int, ScaledPositionedObject>();
            IDictionary<KeyFrameValues, int> keyFrameValuesParentDictionary = new Dictionary<KeyFrameValues, int>();
            IDictionary<int, ScaledPolygon> persistentScaledPolygons = new Dictionary<int, ScaledPolygon>();
            IDictionary<int, SpriterPoint> persistentPoints = new Dictionary<int, SpriterPoint>();

            string oldDir = FileManager.RelativeDirectory;
            FileManager.RelativeDirectory = this.Directory;
            foreach (var folder in this.Folder)
            {
                foreach (var file in folder.File)
                {
                    string folderFileId = string.Format("{0}_{1}", folder.Id, file.Id);
                    filenames[folderFileId] = file.Name;
                    textures[folderFileId] = LoadTexture(file);
                }
            }
            FileManager.RelativeDirectory = oldDir;

            if (entity.ObjectInfos != null)
            {
                boxes =
                    entity.ObjectInfos.Where(oi => oi.Type == "box")
                        .ToDictionary(s => s.Name);
            }

            foreach (var animation in entity.Animation)
            {
                var mainline = animation.Mainline;
                var keyFrameList = new List<KeyFrame>();

                foreach (var key in mainline.Keys)
                {
                    var keyFrame = new KeyFrame {Time = key.Time/1000.0f};

                    // If it's a ScaledSprite (not a bone)
                    if (key.ObjectRef != null)
                    {
                        CreateRuntimeObjectsForSpriterObjectRef(key, persistentScaledSprites, spriterObject, animation, textures,
                            keyFrame, keyFrameValuesParentDictionary, boxes, persistentScaledPolygons, persistentPoints);
                    }

                    // If it's a bone (not a ScaledSprite)
                    if (key.BoneRef != null)
                    {
                        CreateRuntimeObjectsForSpriterBoneRef(key, persistentBones, spriterObject, animation, keyFrame,
                            boneRefDic, keyFrameValuesParentDictionary, entity);
                    }

                    keyFrameList.Add(keyFrame);
                }

                HandleUnreferencedTimelinekeys(animation, mainline, keyFrameList, persistentScaledSprites, spriterObject,
                    textures, keyFrameValuesParentDictionary, persistentBones, boneRefDic, boxes, persistentScaledPolygons,
                    persistentPoints, entity);

                // find all the keyframevalues, and look up the bone id, then take that bone id and
                // set the parent in the keyframevalues variable to the ScaledPositionedObject in the boneRefDic
                foreach (var pair in keyFrameList.SelectMany(keyFrame => keyFrame.Values))
                {
                    if (keyFrameValuesParentDictionary.ContainsKey(pair.Value))
                    {
                        int boneId = keyFrameValuesParentDictionary[pair.Value];
                        var parent = boneRefDic[boneId];
                        pair.Value.Parent = parent;
                    }
                    else if (pair.Key.GetType() != typeof (ScaledSprite) && pair.Key.GetType() != typeof (ScaledPolygon))
                    {
                        pair.Value.Parent = spriterObject;
                    }
                }

                var SpriterObjectAnimation = new SpriterObjectAnimation(animation.Name,
                    animation.Looping, animation.Length/1000.0f,
                    keyFrameList);
                spriterObject.Animations[animation.Name] = SpriterObjectAnimation;
            }
            return spriterObject;
        }