//#####################################################################
// Copyright 2021, Craig Schroeder.
// This file is part of PhysBAM whose distribution is governed by the license contained in the accompanying file PHYSBAM_COPYRIGHT.txt.
//#####################################################################
#ifndef __SHADER__
#define __SHADER__

#include <Core/Data_Structures/HASHTABLE.h>
#include <Core/Vectors/VECTOR.h>
#include "QT_RENDER_UTILS.h"
#include "QT_SHADER_FLAGS.h"
#include <QOpenGLFunctions>
#include <string>

QT_BEGIN_NAMESPACE
class QOpenGLShaderProgram;
class QObject;
QT_END_NAMESPACE

namespace PhysBAM{
class SHADER
{
public:
    typedef QT_RENDER_UTILS::RU_COLOR RU_COLOR;
    struct SH
    {
        const SHADER& shader;
        QOpenGLFunctions& gl;
        SH(const SHADER& shader,const QT_RENDER_UTILS& ru,SHADER_FLAGS flags);
        ~SH();

        template<class T>
        void Set_Uniform(const char* name,const T& v);
        template<class T>
        void Set_Uniform_Array(const char* name,const T* v,int length);
    };

    struct ATTR
    {
        SH& sh;
        GLint attr=-1;

        // Works for T=scalar or T=vector or T=matrix
        template<class T>
        ATTR(SH& sh,const char* name,ARRAY_VIEW<T> X,int part=0);
        ATTR(SH& sh,const char* name,const RU_COLOR& color);
        ~ATTR();
    };

    HASHTABLE<std::string,GLint> attrs;
    HASHTABLE<std::string,GLint> uniforms;

    typedef VECTOR<float,3> COLOR;
    
    QOpenGLShaderProgram *program = nullptr;
    SHADER_FLAGS flags;

    SHADER() = default;
    SHADER(QObject* obj,SHADER_FLAGS flags);
    ~SHADER();
    void Init(QObject* obj,SHADER_FLAGS flags_,bool use_pos,
        const ARRAY<std::pair<const char*,const char*>>& attr_list,
        const ARRAY<std::pair<const char*,const char*>>& uniform_list,
        const char* vs,const char* gs,const char* fs);
};
}

#endif
