public void ParentScaleAffectsSpriteScale()
        {
            var spo = new ScaledPositionedObject
            {
                ScaleX = .5f,
                ScaleY = .25f
            };

            var sprite = new ScaledSprite
            {
                RelativeScaleX = .5f,
                RelativeScaleY = 1.0f
            };

            sprite.AttachTo(spo, true);

            sprite.UpdateDependencies(0);

            Assert.IsTrue(Math.Abs(sprite.Width - .25f * ScaledSprite.DefaultTextureWidth) < Single.Epsilon);
            Assert.IsTrue(Math.Abs(sprite.Height - .25f * ScaledSprite.DefaultTextureHeight) < Single.Epsilon);
        }
        private void CreateRuntimeObjectsForSpriterObjectRef(Key key, IDictionary<int, ScaledSprite> persistentScaledSprites, SpriterObject SpriterObject, SpriterDataEntityAnimation animation, IDictionary<string, Texture2D> textures, KeyFrame keyFrame, IDictionary<KeyFrameValues, int> SpriterefParentDic, IDictionary<string, ObjectInfo> boxes, IDictionary<int, ScaledPolygon> persistentScaledPolygons, IDictionary<int, SpriterPoint> persistentPoints, Key timelineKeyOverride = null)
        {
            foreach (var objectRef in key.ObjectRef)
            {
                var timeline = animation.Timeline.Single(t => t.Id == objectRef.Timeline);
                Key timelineKey = timelineKeyOverride ?? timeline.Key.Single(k => k.Id == objectRef.Key);
                if (timelineKeyOverride == null && key.Time != timelineKey.Time)
                {
                    var nextTimelineKey = timeline.Key.FirstOrDefault(k => k.Time > key.Time) ??
                                          new Key(timeline.Key.First()) { Time = animation.Length };

                    timelineKey = InterpolateToNewTimelineKey(key, timelineKey, nextTimelineKey);
                }

                if (timeline.ObjectType == "box")
                {
                    ScaledPolygon scaledPolygon;
                    ScaledPositionedObject pivot;
                    var box = boxes[timeline.Name];

                    if (persistentScaledPolygons.ContainsKey(objectRef.Id))
                    {
                        scaledPolygon = persistentScaledPolygons[objectRef.Id];
                        pivot = (ScaledPositionedObject)scaledPolygon.Parent;
                    }
                    else
                    {
                        scaledPolygon = ScaledPolygon.CreateRectangle(timelineKey.Object.X, timelineKey.Object.Y, (int)box.Width, (int)box.Height);
                        scaledPolygon.ParentScaleChangesPosition = false;
                        scaledPolygon.Visible = false;

                        var name = objectRef.Name ?? objectRef.Id.ToString(CultureInfo.InvariantCulture);
                        pivot = new ScaledPositionedObject { Name = string.Format("{0}_pivot", name) };

                        scaledPolygon.Name = timeline.Name;

                        scaledPolygon.AttachTo(pivot, true);
                        pivot.AttachTo(SpriterObject, true);

                        persistentScaledPolygons[objectRef.Id] = scaledPolygon;
                        SpriterObject.ObjectList.Add(scaledPolygon);
                        SpriterObject.ObjectList.Add(pivot);
                    }

                    var values = GetKeyFrameValues(timelineKey, box, objectRef);

                    values.ScaledPolygon.Parent = pivot;
                    if (objectRef.Parent.HasValue)
                    {
                        SpriterefParentDic[values.Pivot] = objectRef.Parent.Value;
                    }
                    else
                    {
                        values.Pivot.Parent = SpriterObject;
                    }

                    keyFrame.Values[pivot] = values.Pivot;
                    keyFrame.Values[scaledPolygon] = values.ScaledPolygon;
                }
                else if (timeline.ObjectType == "point")
                {
                    SpriterPoint point;

                    if (persistentPoints.ContainsKey(objectRef.Id))
                    {
                        point = persistentPoints[objectRef.Id];
                    }
                    else
                    {
                        point = new SpriterPoint
                        {
                            X = timelineKey.Object.X,
                            Y = timelineKey.Object.Y,
                            Name = timeline.Name
                        };
                        SpriterObject.ObjectList.Add(point);
                        persistentPoints[objectRef.Id] = point;
                    }

                    KeyFrameValues values = GetKeyFrameValuesForPoint(timelineKey, objectRef);

                    if (objectRef.Parent.HasValue)
                    {
                        SpriterefParentDic[values] = objectRef.Parent.Value;
                    }
                    else
                    {
                        values.Parent = SpriterObject;
                    }

                    keyFrame.Values[point] = values;
                }
                else if (string.IsNullOrEmpty(timeline.ObjectType))
                {
                    var folderFileId = string.Format("{0}_{1}", timelineKey.Object.Folder,
                        timelineKey.Object.File);
                    var file =
                        this.Folder.First(f => f.Id == timelineKey.Object.Folder)
                            .File.First(f => f.Id == timelineKey.Object.File);

                    ScaledSprite scaledSprite;
                    ScaledPositionedObject pivot;
                    if (persistentScaledSprites.ContainsKey(objectRef.Id))
                    {
                        scaledSprite = persistentScaledSprites[objectRef.Id];
                        pivot = (ScaledPositionedObject) scaledSprite.Parent;
                    }
                    else
                    {
                        var name = objectRef.Name ?? objectRef.Id.ToString(CultureInfo.InvariantCulture);
                        pivot = new ScaledPositionedObject {Name = string.Format("{0}_pivot", name)};

                        scaledSprite = new ScaledSprite
                        {
                            Name = string.Format("{0}_sprite", name),
                            Width = file.Width,
                            Height = file.Height,
                            ParentScaleChangesPosition = false
                        };

                        scaledSprite.AttachTo(pivot, true);
                        pivot.AttachTo(SpriterObject, true);

                        persistentScaledSprites[objectRef.Id] = scaledSprite;
                        SpriterObject.ObjectList.Add(scaledSprite);
                        SpriterObject.ObjectList.Add(pivot);
                    }

                    var values = GetKeyFrameValues(timelineKey, file, textures, folderFileId, objectRef);

                    values.ScaledSprite.Parent = pivot;
                    if (objectRef.Parent.HasValue)
                    {
                        SpriterefParentDic[values.Pivot] = objectRef.Parent.Value;
                    }
                    else
                    {
                        values.Pivot.Parent = SpriterObject;
                    }

                    keyFrame.Values[pivot] = values.Pivot;
                    keyFrame.Values[scaledSprite] = values.ScaledSprite;
                }
            }
        }
        private static SpriterObject GetSimpleSpriterObject(bool loops = false)
        {
            var so = new SpriterObject("Global", false);

            var sprite = new ScaledSprite();
            var pivot = new ScaledPositionedObject();
            pivot.AttachTo(so, true);
            sprite.AttachTo(pivot, true);
            sprite.Name = "sprite";
            pivot.Name = "pivot";

            so.Animations.Add("", new SpriterObjectAnimation("", loops, 2.0f, new List<KeyFrame>()));

            // first keyframe (0ms)
            var keyFrame = new KeyFrame
            {
                Time = 0
            };

            // The pivot is at 30,30
            keyFrame.Values[pivot] = new KeyFrameValues
            {
                RelativePosition = new Vector3(30f, 30f, 0f)
            };
            // Sprite is just there to connect to the pivot
            keyFrame.Values[sprite] = new KeyFrameValues
            {
                Alpha = 1.0f,
                Parent = pivot,
                RelativeScaleX = 1.0f,
                RelativeScaleY = 1.0f
            };

            so.Animations[""].KeyFrames.Add(keyFrame);

            keyFrame = new KeyFrame
            {
                Time = 1.0f
            };
            keyFrame.Values[pivot] = new KeyFrameValues
            {
                RelativePosition = Vector3.Zero
            };

            keyFrame.Values[sprite] = new KeyFrameValues
            {
                Alpha = 1.0f,
                Parent = pivot,
                RelativeScaleX = 1.0f,
                RelativeScaleY = 1.0f,
                RelativePosition = Vector3.Zero
            };

            so.Animations[""].KeyFrames.Add(keyFrame);

            so.ObjectList.Add(sprite);
            so.ObjectList.Add(pivot);

            //so.AddToManagers(null);
            return so;
        }
        public void Test2Objects()
        {
            var so = new SpriterObject("Global", false);

            var sprite = new ScaledSprite();
            var pivot = new ScaledPositionedObject();
            var sprite2 = new ScaledSprite();
            var pivot2 = new ScaledPositionedObject();

            pivot.AttachTo(so, true);
            sprite.AttachTo(pivot, true);

            pivot2.AttachTo(so, true);
            sprite2.AttachTo(pivot2, true);
            so.Animations.Add("", new SpriterObjectAnimation("", true, 2.0f, new List<KeyFrame>()));

            var keyFrame = new KeyFrame
            {
                Time = 0
            };
            keyFrame.Values[pivot] = new KeyFrameValues
            {
                RelativePosition = Vector3.Zero
            };
            keyFrame.Values[pivot2] = new KeyFrameValues
            {
                RelativePosition = Vector3.Zero
            };

            so.Animations[""].KeyFrames.Add(keyFrame);

            keyFrame = new KeyFrame
            {
                Time = 1.0f
            };
            keyFrame.Values[pivot] = new KeyFrameValues
            {
                RelativePosition = new Vector3(0f, 10f, 0f)
            };
            keyFrame.Values[pivot2] = new KeyFrameValues
            {
                RelativePosition = new Vector3(10f, 0f, 0f)
            };

            so.Animations[""].KeyFrames.Add(keyFrame);

            so.ObjectList.Add(sprite);
            so.ObjectList.Add(pivot);
            so.ObjectList.Add(sprite2);
            so.ObjectList.Add(pivot2);

            so.StartAnimation();
            TimeManager.CurrentTime += .5;
            so.TimedActivity(.5f, 0f, 0f);

            Assert.AreEqual(5f, so.ObjectList[1].Position.Y);
            Assert.AreEqual(5f, so.ObjectList[3].Position.X);

            TimeManager.CurrentTime += .25;
            so.TimedActivity(.25f, 0f, 0f);
            Assert.AreEqual(7.5f, so.ObjectList[1].Position.Y);
            Assert.AreEqual(7.5f, so.ObjectList[3].Position.X);
        }