#ifndef ANIMATION_HPP
#define ANIMATION_HPP

// Détection du système cible...
#include "usgeDetectSystem.h"

#include <vector>
// Les types "USpeed Game Engine"
#include "Core/CoreTypes.hpp"

// La classe de chrono
#include "Chrono/Chrono.hpp"

namespace USpeedGameEngine
{

class Animation
{
    /****************
    * Les attributs *
    ****************/
    public :
    protected :
    private :
        Chrono msTime;                      //!< <span class="lngFr">Gestion du temps</span><span class="lngEn">Timer</span>
        unsigned int currentFrame;          //!< <span class="lngFr">La trame actuellement en cours de traitement</span><span class="lngEn">Current frame index</span>
        bool running;                       //!< <span class="lngFr">État de l'animation</span><span class="lngEn">Animation state</span>
        bool looping;                       //!< <span class="lngFr">État de boucle de l'animation</span><span class="lngEn">Loop state</span>
        USGE_KeyFrame current;              //!< <span class="lngFr">Informations courantes</span><span class="lngEn">Current keyframe</span>
        std::vector<USGE_KeyFrame> frames;  //!< <span class="lngFr">Liste des trames clés de l'animation</span><span class="lngEn">Keyframe's list</span>

    /***************
    * Les méthodes *
    ***************/
    public :
        // Destructeur par défaut.
        ~Animation();
        // Constructeur par défaut.
        Animation();

        // Remise à zéro de l'instance de la classe.
        void clear();

        // Retourne la valeur actuelle en fonction du temps écoulé et de la durée de l'animation.
        static double getInterpolation(unsigned long int duration, unsigned long int currentTime, double from, double to);
        // Permet de minimiser les déplacements en rotation via un modulo et éventuellement une modification du sens de rotation.
        static USGE_Float3 minimizeRotations(USGE_Float3 const &from, USGE_Float3 const &to);
        static USGE_Float3 minimizeRotations(USGE_Float3 const &from, USGE_Float3 const &to, bool moduloOnly);
        static void minimizeRotations(USGE_Float3 const &from, USGE_Float3 const &to, bool moduloOnly, USGE_Float3 &target);

        ///////////////////////////
        // États des l'animation //
        ///////////////////////////
        // Ajout d'une trame clé.
        void addKeyFrame(USGE_KeyFrame const &keyFrame);
        void addKeyFrame(USGE_KeyFrame const &keyFrame, unsigned int position);
        // Retrait d'une trame clé.
        void removeKeyFrame(unsigned int position);
        // Suppression de toutes les trames clé.
        void removeAll();

        // Retourne le nombre de trames clé.
        unsigned long int getKeyFramesCount();
        // Récupération de la trame spécifiée.
        USGE_KeyFrame *operator[](const unsigned long int index);
        // Récupération des informations actuelles.
        USGE_KeyFrame getInfos();
        void getInfos(USGE_KeyFrame &frame);

        //////////////////////////////
        // Contrôles de l'animation //
        //////////////////////////////
        // Démarrage de l'animation.
        void start();
        // Redémarrage de l'animation depuis les informations initiales.
        void restart();
        // Arrêt (pause) de l'animation.
        void pause();
        // Arrêt et retour au début de l'animation.
        void stop();
        // Permet de savoir si l'animation est en cours.
        bool isRunning();
        // Lancement du calcul d'interpolation sur toutes les informations.
        void interpolate();
        // Mise en boucle de l'animation.
        void loop(bool active);
        // Permet de connaître l'état de mise en boucle de l'animation.
        bool isLooping();

    protected :
    private :
};

}        // Fin "namespace USpeedGameEngine"

#endif
