
#include "Tobjet.h"

// -----------------------
// --- le constructeur ---
// -----------------------

Tobjet::Tobjet()
{
	//
}

// ----------------------
// --- le destructeur ---
// ----------------------

Tobjet::~Tobjet()
{
    //
}


// --------------------
// --- les méthodes ---
// --------------------

void Tobjet::create(std::string flux)
{
    std::vector<std::string> strList;
    std::string sep;

    strList = ECO_strCut(flux, ' ');

    m_code = strList[0];
    //
    m_pos.x = ECO_strToFloat(strList[2]);
    m_pos.y = ECO_strToFloat(strList[3]);
    m_pos.z = ECO_strToFloat(strList[4]);
    m_rot.x = ECO_strToFloat(strList[5]);
    m_rot.y = ECO_strToFloat(strList[6]);
    m_rot.z = ECO_strToFloat(strList[7]);
    m_scale = ECO_strToFloat(strList[8]);
    // 9
    m_conteneur = strList[10];
    m_quantite  = ECO_strToInt(strList[11]);
    m_emplacement = ECO_strToInt(strList[12]);
    //

    _composition();
    _setModel();
}

void Tobjet::create(std::ifstream& flux)
{
    std::string sep;

    flux >> m_code >> sep;
    flux >> m_pos.x >> m_pos.y >> m_pos.z;
    flux >> m_rot.x >> m_rot.y >> m_rot.z >> m_scale >> sep;
    flux >> m_conteneur >> m_quantite >> m_emplacement >> sep;

    _composition();
    _setModel();
}

void Tobjet::_composition()
{
    m_idxCatalogue = -1;
    for (size_t i = 0; i < ECO_sizeOf(gl_catalogue_objet); i++)
    {
        if (m_code == gl_catalogue_objet[i].code)
        {
            m_idxCatalogue = i;
            break;
        }
    }
    if (m_idxCatalogue == -1)
    {
        ECO_error_set("erreur catalogue %s >Tobjet.composition0", m_code.c_str());
        m_conteneur = CONTENEUR_DETRUIT;
        return;
    }

    // s'il y a un mesh
    //if (ECO_fileExist(PATH_MESH + gl_catalogue_objet[m_idxCatalogue].path + gl_catalogue_objet[m_idxCatalogue].file))
    if (gl_catalogue_objet[m_idxCatalogue].file != "null")
    {
        OMesh_gltf::P_setPath(PATH_MESH + gl_catalogue_objet[m_idxCatalogue].path);

        if (!mesh.create(gl_catalogue_objet[m_idxCatalogue].file))
        {
            ECO_error_set("echec chargement %s >Tobjet.composition1", gl_catalogue_objet[m_idxCatalogue].file.c_str());
            m_conteneur = CONTENEUR_DETRUIT;
        }
        m_bound_min = mesh.getBound_min();
        m_bound_max = mesh.getBound_max();
    }
    // mesh generique en position 0,0,-10
/*
    OVec3_f b;
    ECO_error_set("%s", gl_catalogue_objet[m_idxCatalogue].file.c_str());
    b = mesh.getBound_min();
    ECO_error_set("min %f %f %f", b.x, b.y, b.z);
    b = mesh.getBound_max();
    ECO_error_set("max %f %f %f", b.x, b.y, b.z);
*/
    // ---

    m_select = false;
}




void Tobjet::draw(ODshGeo& dshGeo)
{
    if (m_conteneur != CONTENEUR_NULL) return;

    if (m_cull_face)
        glEnable(GL_CULL_FACE);
    else
        glDisable(GL_CULL_FACE);

    dshGeo.enable();
    dshGeo.setModel(m_model);
    dshGeo.setMaskValue(m_select * PPOUTLINE_AMBER);

    for (size_t i_par = 0; i_par < mesh.getPart_size(); i_par++)
    {
        dshGeo.setTextures( mesh.getId_diffuseMap(i_par), mesh.getId_normalMap(i_par), mesh.getId_specularMap(i_par));
        mesh.draw(i_par);
    }
    mesh.end_draw_part();

    dshGeo.setMaskValue(false);

    //glEnable(GL_CULL_FACE);
}

