// IAEngine: 2D Game Engine by IA
// Copyright (C) 2025 IASoft (PVT) LTD (oss@iasoft.dev)
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program.  If not, see <https://www.gnu.org/licenses/>.

#pragma once

#include <Renderer/Pipeline.hpp>
#include <Renderer/GPUResourceManager.hpp>

namespace ia::iae
{
    class Renderer
    {
      public:
        STATIC CONSTEXPR FLOAT32 MIN_DEPTH = -2097152.0f;
        STATIC CONSTEXPR FLOAT32 MAX_DEPTH = 2097152.0f;

        struct Geometry
        {
            INT32 IndexCount{};
            SDL_GPUBuffer *IndexBuffer;
            SDL_GPUBuffer *VertexBuffer;
        };

        struct State
        {
            BOOL FlippedH{false};
            BOOL FlippedV{false};
            BOOL CameraRelative{true};
            BOOL YSortingEnabled{false};
            Color ColorOverlay{};
            Vec2 TextureOffset{0.0f, 0.0f};
            SDL_Rect Scissor{0, 0, 0, 0};
            SDL_GPUTexture* ActiveTexture{nullptr};
            SDL_GPUViewport ActiveViewport{};
            Vec2 SceneScaleFactor{1.0f, 1.0f};
            
            Mat4 ModelMatrix{1.0f};

            SDL_GPURenderPass* ActiveRenderPass{};
            SDL_GPUCommandBuffer* ActiveCommandBuffer{};
            SDL_GPUColorTargetInfo ColorTargetInfo{};
            SDL_GPUDepthStencilTargetInfo DepthStencilTargetInfo{};

            class CameraComponent *ActiveCamera{};
        };

      public:
        STATIC VOID Initialize();
        STATIC VOID Terminate();

        STATIC VOID BeginFrame();
        STATIC VOID EndFrame();

        STATIC VOID WaitForGPUIdle();

        STATIC VOID OnScreenResize(IN INT32 newWidth, IN INT32 newHeight);

      public:
        STATIC Geometry* CreateGeometry(IN CONST Vector<GeometryVertex> &vertices, IN CONST Vector<INT32> &indices);
        STATIC VOID DestroyGeometry(IN Geometry* handle);

        STATIC VOID DrawGeometry(IN Geometry* handle);

        STATIC SDL_GPUTextureFormat GetRenderTargetFormat();

        STATIC SDL_GPUDevice *GetDevice()
        {
            return s_gpuDevice;
        }

      private:
        STATIC State s_state;
        STATIC INT32 s_screenWidth;
        STATIC INT32 s_screenHeight;
        STATIC SDL_GPUDevice *s_gpuDevice;
        STATIC SDL_GPUTexture *s_renderTargetSceneColor;
        STATIC SDL_GPUTexture *s_renderTargetSceneDepth;
        STATIC SDL_GPUTexture *s_renderTargetDebugDrawColor;
        STATIC Pipeline* s_geometryPipeline;
        STATIC Pipeline* s_postprocessPipeline;
        STATIC Geometry* s_quadGeometry;

        friend class Engine;
    };
} // namespace ia::iae