using System;
using System.Collections.Generic;
using Encompass;
using Kav;
using KavTest.Components;
using Microsoft.Xna.Framework.Graphics;

namespace KavTest.Renderers
{
    public class SceneRenderer : GeneralRenderer
    {
        private GraphicsDevice GraphicsDevice { get; }

        private IEnumerable<Kav.Model> Models
        {
            get
            {
                foreach (var entity in ReadEntitiesAsEnumerable<ModelComponent>())
                {
                    var transformComponent = GetComponent<Transform3DComponent>(entity);
                    var modelComponent = GetComponent<ModelComponent>(entity);

                    modelComponent.Model.ApplyTransform(transformComponent.Transform.TransformMatrix);
                    yield return modelComponent.Model;
                }
            }
        }

        private IEnumerable<PointLight> PointLights
        {
            get
            {
                foreach (var entity in ReadEntitiesAsEnumerable<PointLightComponent>())
                {
                    var transformComponent = GetComponent<Transform3DComponent>(entity);
                    var pointLightComponent = GetComponent<PointLightComponent>(entity);

                    yield return new PointLight(
                        transformComponent.Transform.TransformMatrix.Translation,
                        pointLightComponent.Color,
                        pointLightComponent.Intensity
                    );
                }
            }
        }

        public SceneRenderer(GraphicsDevice graphicsDevice)
        {
            GraphicsDevice = graphicsDevice;
        }

        public override void Render()
        {
            if (SomeComponent<CameraComponent>())
            {
                var cameraEntity = ReadEntity<CameraComponent>();
                var transformComponent = GetComponent<Transform3DComponent>(cameraEntity);
                var cameraComponent = GetComponent<CameraComponent>(cameraEntity);

                var camera = new Kav.Camera(
                    transformComponent.Transform.TransformMatrix,
                    cameraComponent.Projection
                );

                Kav.Renderer.Render(
                    GraphicsDevice,
                    camera,
                    Models,
                    PointLights
                );
            }
        }
    }
}
