#ifndef SIMPLE_CAMERA_GL3_H
#define SIMPLE_CAMERA_GL3_H

#include <GL3/gl3.h>
#include <math.h>

#include <SDL2/SDL.h>
#include <SDL2/SDL_video.h>
#include <SDL2/SDL_keycode.h>
#include <SDL2/SDL_keyboard.h>
#include <SDL2/SDL_events.h>

#include "vecteur3f.h"
//#include "../PLIB_CALCUL/pmath.h"

#include "matrice3f.h"
#include "Matrice4.h"

/** @brief Classe qui se comporte comme une caméra, elle indique à OpenGl comment faire son affichage, mais elle est plus rapide que la Camera, car elle ne fait quasiment pas de calcul
*/

class SimpleCameraGl3{
	public:
		//constructeur par défaut de la caméra
		SimpleCameraGl3();
		SimpleCameraGl3(const Vecteur3f & position , float theta, float phi, float rouli);
		SimpleCameraGl3(const SimpleCameraGl3 & camera);
		//destructeur de la Caméra
		virtual ~SimpleCameraGl3();
		//fonction qui met en route la caméra et dit a OpenGl où il faut regarder
		void see(Matrice4 & matriceModelview);
		
		void setAll(const Vecteur3f & position, float theta, float phi, float rouli);
		void setPosition(const Vecteur3f & position);
		void setPosition(float x, float y, float z);
		void setAngles(float theta, float phi,float rouli);
		void setTheta(float theta);
		void setPhi(float phi);
		void setRouli(float rouli);
		void setWindowID(SDL_WindowID id);
		
		void move(const Vecteur3f & dm);        //change la position de la caméra de dm
		void moveVisee(float dl);
		void moveGauche(float dl);
		
		void turnUp(float dPhi);
		void turnDown(float dPhi);
		void turnRight(float dTheta);
		void turnLeft(float dTheta);
		
		void addTheta(float dTheta);
		void addPhi(float dPhi);
		void addRouli(float dRouli);

		//change le rotation de la caméra de d
		void rotation(float dTheta, float dPhi,float dRouli);
		
		Vecteur3f getPosition() const;
		Vecteur3f getVisee();
		Vecteur3f getUp();
		Vecteur3f getPlanGauche();
		float getTheta() const;
		float getPhi() const;
		float getRouli() const;
		
		void modeFPS(float mouseX, float mouseY, float midWidth, float midHeight, float coefSensibiliteX = 1.0, float coefSensibiliteY = 1.0, float phiMin = -80.0, float phiMax = 80.0);
		
		//operateur =
		SimpleCameraGl3 & operator = (const SimpleCameraGl3 & camera);
		
	private:
		//copie la caméra
		void copyCamera(const SimpleCameraGl3 & camera);              //copie la caméra
		//Fonction qui initialise la caméra
		void initialisation(const Vecteur3f & position, float theta, float phi, float rouli);
		void updateCameraGl3();
		///position de la caméra
		Vecteur3f p_position;             //position de la caméra
		///angle d'orientation de la caméra (plan xOy) en radian
		float p_theta;                 //angle d'orientation de la caméra (plan xOy)
		///angle d'orientation de la caméra (plan xOz) en radian
		float p_phi;                   //angle d'orientation de la caméra (plan xOz)
		///angle d'orientation de la caméra (plan yOz) en radian
		float p_rouli;                 //angle d'orientation de la caméra (plan yOz)
		
		Vecteur3f p_visee;
		Vecteur3f p_up;
		Vecteur3f p_planGauche;
		
		///id de la fenêtre de la caméra
		SDL_WindowID p_windowId;     //id de la fenêtre de la caméra
		///matrice de rotation de la caméra (pour pouvoir la déplacée facilement
		Matrice3f p_matriceRotation;
};

#endif