void Tobjet::draw_emissive(OShGlow& shGlow)
{
    if (m_conteneur != CONTENEUR_NULL) return;

    // activer > glDepthFunc(GL_EQUAL); finir par glDepthFunc(GL_LESS);
    shGlow.enable();
        shGlow.setModel(m_model);

    if (m_cull_face)
        glEnable(GL_CULL_FACE);
    else
        glDisable(GL_CULL_FACE);

    //glDepthFunc(GL_EQUAL);
    for (size_t i_par = 0; i_par < mesh.getPart_size(); i_par++)
    {
        // color rgb et a = energie
        if (mesh.getEmissive(i_par).a > 0.0f)
        {
            //shGlow.setTexture( mesh.getId_diffuseMap(i_par) );
            shGlow.setTexture( mesh.getId_emissiveMap(i_par) );
            mesh.draw(i_par);
        }
    }
    mesh.end_draw_part();
}





OVec3_f Tobjet::getBound_min()
{
    return m_bound_min;
}

OVec3_f Tobjet::getBound_max()
{
    return m_bound_max;
}

int Tobjet::getCatalogue_ref()
{
    return m_idxCatalogue;
}

std::string Tobjet::getCode()
{
    return m_code;
}

std::string Tobjet::getConteneur()
{
    return m_conteneur;
}

int Tobjet::getEmplacement()
{
    return m_emplacement;
}

OMesh_gltf& Tobjet::getMesh()
{
    return mesh;
}

OMat4& Tobjet::getModel()
{
    return m_model;
}

std::string Tobjet::getObjet3d()
{
    return gl_catalogue_objet[m_idxCatalogue].file;
}

std::string Tobjet::getPath()
{
    return gl_catalogue_objet[m_idxCatalogue].path;
}

float Tobjet::getPoids()
{
    return gl_catalogue_objet[m_idxCatalogue].weight;
}
OVec3_f& Tobjet::getPos()
{
    return m_pos;
}

int Tobjet::getQuantity()
{
    return m_quantite;
}
/*
std::string Tobjet::getReference()
{
    return m_reference;
}
*/
OVec3_f& Tobjet::getRot()
{
    return m_rot;
}

bool Tobjet::getSelect()
{
    return m_select;
}

int Tobjet::getType()
{
    return gl_catalogue_objet[m_idxCatalogue].type;
}




void Tobjet::incQuantity(int nbr)
{
    m_quantite += nbr;
    if (m_quantite < 0) m_quantite = 0;
}
void Tobjet::setQuantity(int nbr)
{
    m_quantite = nbr;
}

/*
void Tobjet::pick_color(OShColor3d& shPicking, uint32_t& refColor)
{
    glDisable(GL_CULL_FACE);

    shPicking.setModel(m_model);
    shPicking.setColor(refColor);

    mesh.draw_no_texture();

    refColor++;
}
*/



void Tobjet::setConteneur(std::string code)
{
    m_conteneur = code;
    if (code == CONTENEUR_NULL || code == CONTENEUR_DETRUIT)
    {
        m_emplacement = -1; //EMP_NULL
    }
}

void Tobjet::setEmplacement(int local)
{
    //EMP_NULL = -1,
    // s_attache[0] ...
    //EMP_TETE, EMP_BRAS_G, EMP_MAIN_D,
    //
    //EMP_CEINTURE, EMP_SAC,
    m_emplacement = local;
}

void Tobjet::_setModel()
{
    m_model.loadIdentity();
    m_model.translate(m_pos);
    m_model.rotate(m_rot.z, 0, 0, 1);
    m_model.rotate(m_rot.y, 0, 1, 0);
    m_model.rotate(m_rot.x, 1, 0, 0);
    //m_model.scale(m_scale);

    // ma verticale si verticale objet = y => converti en z
    m_model.rotate(90, 1,0,0);
}

void Tobjet::setPos(OVec3_f& pos)
{
	m_pos = pos;
	_setModel();
}

void Tobjet::setRot(OVec3_f& rot)
{
	m_rot = rot;
	_setModel();
}

void Tobjet::setSelect(bool mode)
{
    m_select = mode;
}

void Tobjet::setSelect()
{
    m_select = !m_select;
}








