#pragma once

#include <string>
#include <map>
#include <glad/glad.h>
#include <glm/glm.hpp>
#include <glm/gtc/type_ptr.hpp>

/**
 * @brief OpenGL着色器程序封装类。
 * * 这是一个基础类，用于管理OpenGL着色器程序，包括统一变量(uniform)的设置和缓存。
 * 考虑到继承性，析构函数被设置为虚函数。
 */
class VIVID_2D_MYDLL_API ShaderProgram
{
public:
    // 构造函数
    explicit ShaderProgram(GLuint programId);

    // 虚析构函数，确保派生类能正确清理资源
    virtual ~ShaderProgram();

    // 启用着色器程序
    void use() const;

    // 停止使用着色器程序
    void stop() const;

    // 获取统一变量(uniform)位置，并缓存结果
    GLint getUniformLocation(const std::string& name);

    // --- uniform 设置方法 (使用 name) ---
    void setUniform1i(const std::string& name, GLint value);
    void setUniform1f(const std::string& name, GLfloat value);
    void setUniform2f(const std::string& name, GLfloat x, GLfloat y);
    void setUniform3f(const std::string& name, GLfloat x, GLfloat y, GLfloat z);
    void setUniform4f(const std::string& name, GLfloat x, GLfloat y, GLfloat z, GLfloat w);

    // 使用 glm::mat3
    void setUniformMatrix3(const std::string& name, const glm::mat3& matrix);

    // --- uniform 设置方法 (使用 location) ---
    void setUniform1i(GLint location, GLint value);
    void setUniform1f(GLint location, GLfloat value);
    void setUniform4f(GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
    void setUniformMatrix3(GLint location, const glm::mat3& matrix);

    // 清理OpenGL资源
    void deleteProgram();

    // 获取程序ID
    GLuint getProgramId() const { return m_programId; }

protected:
    const GLuint m_programId;
    std::map<std::string, GLint> m_uniformCache;
};