//
// Created by sebastian on 29.07.26.
//

#ifndef COLORRACE_UNIFORMVALUE_H
#define COLORRACE_UNIFORMVALUE_H
#include "glad/glad.h"
#include <glm/glm.hpp>

#include "Uniform.h"

namespace engine::detail {
    inline void glUniformLoad(int loc, float v)       { glUniform1f(loc, v); }
    inline void glUniformLoad(int loc, int v)         { glUniform1i(loc, v); }
    inline void glUniformLoad(int loc, bool v)        { glUniform1i(loc, v ? 1 : 0); }
    inline void glUniformLoad(int loc, const glm::vec2& v) { glUniform2f(loc, v.x, v.y); }
    inline void glUniformLoad(int loc, const glm::vec3& v) { glUniform3f(loc, v.x, v.y, v.z); }
    inline void glUniformLoad(int loc, const glm::vec4& v) { glUniform4f(loc, v.x, v.y, v.z, v.w); }
    inline void glUniformLoad(int loc, const glm::mat4& m) { glUniformMatrix4fv(loc, 1, GL_FALSE, &m[0][0]); }
}

namespace engine {
    template<typename T>
    class UniformValue : public Uniform {
    public:
        explicit UniformValue(std::string name) : Uniform(std::move(name)) {}

        void load(const T& value) {
            if (m_used && m_currentValue == value) {
                return;
            }
            detail::glUniformLoad(getLocation(), value);
            m_currentValue = value;
            m_used = true;
        }
    private:
        T m_currentValue{};
        bool m_used = false;
    };
}

#endif //COLORRACE_UNIFORMVALUE_H
