//
// Created by sfd on 25-4-24.
//

#ifndef OPENGLSHADER_H
#define OPENGLSHADER_H
#include <Hazel/Renderer/Shader.h>

#include "glm/fwd.hpp"
#include "glm/vec4.hpp"
#include <glad/glad.h>


namespace Hazel
{
    class HAZEL_API OpenGLShader : public Shader
    {
    public:
        OpenGLShader(const std::string& filepath);
        OpenGLShader(const std::string& name, const std::string& vertexSrc, const std::string& fragmentSrc);
        virtual ~OpenGLShader() override;

        void Bind() const override;
        void Unbind() const override;

        virtual const std::string& GetName() const override {return m_Name;}

        virtual void SetFloat(const std::string& name, float value) override;
        virtual void SetFloat3(const std::string& name, const glm::vec3& value) override;
        virtual void SetFloat4(const std::string& name, const glm::vec4& value) override;
        virtual void SetMat3(const std::string& name, const glm::mat3& value) override;
        virtual void SetMat4(const std::string& name, const glm::mat4& value) override;
        virtual void SetInt(const std::string& name, int value) override;
        virtual void SetIntv(const std::string& name, int* values, uint32_t count) override;

        void UploadUniformInt(const std::string& name, int value) const;
        void UploadUniformIntv(const std::string& name, int* values, uint32_t count) const;

        void UploadUniformFloat(const std::string& name, float value) const;
        void UploadUniformFloat3(const std::string& name, const glm::vec3& value) const;
        void UploadUniformFloat4(const std::string& name, const glm::vec4& value) const;
        void UploadUniformMat3(const std::string& name, const glm::mat3& matrix) const;
        void UploadUniformMat4(const std::string& name, const glm::mat4& matrix) const;

    private:
        std::string ReadFile(const std::string& filepath);
        std::unordered_map<GLenum, std::string> PreProcess(const std::string& source);
        void Compile(std::unordered_map<GLenum, std::string>& shaderSource);

    private:
        uint32_t m_RendererID;
        std::string m_Name;
    };
}


#endif //OPENGLSHADER_H
