
#ifndef TFLAG_MED_H_INCLUDED
#define TFLAG_MED_H_INCLUDED

/*
OBJET       classe d'un drapeau de bonne qualité flottant au vent

DATE        02/2026

AUTEUR      philippe Thebaud

COMMENTAIRE ajoutez les normales si vu de près
*/

#include <GL/glew.h>
#include <string>
#include <vector>
#include <deque>
//#include <cstring> //memcopy pour VBO
#include <iostream>

#include "../ECO/OUtils.h"
//#include "OTextureList.h"
#include "../ECO/OMesh_obj.h"
#include "../ECO/defered/ODshGeo.h"

#include "common.h"


#include "../ECO/defered/ODshader.h"


class TDshFlag_med : public ODshader
{
public:

    TDshFlag_med();

    bool        create();

    void        setVP(const OMat4& vp);
    void        setTexture(uint32_t texture);

private:

    uint32_t    m_vp;
	uint32_t    m_colorMap; //, m_normalMap, m_specularMap;

};

class TDshFlag_med_cpt0 : public ODshader
{
public:

    TDshFlag_med_cpt0();

    bool        create();

    void        setWind(float speed, float dir);
    void        setColRow(uint32_t col, uint32_t row);

private:

	uint32_t    m_wind_speed, m_wind_dir;
	uint32_t    m_vertexCount;
};

class TDshFlag_med_cpt1 : public ODshader
{
public:

    TDshFlag_med_cpt1();

    bool        create();

    void        setRestLength(float value);
    void        setColRow(uint32_t col, uint32_t row);

private:

	uint32_t    m_restLength;
	uint32_t    m_col, m_row;

};

class TDshFlag_med_norm : public ODshader
{
public:

    TDshFlag_med_norm();

    bool        create();

    void        setColRow(uint32_t col, uint32_t row);

private:

	uint32_t    m_col, m_row;
};




class Tflag_med
{
public:

	Tflag_med();
    ~Tflag_med();

    void        addModel(std::string flux);

    void        create(std::string file);

    void        draw(const OMat4& vp, ODshGeo& dshGeo);

    void        setWind(float strength, float dir);

private:

    void        _clear();
    void        _composition();

    void        _generate_flag();

    uint32_t    _load_texture(std::string file);

    void        _make_vao();
    void        _make_vao_compute();

    void        _setModel(size_t idx);

private:

    // --- le mat/pole = base
    std::string m_code, m_file, m_path;
    OMesh_obj   mesh;

    std::vector<OVec3_f> m_pos;
    std::vector<OVec3_f> m_rot;
    std::vector<OVec3_f> m_scale;
	std::vector<OMat4>   m_model_multi;

    // --- le drapeau

    TDshFlag_med        dshFlag;
    TDshFlag_med_cpt0   dshFlag_cpt0;
    TDshFlag_med_cpt1   dshFlag_cpt1;
    //TDshFlag_med_norm   dshFlag_norm;

    // pour isoler les données du drapeau
    static const int nbr_vao_buffer = 8;
    static const int nbr_vao_compute_buffer = 2;

    struct s_flag
    {
        OVec3_f     decal_pos;
        float       width, height;
        int         nbCol, nbRow;
        std::string img_tex; //, img_bump;
        //
        uint32_t                vao, vao_buffer[nbr_vao_buffer];
        std::vector<OVec3_f>    vertex;
        std::vector<OVec3_f>    normal;
        std::vector<OVec2_f>    uv;
        std::vector<unsigned>   indice;
        uint32_t                tex_image; //, tex_bump;
        std::vector<OMat4>      model_multi;

        // ---

        uint32_t                vao_compute, vao_compute_buffer[nbr_vao_compute_buffer];
        std::vector<OVec4_f>    cpt_pos;
        std::vector<OVec4_f>    cpt_pos_prev;
        std::vector<OVec3_f>    cpt_norm; // OVec4_f
        uint32_t                groups;
    };
    s_flag m_flag;


};

#endif
