
#ifndef TLAKE3D_MED_1_H_INCLUDED
#define TLAKE3D_MED_1_H_INCLUDED

/*
OBJET       classe d'un effet de lac bonne qualité

DATE        01/2026

AUTEUR      philippe Thebaud

COMMENTAIRE
*/

#include <GL/glew.h>
#include <string>
#include <vector>
#include <iostream>

#include "../ECO/OUtils.h"
#include "../ECO/OTexturelist.h"
#include "../ECO/shader/OShader.h"

#include "common.h"



class Tlake3d_med_1_sh : public OShader
{
public:

    Tlake3d_med_1_sh();

    bool        create();

    void        setVP(const OMat4& vp);
    void        setModel(const OMat4& model);
    void        setTextures(uint32_t refraction, uint32_t normal, uint32_t reflection, uint32_t dudv);
    void        setMulti(bool mode);

    void        setLight(float ambient, const OVec3_f& direction, const OVec3_f& color);
    void        setEyePos(const OVec3_f& EyePos);
    void        setTime(float value);
    void        setTurbidity(float value);
    void        setWaveStrength(float value);
    void        setWindSpeed(float value);

private:

    uint32_t    m_vp, m_model;
    uint32_t    m_dudvMap, m_normalMap, m_refractionMap, m_reflectionMap;
    uint32_t    m_multi;

    uint32_t    m_eyePos;
    uint32_t    m_turbidity;
    uint32_t    m_time;
    uint32_t    m_waveStrength, m_windSpeed;
    uint32_t    m_light_color, m_light_ambient, m_light_dir;
};

// pour la surface eau

class Tlake3d_med_1_shw : public OShader
{
public:

    Tlake3d_med_1_shw();

    bool        create();

    void        setVP(const OMat4& vp);
    void        setModel(const OMat4& model);

    void        setMulti(bool mode);

private:

    uint32_t    m_vp,m_model;
	uint32_t    m_multi;

};

// --- map / carte / plan ---

class Tlake3d_med_1_plan
{
public:

    Tlake3d_med_1_plan();
    ~Tlake3d_med_1_plan();

    void        addModel(std::string flux);
    void        addModel(float px, float py, float pz);

    void        create(uint32_t size, float scale_uv);
    void        create(std::string file);

    void        draw();
    void        draw_multi();

    OMat4&      getModel();
    size_t      getSize();
    bool        getVisible();

    void        setPos(OVec3_f& pos, size_t idx = 0);
    void        setPos(float px, float py, float pz, size_t idx = 0);
    void        setVisible(bool mode);

private:

    void        _make_vao();
    bool        _readLine(std::istream& flux);
    void        _skipLine(std::istream& flux);
    void        _setModel(size_t idx);

private:

    bool        m_visible;

    std::vector<OVec3_f>    m_pos;
    std::vector<OMat4>      m_model;
    std::vector<OMat4>      m_model_multi; // avec mat4 'horizontale'

    uint32_t                m_vao, m_vao_buffer[10];
    std::vector<uint32_t>   m_indice;
    std::vector<OVec3_f>    m_vertex;
    std::vector<OVec3_f>    m_normal;
    std::vector<OVec2_f>    m_uv;

};

// -----------------
// classe principale
// -----------------

class Tlake3d_med_1
{
public:

    Tlake3d_med_1();
    ~Tlake3d_med_1();

    void        create(int size, float scale_uv);
    void        create(std::string file_obj);

    void        draw(OMat4& vp, OVec3_f& eyePos, uint32_t reflectionMap);
    void        draw_water_reflection(OMat4& eyePos);

    void        setLight(float ambient, OVec3_f& dir, OVec3_f& color);

private:

    OTextureList        textureList;
    uint32_t            m_colorMap, m_normalMap, m_dudv;

public:

    Tlake3d_med_1_sh    shLake_med;
    Tlake3d_med_1_shw   shLake_med_w;
    Tlake3d_med_1_plan  plan;
};


#endif // TLAKE3d_MED_1_H_INCLUDED


