
#include "Ttorche.h"


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

Ttorche::Ttorche()
{
	//
}

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

Ttorche::~Ttorche()
{
    //
}


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


void Ttorche::addLight(std::string flux)
{
    size_t idx;

    idx = lightPnt.size();
    lightPnt.push_back(OLightPnt());
    lightPnt[idx].create(flux);
}


// px py pz rx ry rz sx sy sz
void Ttorche::addModel(std::string flux)
{
    std::vector<std::string> strList;
    size_t idx = m_pos.size();
    OVec3_f rot, scale;

    ECO_strCut(strList, flux, ' ');

    m_pos.push_back(OVec3_f());
    m_rot.push_back(OVec3_f());
    m_scale.push_back(OVec3_f());
    m_model.push_back(OMat4());
    m_model_multi.push_back(OMat4());

	m_pos[idx].x = ECO_strToFloat(strList[0]);
	m_pos[idx].y = ECO_strToFloat(strList[1]);
	m_pos[idx].z = ECO_strToFloat(strList[2]);
	m_rot[idx].x = ECO_strToFloat(strList[3]);
	m_rot[idx].y = ECO_strToFloat(strList[4]);
	m_rot[idx].z = ECO_strToFloat(strList[5]);
    m_scale[idx].x = ECO_strToFloat(strList[6]);
	m_scale[idx].y = ECO_strToFloat(strList[7]);
	m_scale[idx].z = ECO_strToFloat(strList[8]);

    _setModel(idx);
    //setSelect(idx, true);
}

void Ttorche::addParticle()
{
    size_t idx = prtTorche.size();
    OVec3_f pos;

    prtTorche.push_back(TprtTorche());
     // code path file src.xywh / max generation_nbr gen_loop / angleH.min.max angleV.min.max /
    // vitesse.min.max / zone.radius zone.yz zone.type.w / size.min.max life.min.max /
    // color.rgb.min color.rgb.max / var_air var_gravite var_color /
    prtTorche[idx].create();
    pos = m_pos[0];
    // bout de la torche
    pos.x += 0.55f;
    pos.y -= 0.05f; // petite correction
    pos.z += 0.32f;
    prtTorche[idx].start(pos);
}




// le mesh support (torche reverbere ...)
// code path file 1 / 0 0 0 0 0 0 1 1 1 /
void Ttorche::create(std::string flux)
{
    std::vector<std::string> strList;
    size_t idx = 0;

    ECO_strCut(strList, flux, ' ');

    // ---

    m_pos.push_back(OVec3_f());
    m_rot.push_back(OVec3_f());
    m_scale.push_back(OVec3_f());
    m_model.push_back(OMat4());
    m_model_multi.push_back(OMat4());

    // ---

	m_code = strList[0];
	m_path = strList[1];
	m_file = strList[2];
	m_cull_face = ECO_strToInt(strList[3]);
	// 4
	m_pos[idx].x = ECO_strToFloat(strList[5]);
	m_pos[idx].y = ECO_strToFloat(strList[6]);
	m_pos[idx].z = ECO_strToFloat(strList[7]);
	m_rot[idx].x = ECO_strToFloat(strList[8]);
	m_rot[idx].y = ECO_strToFloat(strList[9]);
	m_rot[idx].z = ECO_strToFloat(strList[10]);
    m_scale[idx].x = ECO_strToFloat(strList[11]);
	m_scale[idx].y = ECO_strToFloat(strList[12]);
	m_scale[idx].z = ECO_strToFloat(strList[13]);
    // 14

    // ---

    _composition();
    _setModel(idx);
}

void Ttorche::_composition()
{
    std::string file;

    OMesh_obj::P_setPath(PATH_MESH);

    if (m_path != "null")
    {
        file = m_path + m_file;
    }
    else
    {
        file = m_file;
    }
    if (!mesh.create(file))
    {
        ECO_error_set("echec chargement %s >Ttorche::_composition", m_file.c_str());
        return;
    }
}







