#ifndef CSHADER_HPP
#define CSHADER_HPP

#include <string>
#include <glm/glm.hpp>

/**
 * @file CShader.hpp
 * @brief File of CShader, a class to manage complete shader program, composed of a vertex shader,
 * a fragment shader and sometime a geometry shader.
 */

/**
 * @brief Class to manage complete shader program, composed of a vertex shader,
 * a fragment shader and sometime a geometry shader.
 */
class CShader {
public:
    virtual ~CShader();
    /**
     * @brief Get the id of the shader.
     * @return unsigned int, the id.
     */
    virtual unsigned int getId(void) const = 0;

    /**
     * @brief Get the name of the shader.
     * @return std::string, the name.
     */
    virtual std::string getName(void) const = 0;

    /**
     * @brief Get the vertex of the shader.
     * @return std::string, the path.
     */
    virtual std::string getVertexPath(void) const = 0;

    /**
     * @brief Get the geometry of the shader.
     * @return std::string, the path.
     */
    virtual std::string getGeomPath(void) const = 0;

    /**
     * @brief Get the fragment of the shader.
     * @return std::string, the path.
     */
    virtual std::string getFragmentPath(void) const = 0;

    /**
     * @brief set the name of the shader.
     * @param[in] name the name.
     */
    virtual void setName(std::string name) = 0;

    /**
     * @brief Get the vertex source path of the shader.
     * @param[in] vp the path.
     */
    virtual void setVertexPath(std::string vp) = 0;

    /**
     * @brief Get the geometry source path of the shader.
     * @param[in] gp the path.
     */
    virtual void setGeomPath(std::string gp) = 0;

    /**
     * @brief Get the fragment source path of the shader.
     * @param[in] fp the path.
     */
    virtual void setFragmentPath(std::string fp) = 0;

    /**
     * @brief Return true if the shader is ready to use (compiled and linked).
     * @return bool.
     */
    virtual bool isReady(void) const = 0;

    /**
     * @brief Return true if the shader program has a geometry shader.
     * @return bool.
     */
    virtual bool hasGeom(void) const = 0;

    /**
     * @brief Set this shader as active, so it will be used for the next draw.
     */
    virtual void use(void) = 0;

    /**
     * @brief Init the shader to make it ready to use (read the fiel, compile, link...).
     */
    virtual void init(void) = 0;

    /**
     * @brief give a const value to a shader.
     * @param[in] name The name of the uniform constant.
     * @param[in] value The value.
     */
    virtual void setBool(const std::string& name, bool value) const = 0;

    /**
     * @brief give a const value to a shader.
     * @param[in] name The name of the uniform constant.
     * @param[in] value The value.
     */
    virtual void setInt(const std::string& name, int value) const = 0;

    /**
     * @brief give a const value to a shader.
     * @param[in] name The name of the uniform constant.
     * @param[in] value The value.
     */
    virtual void setFloat(const std::string& name, float value) const = 0;

    /**
     * @brief give a const value to a shader.
     * @param[in] name The name of the uniform constant.
     * @param[in] value The value.
     */
    virtual void setMat2(const std::string& name, glm::mat2 value) const = 0;

    /**
     * @brief give a const value to a shader.
     * @param[in] name The name of the uniform constant.
     * @param[in] value The value.
     */
    virtual void setMat3(const std::string& name, glm::mat3 value) const = 0;

    /**
     * @brief give a const value to a shader.
     * @param[in] name The name of the uniform constant.
     * @param[in] value The value.
     */
    virtual void setMat4(const std::string& name, glm::mat4 value) const = 0;

    /**
     * @brief give a const value to a shader.
     * @param[in] name The name of the uniform constant.
     * @param[in] value The value.
     */
    virtual void setVec2(const std::string& name, glm::vec2 value) const = 0;

    /**
     * @brief give a const value to a shader.
     * @param[in] name The name of the uniform constant.
     * @param[in] value The value.
     */
    virtual void setVec3(const std::string& name, glm::vec3 value) const = 0;

    /**
     * @brief give a const value to a shader.
     * @param[in] name The name of the uniform constant.
     * @param[in] value The value.
     */
    virtual void setVec4(const std::string& name, glm::vec4 value) const = 0;
};
#endif