#pragma once
#include <SDL.h>
#include <SDL_image.h>
#include <glad/glad.h>
#include <glm/glm.hpp>
#include <glm/ext/matrix_clip_space.hpp>
#include <glm/gtc/type_ptr.hpp>
#include <map>
#include <string>
#include <json.hpp>
#include "EngineFrame/Render/Texture.h"
class RenderManager
{
public:
    // 绘制纹理的逻辑函数
    using DrawLogicFunc = std::function<void(RefPtr<Texture>, const SDL_Rect *, const SDL_FRect *,
                                             double, const SDL_FPoint *, SDL_RendererFlip,
                                             void *)>;

    struct GL_RenderParams
    {
        GLuint VAO;
        GLuint VBO;
        GLuint EBO;
        std::vector<GLuint> UnimLocs;
        DrawLogicFunc DrawFunc = nullptr;
    };

private:
    SDL_Window *_window;
    // 窗口尺寸
    int _windowWidth;
    int _windowHeight;
    // 游戏正交投影矩阵
    glm::mat4 _GameOrthoMatrix;
    // UI的正交投影矩阵
    glm::mat4 _UIOrthoMatrix;
    // 渲染的正交投影矩阵
    glm::mat4 _OrthoMatrix;

    // 渲染器上下文
    SDL_GLContext _ctx;
    // 着色器程序
    std::map<std::string, GLuint> _shaderProgramMap;
    // 渲染参数
    std::map<std::string, GL_RenderParams> _RenderParamsMap;

    // 当前使用着色器程序
    GLuint _currentShaderProgram;
    // 当前使用渲染参数
    GL_RenderParams _currentRenderParams;

public:
    // 单帧渲染调用次数
    int _frameRenderCount = 0;
public:
    RenderManager(SDL_Window *window);
    ~RenderManager();

    // 初始化着色器程序
    void InitShaderProgram();
    // 初始化绘制2D纹理缓冲程序
    void Init2DTextureProgram();
    // 设定当前使用的着色器程序
    void SetCurrentShaderProgram(std::string name);
    // 设定当前使用的缓冲对象
    void SetCurrentBufferObject(std::string name);

    // 清空屏幕
    void ClearScreen();
    // 交换缓冲区
    void SwapBuffer();
    // 设置裁切区域
    void SetClipRect(const SDL_Rect *rect);
    // 关闭裁切区域
    void CloseClipRect();
    // 绘制纹理
    void DrawTexture(RefPtr<Texture> texture, const SDL_Rect *srcrect, const SDL_FRect *dstrect, const double angle, const SDL_FPoint *center, const SDL_RendererFlip flip, void *userdata = nullptr);
    // 设置正交投影矩阵类型
    void SetOrthoMatrixType(int type);


private:
    // 编译着色器
    GLuint CompileShader(GLenum type, std::string Path);
    // 新增缓冲程序
    void AddBufferObject(std::string name, GL_RenderParams bufferObject);
};
