#pragma once
#include "bgfx/defines.h"
#include <bgfx/bgfx.h>
#include <bx/string.h>
#include <cstdint>

#include "../Gen.h"
#include "../Global.h"
#include "Dither.h"

union SDL_Event;

namespace Game
{
    struct PosColorVertex
    {
        float x;
        float y;
        float z;
        float n_x;
        float n_y;
        float n_z;
        uint32_t abgr;
        float uv_x;
        float uv_y;
    };

    struct Texture
    {
        bgfx::UniformHandle SamplerHandle = {bgfx::kInvalidHandle};
        bgfx::TextureHandle RenderHandle = {bgfx::kInvalidHandle};
        bgfx::TextureInfo Info;
        Generated::TextureHandle TexHandle;
    };

    struct Model
    {
        bgfx::VertexBufferHandle VertexBuffer = {bgfx::kInvalidHandle};
        bgfx::IndexBufferHandle IndexBuffer = {bgfx::kInvalidHandle};
        bgfx::VertexLayout VertLayout;
        Generated::ModelHandle Handle;
    };

    struct Material
    {
        enum UniformNames : uint32_t
        {
            UTime = 0,
            UDotColor = 1,
            UTexInfo = 2,
            UBaseColor = 3,
        };

        bgfx::ProgramHandle Shader;
        bgfx::UniformHandle Uniforms[8];
        uint64_t State = 0;
        uint32_t ViewID = 0;
        static Material LoadFromShader(const char* vertPath, const char* fragPath, uint16_t view);
    };

    enum class UIVisibilityState
    {
        None,
        Game,
        Debug,
    };

    enum class EMaterial : uint16_t
    {
        Default = 0,
        UI = 1,
        UNDEFINED = UINT16_MAX
    };

    class GameRendering
    {
      public:
        static constexpr uint32_t MaxModels = 64;
        static constexpr uint32_t MaxTextures = 64;
        static GameRendering& Get();

      public:
        UIVisibilityState UIVisible = UIVisibilityState::Game;
        DitherData DitherTextures;

      public:
        bgfx::UniformHandle DefaultSampler;
        Texture Textures[MaxTextures];
        Material Materials[8];
        uint32_t ModelCount = 0;
        Model Models[MaxModels];
        int32_t LastWidth = 0;
        int32_t LastHeight = 0;
        uint32_t ResetFlags = BGFX_RESET_VSYNC;
        uint16_t MainViewID = 10;
        float LastShaderLoadTime = 0.0f;
        int32_t DitherRecursion = 1;
        Vec4 DefaultBaseColor;
        Vec4 DefaultTileColor;

      public:
        void Setup();
        void Update();
        void HandleEvents();
        void LoadTextures();
        void ReloadShaders();
        void Shutdown();
        Generated::ModelHandle GetModelHandleFromPath(const char* path);
    };
} // namespace Game
