#include <cmath>
#include <GL/glut.h>
#include <list>
#include <string>
#include <strstream>
#include <vector>

#include "globale.h"
#include "CVector3.h"
#include "CCamera.h"
#include "Temps.h"
#include "CCube.h"
#include "CBloc.h"
#include "Mouvement.h"
#include "CJeu.h"
#include "CWinStream.h"
#include "Pause.h"

void display(void);




// Fonction qui gère le déplacement de la souris et fait les rotations
// de la caméra en conséquence

void JeuBougeSouris(int x, int y)
{
	float AngleHor, AngleVert;

	if ( (x != CENTRE_X) || (y != CENTRE_Y) )
	{
		AngleHor  = (CENTRE_X - x) / 1000.0f;
		AngleVert = (CENTRE_Y - y) / 1000.0f;

		glutWarpPointer(CENTRE_X, CENTRE_Y);

		CVector3 AxeHor;
		AxeHor = (gCamera.Observation - gCamera.Position) ^ gCamera.Haut;
		AxeHor.Normalize();

		gCamera.TournePosition(AngleVert, AxeHor);
		gCamera.TournePosition(AngleHor, gCamera.Haut);

		if (gCamera.EstAvance)
			gCamera.Avance(SPEEDCAM);
		if (gCamera.EstRecule)
			gCamera.Avance(-SPEEDCAM);

		(*gCamera.DisplayFunc)();
	}
	else if (gCamera.EstAvance || gCamera.EstRecule)
	{
		if (gCamera.EstAvance)
			gCamera.Avance(SPEEDCAM);
		if (gCamera.EstRecule)
			gCamera.Avance(-SPEEDCAM);

		(*gCamera.DisplayFunc)();
	}
}




// Fonction qui gère les boutons de la souris et set les flags pour
// avancer ou reculer la caméra en conséquence

void JeuCliqueSouris(int button, int state, int x, int y)
{
	switch (button)
	{
	case GLUT_LEFT_BUTTON:
		if (state == GLUT_DOWN)
		{
			gCamera.EstAvance = true;
		}
		else
			gCamera.EstAvance = false;
		break;

	case GLUT_RIGHT_BUTTON:
		if (state == GLUT_DOWN)
		{
			gCamera.EstRecule = true;
		}
		else
			gCamera.EstRecule = false;
		break;
	}
}




// Fonction qui gère le clavier pendant le jeu

void JeuClavier(unsigned char key, int x, int y)
{
	switch (key)
	{
	// Pour les rotations
	case 'W' : if(!gJeu.Bloc.EstMouvement) Rotation(AVANT); break;
	case 'D' : if(!gJeu.Bloc.EstMouvement) Rotation(DROITE); break;
	case 'S' : if(!gJeu.Bloc.EstMouvement) Rotation(ARRIERE); break;
	case 'A' : if(!gJeu.Bloc.EstMouvement) Rotation(GAUCHE); break;
	case 'Q' : if(!gJeu.Bloc.EstMouvement) Rotation(HORAIRE); break;
	case 'E' : if(!gJeu.Bloc.EstMouvement) Rotation(ANTIHORAIRE); break;

	// Pour les translations
	case 'w' : if(!gJeu.Bloc.EstMouvement) Translation(AVANT); break;
	case 'd' : if(!gJeu.Bloc.EstMouvement) Translation(DROITE); break;
	case 's' : if(!gJeu.Bloc.EstMouvement) Translation(ARRIERE); break;
	case 'a' : if(!gJeu.Bloc.EstMouvement) Translation(GAUCHE); break;

	case ' ' :
		if (GLUT_ACTIVE_SHIFT & glutGetModifiers())
		{
			// Pour descendre le bloc à la position du guide
			if(!gJeu.Bloc.EstMouvement) gJeu.Bloc.DropBloc();
		}
		else
		{
			// Pour descendre le bloc plus rapidement
			gJeu.Bloc.EstDescenteRapide = true;
		}
		break;

	// Pour changer le mode de la caméra
	case '\t' : gCamera.ChangeMode(); break;

	// ESCAPE
	case (27): Pause(); break;
	default: break;
	}
}




// Fonction qui gère le clavier lorsqu'on relâche une touche.
// Utile seulement pour lorsqu'on appuie sur l'espace afin de
// savoir si shift est appuyé

void JeuClavierUp(unsigned char key, int x, int y)
{
	if (key == ' ')
		gJeu.Bloc.EstDescenteRapide = false;
}
