/*****************************************************************************
 *
 *  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_ARMATURE
#define MOGL_ARMATURE

#include <vector>
#include <map>
/*#ifdef _WIN32
        #include <windows.h>
        #include <windowsx.h>
#endif
#include <GL/gl.h>*/

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

using namespace std;

/**
   Représente un élément d'armature. Cet élément peut être assimilé à un os dans un squelette. Un squelette
   est formé d'un arbre de MOGL_Armature. Cette classe est conçue pour fonctionner avec MOGL_Peau : la peau 
   recouvre le squelette. Ainsi cette classe se caractérise par une liste de point qui est transformé selon 
   la matrice de transformation.
   @sa MOGL_Peau
 */
class MOGL_Armature: public MOGL_Noeud
{
    // **** Types locaux à la classe ****
    typedef vector <MOGL_Struct_PointSimple> MOGL_Vecteur_PointSimple;
    typedef MOGL_Vecteur_PointSimple::iterator MOGL_ItVecteur_PointSimple;
    // **********************************

  protected :
    MOGL_Vecteur_PointSimple _VecteurPoint;
    MOGL_Vecteur_PointSimple _VecteurPointTransforme;

    MOGL_MatriceTransformation _MatriceInitiale, _MatriceFinale;

    bool _ModifiePoint;
    const MOGL_MatriceTransformation * _InvMatriceBase;
    MOGL_MatriceTransformation _MatriceTransformationPoint;
        
    /**
       Calcule les points.
     */
    void CalculerPoints();

  public :
    /**
       Constructeur.
    */
    MOGL_Armature();

    virtual void TnL(MOGL_Afficheur * p_Afficheur);

    /**
       Permet d'ajouter un point.
       @param p_NumPoint : indice du point.
       @param p_Point : point à ajouter.
     */
    void AjouterPoint(unsigned int p_NumPoint, const MOGL_Struct_PointSimple & p_Point);

    /**
       Permet d'ajouter un point.
       @param p_NumPoint : indice du point.
       @param xp  : coordonné x du point à ajouter.
       @param yp  : coordonné y du point à ajouter.
       @param zp  : coordonné z du point à ajouter.
       @param xn  : coordonné x de la normale du point à ajouter.
       @param yn  : coordonné y de la normale du du point à ajouter.
       @param zn  : coordonné z de la normale du du point à ajouter.
     */
    void AjouterPoint(unsigned int p_NumPoint, GLfloat xp, GLfloat yp, GLfloat zp,
                      GLfloat xn, GLfloat yn, GLfloat zn);

    /**
       Permet de récupérer le point initial non transformé.
       @return Le point non transformé.
     */
    MOGL_Struct_PointSimple GetPointInitial(unsigned int p_Indice);

    /**
       Permet de récupérer le point initial transformé.
       @return Le point transformé.
    */
    MOGL_Struct_PointSimple GetPointTransforme(unsigned int p_Indice);

    /**
       Redéfinition de MOGL_ElementArbre::ReinitialiserPosition();
    */
    void ReinitialiserPosition();

    /**
       Permet de définir la matrice d'initialisation.
       @param p_Matrice : matrice de transformation d'initialisation.
     */
    void SetMatriceInitialisation(const MOGL_MatriceTransformation & p_Matrice);

    /**
       Permet de définir la matrice inverse de base.
       Lors de l'appel à TnL(), tous les points associés à l'objet sont transformés en appliquant
       la transformation absolue associée (c'est à dire l'ensemble des transformations des noeuds
       parents, et la transformation relative associée à l'objet MOGL_Armature).
       En définissant une matrice inverse de base, on indique une matrice représentant la transformation
       inverse à appliquer au point une fois transformé. Cela permet de limiter la transformation des points
       du MOGL_Armature à un sous espace. Ainsi MOGL_Peau utilise cette méthode pour ne transformer les points
       de ses MOGL_Armature que par rapport à lui même, et ainsi de ne pas les rendre dépendant des noeuds
       parents ou de la transformation de MOGL_Camera.
       @param p_InvMatriceBase : pointeur vers la MOGL_MatriceTransformation inverse de base.
    */
    void SetInvMatriceBase(const MOGL_MatriceTransformation * p_InvMatriceBase);
};

#endif

