public static void TestPlay()
    {
        GameObject gameObject = new GameObject();
        Roga2dAnimationPlayer player = new Roga2dAnimationPlayer();
        Roga2dWait interval = new Roga2dWait(3);
        Roga2dNode node = new Roga2dNode();
        Roga2dAnimation animation = Roga2dAnimation.Build(node, interval);
        player.Play(null, null, animation, AnimationFinished);

        Tester.Ok(!interval.IsDone());

        player.Update();
        Tester.Ok(!interval.IsDone());

        player.Update();
        Tester.Ok(!interval.IsDone());

        player.Update();
        Tester.Ok(!interval.IsDone());

        Tester.Match(testCounter, 0);

        player.Update();
        Tester.Ok(interval.IsDone());
        Tester.Match(testCounter, 999);

        node.Destroy();
        Object.Destroy(gameObject);
    }
    public static void TestAddRemove()
    {
        Roga2dNode node1 = new Roga2dNode();
        Roga2dNode node2 = new Roga2dNode();

        node1.LocalPosition = new Vector2(5, 5);
        node1.LocalRotation = 50.0f;
        node1.LocalScale = new Vector2(3, 2);

        node2.LocalPosition = new Vector2(10, 10);
        node2.LocalRotation = 100.0f;
        node2.LocalScale = new Vector2(5, 4);

        Tester.Match(node1.ChildrenCount, 0);

        node1.AddChild(node2);
        Tester.Match(node1.ChildrenCount, 1);
        Tester.Match(node1, node2.Parent);

        // Check parent node transform is as expected
        Tester.Match(node1.LocalPosition, new Vector2(5, 5));
        Tester.Match(node1.LocalRotation, 50.0f);
        Tester.Match(node1.LocalScale, new Vector2(3, 2));

        // Check child node transform is as expected
        Tester.Match(node2.LocalPosition, new Vector2(10, 10));
        Tester.Match(node2.LocalRotation, 100.0f);
        Tester.Match(node2.LocalScale, new Vector2(5, 4));

        node1.RemoveChild(node2);
        Tester.Match(node1.ChildrenCount, 0);

        node1.Destroy();
    }
    public static void TestTween()
    {
        Roga2dNode node = new Roga2dNode();
        Roga2dRotationIntervalOption option = new Roga2dRotationIntervalOption();
        Roga2dRotationInterval interval = new Roga2dRotationInterval(node, 360.0f, 0.0f, 3, true, option);

        Tester.Ok(!interval.IsDone());

        Tester.Match(node.LocalRotation, 0.0f);
        Tester.Ok(!interval.IsDone());

        interval.Start();
        Tester.Match(node.LocalRotation, 0.0f); // 360.0f = 0.0f
        Tester.Ok(!interval.IsDone());

        interval.Update();
        Tester.Match(node.LocalRotation, 240.0f);
        Tester.Ok(!interval.IsDone());

        interval.Update();
        Tester.Match(node.LocalRotation, 120.0f);
        Tester.Ok(!interval.IsDone());

        interval.Update();
        Tester.Match(node.LocalRotation, 0.0f);
        Tester.Ok(interval.IsDone());

        interval.Reset();
        Tester.Match(node.LocalRotation, 0.0f); // 360.0f = 0.0f
        Tester.Ok(!interval.IsDone());

        node.Destroy();
    }
    public static void TestTween()
    {
        Roga2dNode node = new Roga2dNode();

        Roga2dAlphaInterval interval1 = new Roga2dAlphaInterval(node, 0.1f, 1.0f, 3, true);
        Roga2dRotationIntervalOption option = new Roga2dRotationIntervalOption();
        Roga2dRotationInterval interval2 = new Roga2dRotationInterval(node, 0.0f, 180.0f, 5, true,  option);

        List<Roga2dBaseInterval> intervals = new List<Roga2dBaseInterval>();
        intervals.Add(interval1);
        intervals.Add(interval2);
        Roga2dParallel parallel = new Roga2dParallel(intervals);

        parallel.Start();
        Tester.Match(node.LocalAlpha, 0.1f);
        Tester.Match(node.LocalRotation, 0.0f);
        Tester.Ok(!parallel.IsDone());

        parallel.Update();
        Tester.Match(node.LocalAlpha, 0.4f);
        Tester.Match(node.LocalRotation, 36.0f);
        Tester.Ok(!parallel.IsDone());

        parallel.Update();
        Tester.Match(node.LocalAlpha, 0.7f);
        Tester.Match(node.LocalRotation, 72.0f);
        Tester.Ok(!parallel.IsDone());

        parallel.Update();
        Tester.Match(node.LocalAlpha, 1.0f);
        Tester.Match(node.LocalRotation, 108.0f);
        Tester.Ok(!parallel.IsDone());

        parallel.Update();
        Tester.Match(node.LocalAlpha, 1.0f);
        Tester.Match(node.LocalRotation, 144.0f);
        Tester.Ok(!parallel.IsDone());

        parallel.Update();
        Tester.Match(node.LocalAlpha, 1.0f);
        Tester.Match(node.LocalRotation, 180.0f);
        Tester.Ok(parallel.IsDone());

        parallel.Update();
        Tester.Match(node.LocalAlpha, 1.0f);
        Tester.Match(node.LocalRotation, 180.0f);
        Tester.Ok(parallel.IsDone());

        parallel.Reset();
        Tester.Match(node.LocalAlpha, 0.1f);
        Tester.Match(node.LocalRotation, 0.0f);
        Tester.Ok(!parallel.IsDone());

        node.Destroy();
    }
    public static void TestAddRemoveAll()
    {
        Roga2dNode node1 = new Roga2dNode();
        Roga2dNode node2 = new Roga2dNode();

        Tester.Match(node1.ChildrenCount, 0);

        node1.AddChild(node2);
        Tester.Match(node1.ChildrenCount, 1);
        Tester.Match(node1, node2.Parent);

        node1.RemoveAllChildren();
        Tester.Match(node1.ChildrenCount, 0);

        node1.Destroy();
    }
    public static void Test2Loop()
    {
        Roga2dNode node = new Roga2dNode();

        Roga2dAlphaInterval interval1 = new Roga2dAlphaInterval(node, 0.1f, 1.0f, 1, true);
        Roga2dWait interval2 = new Roga2dWait(1);
        Roga2dAlphaInterval interval3 = new Roga2dAlphaInterval(node, 0.7f, 0.0f, 1, true);

        List<Roga2dBaseInterval> intervals = new List<Roga2dBaseInterval>();
        intervals.Add(interval1);
        intervals.Add(interval2);
        intervals.Add(interval3);

        Roga2dSequence sequence = new Roga2dSequence(intervals);
        Roga2dLoop loop = new Roga2dLoop(sequence, 2);

        loop.Start();
        Tester.Match(node.LocalAlpha, 0.1f);
        Tester.Ok(!loop.IsDone());

        loop.Update();
        Tester.Match(node.LocalAlpha, 1.0f);
        Tester.Ok(!loop.IsDone());

        loop.Update();
        Tester.Match(node.LocalAlpha, 1.0f);
        Tester.Ok(!loop.IsDone());

        loop.Update();
        Tester.Match(node.LocalAlpha, 0.1f);
        Tester.Ok(!loop.IsDone());

        loop.Update();
        Tester.Match(node.LocalAlpha, 1.0f);
        Tester.Ok(!loop.IsDone());

        loop.Update();
        Tester.Match(node.LocalAlpha, 1.0f);
        Tester.Ok(!loop.IsDone());

        loop.Update();
        Tester.Match(node.LocalAlpha, 0.0f);
        Tester.Ok(loop.IsDone());

        node.Destroy();
    }
    public static void TestAddRemove()
    {
        Roga2dNode node = new Roga2dNode();
        Roga2dRenderObject renderObject = new Roga2dRenderObject(null, new Vector2(64, 64), new Vector2(32, 16), new Rect(0, 0, 1, 1));
        Roga2dSprite sprite = new Roga2dSprite(renderObject);

        Tester.Match(node.ChildrenCount, 0);

        node.AddChild(sprite);
        Tester.Match(node.ChildrenCount, 1);
        node.Update();

        node.RemoveAllChildren();
        Tester.Match(node.ChildrenCount, 0);

        node.Destroy();
    }
    public static void TestTween()
    {
        Roga2dNode node = new Roga2dNode();
        Roga2dAlphaInterval interval = new Roga2dAlphaInterval(node, 0.0f, 1.0f, 5, true);

        Tester.Ok(!interval.IsDone());

        interval.Start();
        Tester.Match(node.LocalAlpha, 0.0f);
        Tester.Ok(!interval.IsDone());

        interval.Update();
        Tester.Match(node.LocalAlpha, 0.2f);
        Tester.Ok(!interval.IsDone());

        interval.Update();
        Tester.Match(node.LocalAlpha, 0.4f);
        Tester.Ok(!interval.IsDone());

        interval.Update();
        Tester.Match(node.LocalAlpha, 0.6f);
        Tester.Ok(!interval.IsDone());

        interval.Update();
        Tester.Match(node.LocalAlpha, 0.8f);
        Tester.Ok(!interval.IsDone());

        interval.Update();
        Tester.Match(node.LocalAlpha, 1.0f);
        Tester.Ok(interval.IsDone());

        interval.Update();
        Tester.Match(node.LocalAlpha, 1.0f);
        Tester.Ok(interval.IsDone());

        interval.Reset();
        Tester.Match(node.LocalAlpha, 0.0f);
        Tester.Ok(!interval.IsDone());

        node.Destroy();
    }
    public static void TestTween()
    {
        Roga2dNode node = new Roga2dNode();

        Vector2 start = new Vector2(10.0f, 10.0f);
        Vector2 end = new Vector2(2.0f, 6.0f);
        Roga2dPositionIntervalOption option = Roga2dPositionIntervalOption.Build();
        Roga2dPositionInterval interval = new Roga2dPositionInterval(node, start, end, 4, true, option);

        Tester.Ok(!interval.IsDone());

        Tester.Match(node.LocalPosition, new Vector2(0.0f, 0.0f));
        Tester.Ok(!interval.IsDone());

        interval.Start();
        Tester.Match(node.LocalPosition, new Vector2(10.0f, 10.0f));
        Tester.Ok(!interval.IsDone());

        interval.Update();
        Tester.Match(node.LocalPosition, new Vector2(8.0f, 9.0f));
        Tester.Ok(!interval.IsDone());

        interval.Update();
        Tester.Match(node.LocalPosition, new Vector2(6.0f, 8.0f));
        Tester.Ok(!interval.IsDone());

        interval.Update();
        Tester.Match(node.LocalPosition, new Vector2(4.0f, 7.0f));
        Tester.Ok(!interval.IsDone());

        interval.Update();
        Tester.Match(node.LocalPosition, new Vector2(2.0f, 6.0f));
        Tester.Ok(interval.IsDone());

        interval.Reset();
        Tester.Match(node.LocalPosition, new Vector2(10.0f, 10.0f));
        Tester.Ok(!interval.IsDone());

        node.Destroy();
    }
    public static void TestTween()
    {
        Roga2dNode node = new Roga2dNode();

        Vector2 start = new Vector2(10.0f, 10.0f);
        Vector2 end = new Vector2(2.0f, 6.0f);
        Roga2dScaleInterval interval = new Roga2dScaleInterval(node, start, end, 4, true);

        Tester.Ok(!interval.IsDone());

        Tester.Match(node.LocalScale, new Vector2(1.0f, 1.0f));
        Tester.Ok(!interval.IsDone());

        interval.Start();
        Tester.Match(node.LocalScale, new Vector2(10.0f, 10.0f));
        Tester.Ok(!interval.IsDone());

        interval.Update();
        Tester.Match(node.LocalScale, new Vector2(8.0f, 9.0f));
        Tester.Ok(!interval.IsDone());

        interval.Update();
        Tester.Match(node.LocalScale, new Vector2(6.0f, 8.0f));
        Tester.Ok(!interval.IsDone());

        interval.Update();
        Tester.Match(node.LocalScale, new Vector2(4.0f, 7.0f));
        Tester.Ok(!interval.IsDone());

        interval.Update();
        Tester.Match(node.LocalScale, new Vector2(2.0f, 6.0f));
        Tester.Ok(interval.IsDone());

        interval.Reset();
        Tester.Match(node.LocalScale, new Vector2(10.0f, 10.0f));
        Tester.Ok(!interval.IsDone());

        node.Destroy();
    }
    public static void TestMixTween()
    {
        Roga2dNode node = new Roga2dNode();

        Roga2dAlphaInterval interval1 = new Roga2dAlphaInterval(node, 1.0f, 0.5f, 1, false);
        Roga2dAlphaInterval interval2 = new Roga2dAlphaInterval(node, 0.5f, 0.3f, 1, false);
        Roga2dAlphaInterval interval3 = new Roga2dAlphaInterval(node, 0.3f, 0.1f, 1, true);
        Roga2dAlphaInterval interval4 = new Roga2dAlphaInterval(node, 0.1f, 0.1f, 1, true);

        List<Roga2dBaseInterval> intervals = new List<Roga2dBaseInterval>();
        intervals.Add(interval1);
        intervals.Add(interval2);
        intervals.Add(interval3);
        intervals.Add(interval4);

        Roga2dSequence sequence = new Roga2dSequence(intervals);

        sequence.Start();
        Tester.Match(node.LocalAlpha, 1.0f);
        Tester.Ok(!sequence.IsDone());

        sequence.Update();
        Tester.Match(node.LocalAlpha, 0.5f);
        Tester.Ok(!sequence.IsDone());

        sequence.Update();
        Tester.Match(node.LocalAlpha, 0.3f);
        Tester.Ok(!sequence.IsDone());

        sequence.Update();
        Tester.Match(node.LocalAlpha, 0.1f);
        Tester.Ok(!sequence.IsDone());

        sequence.Update();
        Tester.Match(node.LocalAlpha, 0.1f);
        Tester.Ok(sequence.IsDone());

        node.Destroy();
    }
    public static void TestSetterGetter()
    {
        Roga2dNode node = new Roga2dNode();

        // Scale
        node.LocalScale = new Vector2(1.0f, 1.0f);
        Tester.Match(node.LocalScale, new Vector2(1.0f, 1.0f));

        // Position
        node.LocalPosition = new Vector2(1.0f, 1.0f);
        Tester.Match(node.LocalPosition, new Vector2(1.0f, 1.0f));
        Tester.Match(node.Position, new Vector2(1.0f, 1.0f));

        // Rotation
        node.LocalRotation = 30.0f;
        Tester.Match(node.LocalRotation, 30.0f);

        // Alpha
        node.LocalAlpha = 0.5f;
        Tester.Match(node.LocalAlpha, 0.5f);

        // Hue
        node.LocalHue = new Roga2dHue(100, 100, 100);
        Tester.Match(node.LocalHue, new Roga2dHue(100, 100, 100));

        // Priority
        node.LocalPriority = 0.5f;
        Tester.Match(node.LocalPriority, 0.5f);

        // BlendType
        node.BlendType = Roga2dBlendType.Add;
        Tester.Match(node.BlendType, Roga2dBlendType.Add);

        node.Destroy();
    }
    public static void TestVisibility()
    {
        Roga2dNode node1 = new Roga2dNode();
        Roga2dNode node2 = new Roga2dNode();

        node1.Hide();
        Tester.Match(node1.IsVisible, false);

        node1.AddChild(node2);
        Tester.Match(node2.IsVisible, false);

        node1.Hide();
        Tester.Match(node1.IsVisible, false);
        Tester.Match(node2.IsVisible, false);

        node1.Show();
        Tester.Match(node1.IsVisible, true);
        Tester.Match(node2.IsVisible, true);

        node1.Destroy();
        node2.Destroy();
    }
    public static void TestUpdate()
    {
        Roga2dNode node = new Roga2dNode();
        Roga2dNode child = new Roga2dNode();

        node.LocalAlpha = 0.3f;
        node.LocalPriority = 0.4f;
        node.LocalPosition = new Vector2(1.0f, 2.0f);
        node.LocalRotation = 3.0f;
        node.LocalScale = new Vector2(-1.0f, -2.0f);

        child.LocalAlpha = 0.3f;
        child.LocalPriority = 0.4f;
        node.AddChild(child);

        // Before transform
        Tester.Match(node.Alpha, 1.0f);
        Tester.Match(node.Priority, -999.0f);
        Tester.Match(child.Alpha, 1.0f);
        Tester.Match(child.Priority, -999.0f);

        node.Update();
        // After transform
        Tester.Match(node.Transform.localPosition, new Vector3(1.0f, 2.0f, 0.4f));
        Tester.Match(node.Transform.localEulerAngles, new Vector3(0.0f, 0.0f, 3.0f));
        Tester.Match(node.Transform.localScale, new Vector3(-1.0f, -2.0f, 1.0f));
        Tester.Match(node.Transform, child.Transform.parent);
        Tester.Match(node.Alpha, 0.3f);
        Tester.Match(node.Priority, 0.4f);
        Tester.Match(child.Alpha, 0.09f);
        Tester.Match(child.Priority, 0.8f);

        node.Destroy();
    }
 public void RemoveChild(Roga2dNode node)
 {
     if (node != null) {
         this.children.Remove(node);
         node.Destroy();
         nodeCount -= 1;
     }
 }
    public static void TestTween()
    {
        Roga2dNode node = new Roga2dNode();

        Roga2dAlphaInterval interval1 = new Roga2dAlphaInterval(node, 0.1f, 1.0f, 3, true);
        Roga2dWait interval2 = new Roga2dWait(2);
        Roga2dAlphaInterval interval3 = new Roga2dAlphaInterval(node, 0.7f, 0.0f, 2, true);

        List<Roga2dBaseInterval> intervals = new List<Roga2dBaseInterval>();
        intervals.Add(interval1);
        intervals.Add(interval2);
        intervals.Add(interval3);

        Roga2dSequence sequence = new Roga2dSequence(intervals);

        sequence.Start();
        Tester.Match(node.LocalAlpha, 0.1f);
        Tester.Ok(!sequence.IsDone());

        sequence.Update();
        Tester.Match(node.LocalAlpha, 0.4f);
        Tester.Ok(!sequence.IsDone());

        sequence.Update();
        Tester.Match(node.LocalAlpha, 0.7f);
        Tester.Ok(!sequence.IsDone());

        sequence.Update();
        Tester.Match(node.LocalAlpha, 1.0f);
        Tester.Ok(!sequence.IsDone());

        sequence.Update();
        Tester.Match(node.LocalAlpha, 1.0f);
        Tester.Ok(!sequence.IsDone());

        sequence.Update();
        Tester.Match(node.LocalAlpha, 1.0f);
        Tester.Ok(!sequence.IsDone());

        sequence.Update();
        Tester.Match(node.LocalAlpha, 0.35f);
        Tester.Ok(!sequence.IsDone());

        sequence.Update();
        Tester.Match(node.LocalAlpha, 0.0f);
        Tester.Ok(sequence.IsDone());

        sequence.Reset();
        Tester.Match(node.LocalAlpha, 0.1f);
        Tester.Ok(!sequence.IsDone());

        node.Destroy();
    }