#ifndef QUATERNION_HPP
#define QUATERNION_HPP

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

// Classe mère
#include "Math.hpp"
#include "Matrix4x4.hpp"
#include "Point3D.hpp"
#include "Vector3D.hpp"

namespace USpeedGameEngine
{

class Math::Quaternion
{
    /****************
    * Les attributs *
    ****************/
    public :
    protected :
    private :
        float w;            //!< Valeur w du quaternion (pour "<code>w + (x * i) + (y * j) + (z * k)</code>)")
        float x;            //!< Valeur x du quaternion (pour "<code>w + (x * i) + (y * j) + (z * k)</code>)")
        float y;            //!< Valeur y du quaternion (pour "<code>w + (x * i) + (y * j) + (z * k)</code>)")
        float z;            //!< Valeur z du quaternion (pour "<code>w + (x * i) + (y * j) + (z * k)</code>)")

    /***************
    * Les méthodes *
    ***************/
    public :
        // Constructeurs
        Quaternion();
        Quaternion(float w, float x, float y, float z);
        Quaternion(float xEuler, float yEuler, float zEuler);
        Quaternion(Math::Vector3D *vector, float angle);

        // Destructeur par défaut
        ~Quaternion();

        ////////////////////
        // Les opérateurs //
        ////////////////////
        // Produit de quaternions
        Math::Quaternion	operator*(const Math::Quaternion &q) const;
        // Copie (affectation)
        Math::Quaternion&	operator=(const Math::Quaternion &q);
        // Produit et affectation
        Math::Quaternion&	operator*=(const Math::Quaternion &q);

        //////////////////////
        // Autres fonctions //
        //////////////////////
        // Récupération des 4 composantes
        void getValues(float *w, float *x, float *y, float *z);
        // Calcule et retourne la norme du quaternion
        float getNorm();
        // Génère la matrice 4x4 associée au quaternion
        void getMatrix(Math::Matrix4x4 *matrix);
        // Normalisation du quaternion
        void normalize();
        // Quaternion Identité
        void loadIdentity();
        // Convertion d'un quaternion en 3 angles d'Euler
        void toEuler(float *xEuler, float *yEuler, float *zEuler);
        // Convertion d'un quaternion en un vecteur et un angle
        void toAxis(Math::Vector3D *vector, float *angle);
        // Convertion des angles d'Euler en un Quaternion
        void fromEuler(float xEuler, float yEuler, float zEuler);
        // Convertion d'un vecteur et d'un angle en un quaternion
        void fromAxis(Math::Vector3D *vector, float angle);

    protected :
    private :

};

}        // Fin "namespace USpeedGameEngine"

#endif
