#ifndef VECTOR_3D_HPP
#define VECTOR_3D_HPP

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

// Classe mère
#include "Math.hpp"

namespace USpeedGameEngine
{

class Math::Vector3D
{
    /****************
    * Les attributs *
    ****************/
    public :
        float x;        //!< Composante X du vecteur
        float y;        //!< Composante Y du vecteur
        float z;        //!< Composante Z du vecteur
    protected :
    private :

    /***************
    * Les méthodes *
    ***************/
    public :
        // Constructeurs
        Vector3D();
        Vector3D(float pX, float pY, float pZ);
        Vector3D(Math::Vector3D *vector);
        Vector3D(const Math::Vector3D &vector);
        // Destructeur par défaut
        ~Vector3D();

        // Vérifie si le vecteur est unitaire (longeur proche de 1.0f)
        bool isUnit();
        // Vérifie si le vecteur est poinctuel (longeur proche de 0.0f)
        bool isZero();
        // Accesseurs x, y et z
        float getX();
        float getY();
        float getZ();
        // Accesseur aux 3 composantes du vecteur
        void getValues(float *pX, float *pY, float *pZ);
        // Définition des 3 composantes du vecteur
        void setValues(float pX, float pY, float pZ);

        // Détermine si le vecteur courant est parallèle au vecteur fourni
        bool isParallel(Math::Vector3D *vector);
        // Calcul de la longueur du vecteur
        double getLength();
        // Normalisation du vecteur
        double normalize();
        // En dessous du seuil de précision, les composantes sont mise à zéro
        void zeroClamp();
        // Arrondissement des composantes à la précision par défaut de la classe Math
        void round();
        // Génération d'un point, produit de deux vecteurs
        float dotProduct(Math::Vector3D *vector);
        // Produit en croix de deux vecteurs fournis vers le vecteur courant
        bool crossProduct(Math::Vector3D *vect1, Math::Vector3D *vect2);
        // Retourne l'angle en degrés du vecteur avec celui fourni
        float getAngleDeg(Math::Vector3D *vector);
        // Retourne l'angle en radian du vecteur avec celui fourni
        float getAngleRad(Math::Vector3D *vector);
        // Modification de l'échelle du vecteur
        void scale(float scale);
        // Opposé des composantes du vecteur
        void negate();

        ////////////////
        // Opérateurs //
        ////////////////
        Math::Vector3D operator*(const Math::Vector3D &v);
        Math::Vector3D operator+(const Math::Vector3D &v) const;
        Math::Vector3D operator-(const Math::Vector3D &v) const;
        Math::Vector3D operator-() const;
        Math::Vector3D& operator=(const Math::Vector3D &v);
        Math::Vector3D& operator*=(const float scalar);
        Math::Vector3D& operator+=(const Math::Vector3D &v);
        Math::Vector3D& operator-=(const Math::Vector3D &v);
        bool operator==(const Vector3D &v) const;
        bool operator!=(const Vector3D &v) const;

    protected :
    private :
    };
}        // Fin "namespace USpeedGameEngine"

#endif
