/*
	Auteur : Pierre Aubert
	Mail : aubertp7@gmail.com
	Licence : lgpl
*/
#ifndef MATRICE3F_H
#define MATRICE3F_H

#include "vecteur3f.h"

float radToDegF(float rad);
float degToRadF(float deg);

/** @brief classe qui permet de manipuler les matrices simplement, avec les fonctions usuelles de calculs sur les matrices et les opérateurs
*/
class Matrice3f{
	public:
		Matrice3f(const Vecteur3f & v1 = VECT3F_NULL, const Vecteur3f & v2 = VECT3F_NULL, const Vecteur3f & v3 = VECT3F_NULL);
		Matrice3f(float x1, float y1, float z1, float x2, float y2, float z2, float x3, float y3, float z3);
		Matrice3f(const Matrice3f & matrice);
		virtual ~Matrice3f();
		
		void setVecteur3f(const Vecteur3f & v1 = VECT3F_NULL, const Vecteur3f & v2 = VECT3F_NULL, const Vecteur3f & v3 = VECT3F_NULL);
		void fill(float val);
		
		void setRotRad(const Vecteur3f & axe, float angleRad);
		void setRotRad(float rotX, float rotY, float rotZ);
		void setRotXRad(float angleRad);
		void setRotYRad(float angleRad);
		void setRotZRad(float angleRad);
		
		void setRotDeg(const Vecteur3f & axe, float angleDeg);
		void setRotDeg(float rotX, float rotY, float rotZ);
		void setRotXDeg(float angleDeg);
		void setRotYDeg(float angleDeg);
		void setRotZDeg(float angleDeg);
		
		float determinant();
		
		Matrice3f transposed();
		Matrice3f comatrice();
		Matrice3f comatriceTranposed();
		Matrice3f invert();
		
		Matrice3f & operator = (const Matrice3f & matrice);
		Matrice3f & operator += (const Matrice3f & matrice);
		Matrice3f & operator *= (const Matrice3f & matrice);
		Matrice3f & operator *= (float scal);
		Matrice3f & operator /= (float scal);
		Matrice3f & operator - ();
		
		float operator [] (unsigned int i) const;
		
		friend Matrice3f operator + (const Matrice3f & matrice1, const Matrice3f & matrice2);

		friend Matrice3f operator - (const Matrice3f & matrice1, const Matrice3f & matrice2);

		friend Matrice3f operator / (const Matrice3f & matrice1, float scal);
		
		friend Matrice3f operator * (const Matrice3f & matrice1, float scal);
		
		friend Matrice3f operator * (float scal, const Matrice3f & matrice2);
		
		friend Matrice3f operator * (const Matrice3f & matrice1, const Matrice3f & matrice2);
		
		friend Vecteur3f operator * (const Matrice3f & matrice1, const Vecteur3f & vecteur);
		
		friend bool operator == (const Matrice3f & matrice1, const Matrice3f & matrice2);
		//Définition de l'inégalité entre deux Vecteur3f
		friend bool operator != (const Matrice3f & matrice1, const Matrice3f & matrice2);
		
		friend std::ostream & operator << (std::ostream & out, const Matrice3f & matrice);
		
	private:
		void initialisation(const Vecteur3f & v1, const Vecteur3f & v2, const Vecteur3f & v3);
		void copyMatrice3f(const Matrice3f & matrice);
		float det2(unsigned int i);
		///tabteau de float, la matrice
		float * p_mat;
	
};

///definition de la matrice NULL
extern const Matrice3f MAT3F_NULL;
///définition de la matrice identité
extern const Matrice3f MAT3F_ID;

#endif
