﻿using Nemesis.Rendering.View.Projection;
using OpenTK;

namespace Nemesis.Rendering.View
{
    internal sealed class ViewportView : IView
    {
        const float orthographicHeight = 50.0f;

        private readonly Viewport viewport;
        private readonly IProjection projection;

        private Vector3 center;
        private float scale = 1.0f;

        public ViewportView(Viewport viewport)
        {
            this.viewport = viewport;
            this.projection = new OrthographicProjection(orthographicHeight, 0.0f, 1.0f);
        }

        public void SetCenterAndScale(Vector2 pointInNDC, float scale)
        {
            var pointInCameraSpace = FromNdcToCameraSpace(pointInNDC);
            this.center = new Vector3(pointInCameraSpace.X, pointInCameraSpace.Y, 0.0f);
            this.scale = scale;
        }

        private Vector2 FromNdcToCameraSpace(Vector2 pointInNDC)
        {
            var projectionWidth = orthographicHeight * viewport.Aspect;

            return new Vector2(
                pointInNDC.X * projectionWidth / 2.0f,
                pointInNDC.Y * orthographicHeight / 2.0f);
        }

        Matrix4 IView.GetViewMatrix()
        {
            return Matrix4.CreateScale(scale) * Matrix4.CreateTranslation(center);
        }

        Matrix4 IView.GetProjectionMatrix()
        {
            return projection.GetProjectionMatrix(viewport.Aspect);
        }
    }
}
