using NUnit.Framework;
using FluentAssertions;

using System;
using System.Collections.Generic;
using System.Text;

using Encompass;

namespace Tests
{
    public class WorldTest
    {
        struct TestComponent : IComponent { }
        struct TestDrawComponent : IComponent, IDrawableComponent
        {
            public int Layer { get; set; }
        }

        static List<object> drawOrder = new List<object>();

        class TestEntityRenderer : OrderedRenderer<TestDrawComponent>
        {
            public override void Render(Entity entity, TestDrawComponent testDrawComponent)
            {
                drawOrder.Add(entity);
            }
        }

        class TestGeneralRenderer : GeneralRenderer
        {
            public override void Render()
            {
                drawOrder.Add(this);
            }
        }

        [Test]
        public void DrawOrder()
        {
            var worldBuilder = new WorldBuilder();
            worldBuilder.RegisterDrawLayer(1);
            worldBuilder.RegisterDrawLayer(2);
            worldBuilder.RegisterDrawLayer(3);
            worldBuilder.RegisterDrawLayer(4);
            worldBuilder.RegisterDrawLayer(7);

            worldBuilder.AddOrderedRenderer(new TestEntityRenderer());
            var testGeneralRenderer = worldBuilder.AddGeneralRenderer(new TestGeneralRenderer(), 7);

            TestComponent testComponent;
            TestDrawComponent drawComponentThree = new TestDrawComponent { Layer = 3 };
            var drawComponentTwo = new TestDrawComponent { Layer = 2 };
            var drawComponentOne = new TestDrawComponent { Layer = 1 };
            var drawComponentFour = new TestDrawComponent { Layer = 4 };

            var entity = worldBuilder.CreateEntity();
            worldBuilder.SetComponent(entity, testComponent);
            worldBuilder.SetComponent(entity, drawComponentThree);

            var entityTwo = worldBuilder.CreateEntity();
            worldBuilder.SetComponent(entityTwo, testComponent);
            worldBuilder.SetComponent(entityTwo, drawComponentTwo);

            var entityThree = worldBuilder.CreateEntity();
            worldBuilder.SetComponent(entityThree, testComponent);
            worldBuilder.SetComponent(entityThree, drawComponentThree);

            var entityFour = worldBuilder.CreateEntity();
            worldBuilder.SetComponent(entityFour, testComponent);
            worldBuilder.SetComponent(entityFour, drawComponentFour);

            var world = worldBuilder.Build();

            world.Update(0.01f);
            world.Draw();

            drawOrder.Should().BeEquivalentTo(entityFour, entityTwo, entity, entityThree, testGeneralRenderer);
        }
    }
}