/***************************************************************************
     Copyright (C) 2009 by Pierre,,,
     pierre@pierre-laptop
 ***************************************************************************/
#ifndef DEFVECTEUR_3D_H
#define DEFVECTEUR_3D_H

#include <complex.h>
#include <math.h>
#include <stdio.h>
#include <iostream>
#include <list>
#include <vector>

///@brief classe permettant de manipuler des Vecteur et une partie des calculs qui leur est associé sans avoir à se trimballer les 3 coordonnées en vrac

/**
libs utilisées dans cette library
@li complex.h : cette lib est utilisée pour calculer la rotation du Vecteur (mais n'est pas utiliser pour le moment)
@li math.h : indispensable pour les calculs qui nécessites des fonctions trigonomètriqes (sin, cos, tan, asin, acos...)
@li stdio.h : lib utile pour ouvrir un fichier et écrire dedans
@li iostream : utile pour utliliser la sortie standard de la console
*/

class Vecteur{
	public:
		//constructeur de Vecteur
		Vecteur(double vecX = 0, double vecY = 0, double vecZ = 0);
		//initialise un vecteur avec une chaîne
		Vecteur(const char * str);
		//constructeur de copie de Vecteur
		Vecteur(const Vecteur & vec);
		//destructeur de Vecteur
		virtual ~Vecteur();
		//sauvegarde des coordonnées du Vecteur dans un ficher ouvert en écriture
		void save(FILE* fp);
		void save2d(FILE* fp);
		//initialisation des coordonnées du Vecteur à partir d'un ficher ouvert en lecture
		void load(FILE* fp);
		//initialisation avec une chaine de caractères
		bool initString(const char * str);
		//redéfinition de l'opérateur =
		Vecteur & operator = (const Vecteur & vect);
		//redéfinition de l'opérateur +=
		Vecteur & operator += (const Vecteur & vect);
		//redéfinition de l'opérateur -=
		Vecteur & operator -= (const Vecteur & vect);
		//redéfinition de l'opérateur *=
		Vecteur & operator *= (double coef);    //redéfinition de l'opérateur *=
		//redéfinition de l'opérateur /=
		Vecteur & operator /= (double coef);
		//redéfinition de l'opérateur -
		Vecteur operator - ();
		//donne la norme euclidienne du Vecteur
		double taille() const;
		//donne la norme du vecteur en coordonnées de Leci-Civita
		double tailleLeviCivita() const;
		//fonction qui calcul et renvoie la norme au carré de *this
		double normeSQR() const;
		//Retourne un Veteur ayant pour composantes les valeurs absolues des composantes de this
		Vecteur abs() const;
		//renvoie un Vecteur qui a un x positif
		Vecteur absX() const;
		//renvoie un Vecteur qui a un y positif
		Vecteur absY() const;
		//renvoie un Vecteur qui a un z positif
		Vecteur absZ() const;
		///renvoie la composante x du Vecteur
		/** @return la composante x du Vecteur
		*/
		inline double getx() const{return p_x;}
		///renvoie la composante y du Vecteur
		/** @return la composante y du Vecteur
		*/
		inline double gety() const{return p_y;}
		///renvoie la composante z du Vecteur
		/** @return la composante z du Vecteur
		*/
		inline double getz() const{return p_z;}
		//donne un Vecteur de la composante x du Vecteur
		Vecteur getVectX() const;
		//donne un Vecteur de la composante y du Vecteur
		Vecteur getVectY() const;
		//donne un Vecteur de la composante z du Vecteur
		Vecteur getVectZ() const;
		//donne un Vecteur (x, y, 0)
		Vecteur getVectXY() const;
		//donne un Vecteur (0, y, z)
		Vecteur getVectYZ() const;
		//donne un Vecteur (x, 0, z)
		Vecteur getVectXZ() const;
		//donne le Vecteur unitaire correspondant au Vecteur courrant
		Vecteur getUnit() const;
		//fonction de calcul d'angle qui doit être plus rapide que le calcul avec des nombres complexes
		double getAngle(const Vecteur & normale) const;
		//fonction qui transforme un vecteur en coordonnées de Leci-Civita (u, v) en un Vecteur normal (x, y, 0) en 2D en tout cas pour l'instant
		Vecteur leviCivitaToVecteur() const;
		//fonction qui initialise les composantes du Vecteur
		void setXYZ(double vecX, double vecY, double vecZ);
		//initialise la composantes x du Vecteur
		void setx(const double x);
		//initialise la composantes y du Vecteur
		void sety(const double y);
		//initialise la composantes z du Vecteur
		void setz(const double z);
		//ajoute une valeur à la composante en x du Vecteur
		void addx(double dx);
		//ajoute une valeur à la composante en y du Vecteur
		void addy(double dy);
		//ajoute une valeur à la composante en z du Vecteur
		void addz(double dz);
		//fonction qui initialise le vecteur avec des angles en coordonnées spériques
		void setRotation(double angleTeta, double anglePhi);
		void setSpheric(double rho, double angleTeta, double anglePhi);
		double getAngleTeta() const;
		//fonction qui calcul la rotation du vecteur avec les variations de ses angles en coordonnées spériques
		void rotation(const Vecteur & axe, double angle);            //change l'orientation du Vecteur
		//fonction qui calcul le réflexion du Vecteur *this par rapport à un vecteur normal
		void reflexion(const Vecteur & normal);
		//addition
		friend Vecteur operator + (const Vecteur & vect1, const Vecteur & vect2);
		//soustraction
		friend Vecteur operator - (const Vecteur & vect1, const Vecteur & vect2);
		//Définition du produit scalaire entre deux Vecteur
		friend double operator * (const Vecteur & vect1, const Vecteur & vect2);
		//mutiplication par un scalaire à droite
		friend Vecteur operator * (const Vecteur & vect, double scal);
		//mutiplication par un scalaire à gauche
		friend Vecteur operator * (double scal, const Vecteur & vect);
		//division par un scalaire
		friend Vecteur operator / (const Vecteur & vect, double scal);
		//Définition  du produit vectoriel
		friend Vecteur operator ^ (const Vecteur & vect1, const Vecteur & vect2);
		//Définition de l'égalité entre deux Vecteur
		friend bool operator == (const Vecteur & vect1, const Vecteur & vect2);
		//Définition de l'inégalité entre deux Vecteur
		friend bool operator != (const Vecteur & vect1, const Vecteur & vect2);
		//permet l'affichage d'un vecteur dans la console
		friend std::ostream & operator << (std::ostream & out, const Vecteur & vecteur);
		//permet l'initialisation d'un Vecteur dans la console où avec un fichier de config
		friend std::istream & operator >> (std::istream & in, Vecteur & v);
		//initialise un Vecteur à partir d'une chaine de type (x,y,z)
		bool loadFromConfig(const char  * source);
	private:
		//initialisation de Vecteur
		void initialisationVecteur(double vecX, double vecY, double vecZ);//initialisation de Vecteur
		
		///composante sur l'axe des x
		double p_x;
		///composante sur l'axe des y
		double p_y;
		///composante sur l'axe des z
		double p_z;

};

#endif


