/*****************************************************************************
 *
 *  Copyright (C) 2003 Cédric Brégardis <cedric.bregardis@free.fr>
 *
 *  This file is part of BRIQUOLO
 *
 *  BRIQUOLO is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  BRIQUOLO is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with BRIQUOLO; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 *
 *****************************************************************************/
#ifndef MOGL_PEAU
#define MOGL_PEAU

#include <list>
#include <map>

#include "MOGL_Noeud.h"
#include "MOGL_TrianglePeau.h"
#include "MOGL_Structure.h"
#include "MOGL_Constante.h"

using namespace std;

/**
   Représente une peau. Une peau recouvre un squelette (un ensemble de MOGL_Armature), et suis ses déformation tout en
   gardant un aspect uni. Ainsi une peau est un ensemble de triangles dont les points peuvent appartenir à des os (MOGL_Armature).
   Les triangles peuvent ainsi se déformer selon la position des os. Les point peuvent aussi être locaux à la peau, auquel
   cas ils ne subissent que la déformation globale de la peau.<p>
   MOGL_Peau spécialise MOGL_Noeud, et peut donc contenir une liste de MOGL_ElementArbre. Il est ainsi possible de faire en sorte
   que le squelette soit défini par cette liste.
 */
class MOGL_Peau: public MOGL_Noeud
{
    // **** Types locaux à la classe ****
    typedef vector <MOGL_Struct_PointSimple> MOGL_Vecteur_PointSimple;
    typedef MOGL_Vecteur_PointSimple::iterator MOGL_ItVecteur_PointSimple;

    struct MOGL_Struct_TableauTexture
    {
        int IdentifiantAbonnement;
        GLfloat * TabPoint;
        GLfloat * TabNormale;
        GLfloat * TabTexture;
        MOGL_Texture * Texture;
    };

    typedef list <MOGL_Struct_TableauTexture> MOGL_Liste_TableauxTriangle;
    typedef MOGL_Liste_TableauxTriangle::iterator MOGL_ItListe_TableauxTriangle;

    struct MOGL_Struct_AffichageTriangle
    {
        GLfloat * point;
        GLfloat * normal;
        GLfloat * texture;
    };

    typedef vector <MOGL_Struct_AffichageTriangle> MOGL_Vecteur_AffichageTriangle;
    typedef MOGL_Vecteur_AffichageTriangle::iterator MOGL_ItVecteur_AffichageTriangle;

    typedef list <MOGL_TrianglePeau> MOGL_Liste_TrianglePeau;
    typedef MOGL_Liste_TrianglePeau::iterator MOGL_ItListe_TrianglePeau;

        
    // **********************************

  protected :
    MOGL_Vecteur_PointSimple _VecteurPoint;
    MOGL_Vecteur_PointSimple _VecteurPointTransforme;
    MOGL_Liste_TrianglePeau _ListeTrianglePeau; 

    /** Tableau de stockage des abonnements */
    MOGL_Liste_TableauxTriangle _TabTriangle;
    MOGL_Vecteur_AffichageTriangle _TabAffichageTriangle;
    MOGL_MatriceTransformation _MatriceFinale, _InvMatriceFinale;

    bool _ModifieTriangle;      
    bool _DessinerBord;
    MOGL_Struct_Couleur _CouleurBord;
    unsigned int _TailleBord;


    /**
       Permet de calculer la transformation des points locaux à la peau.
     */
    void CalculerPoints();

  public :
    /**
       Constructeur
     */
    MOGL_Peau();
    virtual ~MOGL_Peau();
    virtual void TnL(MOGL_Afficheur * p_Afficheur);

    void AjouterTriangle(const MOGL_TrianglePeau & p_TrianglePeau);

    void AjouterPoint(unsigned int p_NumPoint, const MOGL_Struct_PointSimple & p_Point);
    void AjouterPoint(unsigned int p_NumPoint, GLfloat xp, GLfloat yp, GLfloat zp,
                      GLfloat xn, GLfloat yn, GLfloat zn);

    void DefinirInvMatriceBase(MOGL_Armature * p_Armature);

    void SetDessinerBord(bool p_Dessiner);
    bool GetDessinerBord() const;        

    void SetCouleurBord(MOGL_Struct_Couleur p_Couleur);
    MOGL_Struct_Couleur GetCouleurBord() const;

    void SetTailleBord(unsigned int p_TailleBord);
    unsigned int GetTailleBord() const;

};

#endif