void Ttorche::draw(ODshGeo& dshGeo)
{
    // si besoin => actualisez ici
    //mesh.setModelMulti(m_model_multi);

    dshGeo.enable();
        dshGeo.setMulti(true);

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

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

    dshGeo.setMulti(false);
}

/*
void Ttorche::draw(ODshGeoClipZ& dshGeoClipZ)
{
    // si besoin => actualisez ici
    //mesh.setModelMulti(m_model_multi);

    dshGeoClipZ.enable();
        dshGeoClipZ.setMulti(true);

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

    for (size_t part = 0; part < mesh.getPart_size(); part++)
    {
        dshGeoClipZ.setTextures( mesh.getId_diffuseMap(part), mesh.getId_normalMap(part), mesh.getId_specularMap(part));
        mesh.draw_multi(part);
    }
    mesh.end_draw_part();

    dshGeoClipZ.setMulti(false);
}
*/
void Ttorche::draw_light_point(ODBuffer& buffer, ODshNull& dshNull, ODshPoint& dshPoint)
{
    OMat4 model;
    OVec3_f pos;

    for (size_t i = 0 ; i < lightPnt.size(); i++)
    {
        if (lightPnt[i].getState() < LIGHT_ON) continue;

        model = m_model[0]; // version simple objet, non transposée
/*
        model.loadIdentity();
        model.translate(m_pos[0]);
        model.rotate(m_rot[0].z, 0,0,1);
        model.rotate(m_rot[0].y, 0,1,0);
        model.rotate(m_rot[0].x, 1,0,0);
*/
        // inclinaison du lightspoint / spot
        //model.rotate(30, 1,0,0);

        model.translate(lightPnt[i].getDecal());
        model.scale(lightPnt[i].getRadius()*2.0f);
        // mat horizontale
        pos.x = model[3];
        pos.y = model[7];
        pos.z = model[11];

        //stencilPass
        buffer.stencilPass1();
        dshNull.enable();
            dshNull.setModel(model);
            lightPnt[i].draw();
        dshNull.disable();

        //pointLightPass
        buffer.stencilPass2();
        dshPoint.enable();
            //dshPoint.setTextureUnit();
            dshPoint.setModel(model);
            dshPoint.setColor(lightPnt[i].getColor());
            dshPoint.setAmbient(lightPnt[i].getAmbient());
            dshPoint.setPosition(pos); // c'est la direction que l'on veut

            dshPoint.setRadius(lightPnt[i].getRadius());
            dshPoint.setCutoff(lightPnt[i].getCutoff());
        lightPnt[i].draw();
        dshPoint.disable();
    }

}

void Ttorche::draw_particle()
{
    for (size_t i = 0; i < prtTorche.size(); i++)
    {
        prtTorche[i].draw();
    }
}




void Ttorche::_setModel(size_t idx)
{
    m_model[idx].loadIdentity();
    m_model[idx].translate(m_pos[idx]);
    m_model[idx].rotate(m_rot[idx].z, 0,0,1);
    m_model[idx].rotate(m_rot[idx].y, 0,1,0);
    m_model[idx].rotate(m_rot[idx].x, 1,0,0);
    m_model[idx].scale(m_scale[idx]);
/*
    switch(mesh.getVerticale())
    {
    case 0:
        m_model[idx].rotate(180, 1,0,0);
        break;
    case 1:
        m_model[idx].rotate(90, 1,0,0);
        break;
    }
*/
    m_model_multi[idx] = m_model[idx];
    m_model_multi[idx].transpose();

    mesh.setModelMulti(m_model_multi);
}

void Ttorche::setState(int value)
{
    for (size_t i = 0; i < lightPnt.size(); i++)
    {
        lightPnt[i].setState(value);
    }
}




void Ttorche::update(float ambient)
{
    for (size_t i = 0; i < prtTorche.size(); i++)
    {
        prtTorche[i].generation();
        prtTorche[i].update(ambient);
    }
}




