/*====================ÉCOLE POLYTECHNIQUE DE MONTRÉAL============================
  
	NOM DU FICHIER :CPartie.cpp
	
	DESCRIPTION :	Déclaration de la classe qui gère la partie
	
	AUTEUR : Martin Bisson, Anne-Marie Buki, Mylene Denis & Jean-Francois Pérusse
	
===============================================================================*/
#include <string>
using std::string;
#include "CPartie.h"
#include <list>
#include <time.h>
#include <GL/glut.h>
#include "al/al.h"
#include "al/alc.h"
#include "al/alut.h"


int CPartie::LastBird = -1;
int CPartie::GameSource;
int CPartie::WaterSource;
int CPartie::BirdSoundsBuffer[NUM_BIRD_SOUNDS];
int CPartie::WaterSoundBuffer;
CPngTexture CPartie::TexBaton;


/*------------------------------------------------------------------
  Fonction :	CPartie::CPartie
  
  Description :	Constructeur
  
  Par : Martin Bisson, Anne-Marie Buki, Mylene Denis & Jean-Francois Pérusse
  MAJ: 
------------------------------------------------------------------*/
CPartie::CPartie()
{
    JoueOiseaux = true;
    TDJ = 0;
    TerrainCourant = 1;
    JoueurCourant = 1;
    CoupCourant = 1;
    EtatJeu = ETAT_INACTIF;
    
}


/*------------------------------------------------------------------
  Fonction :	CPartie::~CPartie
  
  Description :	Destructeur
  
  Par : Martin Bisson, Anne-Marie Buki, Mylene Denis & Jean-Francois Pérusse
  MAJ: 
------------------------------------------------------------------*/
CPartie::~CPartie()
{
    
}


/*------------------------------------------------------------------
  Fonction :	CPartie::getTerrain
  
  Description :	Fonction qui retourne le terrain actif
  
  Paramètres :
  
  Valeur retournée :	CTerrain* : Pointeur du terrain actif TDJ
  
  Par : 2004-3-16 Martin Bisson, Anne-Marie Buki, Mylene Denis & Jean-Francois Pérusse
  MAJ: 
------------------------------------------------------------------*/
CTerrain* CPartie::getTerrain()
{
    return this->TDJ;   
}

/*------------------------------------------------------------------
  Fonction :	CPartie::setTerrain
  
  Description :	Modifie le terrain actif
  
  Paramètres :
	 CTerrain* T : Valeur à attribuer au pointeur TDJ
	 
  Par : Martin Bisson, Anne-Marie Buki, Mylene Denis & Jean-Francois Pérusse
  MAJ: 
------------------------------------------------------------------*/

void CPartie::setTerrain(CTerrain* T)
{
    this->TDJ = T;
}


/*------------------------------------------------------------------
  Fonction :	CPartie::getTerrainCourant
  
  Description :	Fonction qui retourne la position du terrain courant à afficher
  
  Valeur retournée :	int : Position dans le vector du terrain
  
  Par : Martin Bisson, Anne-Marie Buki, Mylene Denis & Jean-Francois Pérusse
  MAJ: 
------------------------------------------------------------------*/
int CPartie::getTerrainCourant()
{
    return this->TerrainCourant;
}


/*------------------------------------------------------------------
  Fonction :	CPartie::setTerrainCourant
  
  Description :	Modifie l'indice du terrain courant
  
  Paramètres :
	 int Terrain : Position à attribuer
	 
  Par : Martin Bisson, Anne-Marie Buki, Mylene Denis & Jean-Francois Pérusse
  MAJ: 
------------------------------------------------------------------*/
void CPartie::setTerrainCourant(int Terrain)
{
    this->TerrainCourant = Terrain;
}


/*------------------------------------------------------------------
  Fonction :	CPartie::getJoueurCourant
  
  Description :	Retourne la position du joueur actuel
  
  Valeur retournée :	int : Position actuelle du joueur dans le vector
  
  Par : Martin Bisson, Anne-Marie Buki, Mylene Denis & Jean-Francois Pérusse
  MAJ: 
------------------------------------------------------------------*/
int CPartie::getJoueurCourant()
{
    return this->JoueurCourant;
}


/*------------------------------------------------------------------
  Fonction :	CPartie::setJoueurCourant
  
  Description :	Modifie l'indice du joueur courant
  
  Paramètres :
	 int Joueur : Position à attribuer
	 
  Par : Martin Bisson, Anne-Marie Buki, Mylene Denis & Jean-Francois Pérusse
  MAJ: 
------------------------------------------------------------------*/
void CPartie::setJoueurCourant(int Joueur)
{
    this->JoueurCourant = Joueur;
}


/*------------------------------------------------------------------
  Fonction :	CPartie::getEtatJeu
  
  Description :	Retourne l'état du jeu
  
  Retour :
	 type_etatjeu : L'état du jeu
	 
  Par : Martin Bisson, Anne-Marie Buki, Mylene Denis & Jean-Francois Pérusse
  MAJ: 
------------------------------------------------------------------*/
type_etatjeu CPartie::getEtatJeu()
{
    return this->EtatJeu;
}

/*------------------------------------------------------------------
  Fonction :	CPartie::setEtatJeu
  
  Description :	Change l'état du jeu
  
  Paramètre :
	 type_etatjeu Etat : Le nouvel état du jeu
	 
  Par : Martin Bisson, Anne-Marie Buki, Mylene Denis & Jean-Francois Pérusse
  MAJ: 
------------------------------------------------------------------*/
void CPartie::setEtatJeu(type_etatjeu Etat)
{
    this->EtatJeu = Etat;
}

/*------------------------------------------------------------------
  Fonction :	CPartie::getCoupCourant
  
  Description :	Retourne le coup courant
  
  Retour :
	 int : Le coup courant
	 
  Par : Martin Bisson, Anne-Marie Buki, Mylene Denis & Jean-Francois Pérusse
  MAJ: 
------------------------------------------------------------------*/
int CPartie::getCoupCourant()
{
    return this->CoupCourant;
}

/*------------------------------------------------------------------
  Fonction :	CPartie::setCoupCourant
  
  Description : Change le coup courant
  
  Paramètre :
	 int Coup : Le coup courant
	 
  Par : Martin Bisson, Anne-Marie Buki, Mylene Denis & Jean-Francois Pérusse
  MAJ: 
------------------------------------------------------------------*/
void CPartie::setCoupCourant(int Coup)
{
    this->CoupCourant = Coup;
}

/*------------------------------------------------------------------
  Fonction :	CPartie::setCoupCourant
  
  Description : Change le coup courant
  
  Paramètre :
	 int Coup : Le coup courant
	 
  Par : Martin Bisson, Anne-Marie Buki, Mylene Denis & Jean-Francois Pérusse
  MAJ: 
------------------------------------------------------------------*/
CVector3f CPartie::getMousePosition()
{
    return this->PosSouris;
}

/*------------------------------------------------------------------
  Fonction :	CPartie::setMousePosition
  
  Description : Conserve la position actuelle de la souris
  
  Paramètre :
	 CVector3f V : Position de la souris
	 
  Par : Martin Bisson, Anne-Marie Buki, Mylene Denis & Jean-Francois Pérusse
  MAJ: 
------------------------------------------------------------------*/
void CPartie::setMousePosition(CVector3f V)
{
    this->PosSouris = V;
}


/*------------------------------------------------------------------
  Fonction :	CPartie::ComparerPosition
  
  Description :	Fonction qui détermine la valeur maximale à attribuer au vecteur déplacement
  
  Paramètres :
	 CVector3f& DirTemp : Vecteur déplacement à modifier, norme maximale de 1
	 
  Valeur retournée :	bool : 
  
  Par : Martin Bisson, Anne-Marie Buki, Mylene Denis & Jean-Francois Pérusse
  MAJ: 
------------------------------------------------------------------*/
bool CPartie::ComparerPosition(CVector3f& DirTemp)
{
    //Donner la vitesse a la balle equivalente a la distance entre souris et balle
    DirTemp = TDJ->getBalle()->getPos() - PosSouris;
    //    cout << DirTemp;
    DirTemp.setZ(0);
    //Si la norme du vecteur déplacement est trop grand
    if(DirTemp.GetNorm() == 0.0f)
	return false;
    if(DirTemp.GetNorm() > 1)
	DirTemp = DirTemp / DirTemp.GetNorm();
    if(DirTemp.GetNorm() < 0.1f)
	DirTemp = DirTemp.GetNormalVector() * 0.1f;
    DirTemp = 20*DirTemp;
    return true;
}


/*------------------------------------------------------------------
  Fonction :	CPartie::AfficheGL
  
  Description :	Fonction qui affiche l'openGL
  
  Par : Martin Bisson, Anne-Marie Buki, Mylene Denis & Jean-Francois Pérusse
  MAJ: 
------------------------------------------------------------------*/
void CPartie::AfficheGL()
{
    TDJ->AfficheGL();
    if (EtatJeu == ETAT_FRAPPEBALLE)
    {
	AfficheLigne();
	AfficheBaton();
    }
}


/*------------------------------------------------------------------
  Fonction : CPartie::AfficheLigne
  
  Description :	Fonction qui affiche la ligne directrice de la balle
  
  Par : Martin Bisson, Anne-Marie Buki, Mylene Denis & Jean-Francois Pérusse
  MAJ: 
------------------------------------------------------------------*/
void CPartie::AfficheLigne()
{
    glDisable(GL_LIGHTING);
    std::vector<CVector3f> Tableau;
    std::vector<CVector3f>::iterator it, it2;
    CVector3f DirTemp;
    float X;
    ComparerPosition(DirTemp);
    float Norme = 0.0f;
    
    //Balle fictive copie de la vraie balle
    CBalle BB(0.9f,0.1f);
    
    BB.setPos(TDJ->getBalle()->getPos());
    BB.setDirection(DirTemp);
    
    //Premier élément du tableau est la position de la balle
    Tableau.push_back(BB.getPos());
    int ColCount = 0;
    int StripCount = 0;
    do
    {
	//Si la ligne va collisioner avec un élément du terrain
	if(TDJ->CCM(&BB) || TDJ->CollisionObjetsLigne(&BB))
	{
	    //Ajouter la position au tableau
	    Tableau.push_back(BB.getPos());
	    ColCount++;
	}
	
	//Faire avancer la balle fictive
	BB.Avance();	
	Norme = 0.0f;
	Tableau.push_back(BB.getPos());
	for(it = Tableau.begin(); it != Tableau.end()-1; it++)
	{
	    it2 = it+1;
	    Norme += CVector3f((*it2) - (*it)).GetNorm();
	}
	if ((int(Norme*100.0f) % 25) == 0 && int((Norme*100.0f)/25.0f) > StripCount)
	{
	    StripCount++;
	} else {
	    Tableau.pop_back();
	}
    }while(Norme < 3.0f && ColCount < 4 && !BB.StopBall()); //Tant que la norme de la ligne n'est pas 3, ajouter des points
    
    //Ajouter la dernière position au tableau de la balle fictive
    Tableau.push_back(BB.getPos());
    
    //Dessiner la ligne fictive
    //glColor4f(1.0f, 1.0f, 1.0f, 0.7f);
    X = DirTemp.GetNorm()/20;
    glColor4f(1.0f, 1.0f-X, 0.0f, 1.0f);
    
    glShadeModel(GL_FLAT);
    glBegin(GL_LINES);
    for(it = Tableau.begin(); it != Tableau.end(); it++)
    {
	glVertex3f((*it).GetPosX(),(*it).GetPosY(),0);  
    }
    glEnd();
    glShadeModel(GL_SMOOTH);
    glEnable(GL_LIGHTING);
}

#define BATON_LARGEUR 0.2f
#define BATON_PROFONDEUR 0.05f

/*------------------------------------------------------------------
  Fonction : CPartie::AfficheBaton
  
  Description :	Fonction qui affiche le baton
  
  Par : Martin Bisson, Anne-Marie Buki, Mylene Denis & Jean-Francois Pérusse
  MAJ: 
------------------------------------------------------------------*/
void CPartie::AfficheBaton()
{
    GLfloat mat_diffuse[] = {1.0, 1.0, 1.0, 1.0};
    GLfloat mat_specular[] = {1.0, 1.0, 1.0, 1.0};
    GLfloat mat_shininess[] = {5.0};
    GLfloat mat_ambient[] = { 0.6, 0.6, 0.6, 1.0 };
    glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, mat_ambient);
    glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, mat_diffuse);
    glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, mat_specular);
    glMaterialfv(GL_FRONT_AND_BACK, GL_SHININESS, mat_shininess);
    
    CVector3f DirTemp;
    ComparerPosition(DirTemp);
    DirTemp = DirTemp / (-20.0f);
    float Angle = (180.0f/M_PI)*atan2(DirTemp.GetPosX(),-DirTemp.GetPosY());
    glEnable(GL_TEXTURE_2D);
    glBindTexture(GL_TEXTURE_2D, TexBaton.GetID());
    glPushMatrix();
    {
	glNormal3f(0,0,1);
	glTranslatef(TDJ->getBalle()->getPos().GetPosX()+DirTemp.GetPosX(),TDJ->getBalle()->getPos().GetPosY()+DirTemp.GetPosY(),0);
	glRotatef(Angle,0,0,1);
	glBegin(GL_QUADS);
	{
	    glTexCoord2i(0,1);
	    glVertex3f(-BATON_LARGEUR/2.0f/TAILLE_TUILE,-BATON_PROFONDEUR/2.0f/TAILLE_TUILE,2*BATON_PROFONDEUR);
	    glTexCoord2i(1,1);
	    glVertex3f(BATON_LARGEUR/2.0f/TAILLE_TUILE,-BATON_PROFONDEUR/2.0f/TAILLE_TUILE,2*BATON_PROFONDEUR);
	    glTexCoord2i(1,0);
	    glVertex3f(BATON_LARGEUR/2.0f/TAILLE_TUILE,BATON_PROFONDEUR/2.0f/TAILLE_TUILE,2*BATON_PROFONDEUR);
	    glTexCoord2i(0,0);
	    glVertex3f(-BATON_LARGEUR/2.0f/TAILLE_TUILE,BATON_PROFONDEUR/2.0f/TAILLE_TUILE,2*BATON_PROFONDEUR);
	}
	glEnd();
	glBegin(GL_QUADS);
	{
	    glNormal3f(0,-1,0);
	    glTexCoord2i(0,1);
	    glVertex3f(-BATON_LARGEUR,-BATON_PROFONDEUR/2.0f/TAILLE_TUILE,0);
	    glTexCoord2i(1,1);
	    glVertex3f(BATON_LARGEUR,-BATON_PROFONDEUR/2.0f/TAILLE_TUILE,0);
	    glTexCoord2i(1,0);
	    glVertex3f(BATON_LARGEUR/2.0f/TAILLE_TUILE,-BATON_PROFONDEUR/2.0f/TAILLE_TUILE,2*BATON_PROFONDEUR);
	    glTexCoord2i(0,0);
	    glVertex3f(-BATON_LARGEUR/2.0f/TAILLE_TUILE,-BATON_PROFONDEUR/2.0f/TAILLE_TUILE,2*BATON_PROFONDEUR);
	}
	glEnd();
	glBegin(GL_QUADS);
	{
	    glNormal3f(0,1,0);
	    glTexCoord2i(0,1);
	    glVertex3f(BATON_LARGEUR,BATON_PROFONDEUR/2.0f/TAILLE_TUILE,0);
	    glTexCoord2i(1,1);
	    glVertex3f(-BATON_LARGEUR,BATON_PROFONDEUR/2.0f/TAILLE_TUILE,0);
	    glTexCoord2i(1,0);
	    glVertex3f(-BATON_LARGEUR/2.0f/TAILLE_TUILE,BATON_PROFONDEUR/2.0f/TAILLE_TUILE,2*BATON_PROFONDEUR);
	    glTexCoord2i(0,0);
	    glVertex3f(BATON_LARGEUR/2.0f/TAILLE_TUILE,BATON_PROFONDEUR/2.0f/TAILLE_TUILE,2*BATON_PROFONDEUR);
	}
	glEnd();
	glBegin(GL_QUADS);
	{
	    glNormal3f(1,0,0);
	    glTexCoord2i(0,1);
	    glVertex3f(BATON_LARGEUR,-BATON_PROFONDEUR/2.0f/TAILLE_TUILE,0);
	    glTexCoord2i(1,1);
	    glVertex3f(BATON_LARGEUR,BATON_PROFONDEUR/2.0f/TAILLE_TUILE,0);
	    glTexCoord2i(1,0);
	    glVertex3f(BATON_LARGEUR/2.0f/TAILLE_TUILE,BATON_PROFONDEUR/2.0f/TAILLE_TUILE,2*BATON_PROFONDEUR);
	    glTexCoord2i(0,0);
	    glVertex3f(BATON_LARGEUR/2.0f/TAILLE_TUILE,-BATON_PROFONDEUR/2.0f/TAILLE_TUILE,2*BATON_PROFONDEUR);
	}
	glEnd();
	glBegin(GL_QUADS);
	{
	    glNormal3f(-1,0,0);
	    glTexCoord2i(0,1);
	    glVertex3f(-BATON_LARGEUR,BATON_PROFONDEUR/2.0f/TAILLE_TUILE,0);
	    glTexCoord2i(1,1);
	    glVertex3f(-BATON_LARGEUR,-BATON_PROFONDEUR/2.0f/TAILLE_TUILE,0);
	    glTexCoord2i(1,0);
	    glVertex3f(-BATON_LARGEUR/2.0f/TAILLE_TUILE,-BATON_PROFONDEUR/2.0f/TAILLE_TUILE,2*BATON_PROFONDEUR);
	    glTexCoord2i(0,0);
	    glVertex3f(-BATON_LARGEUR/2.0f/TAILLE_TUILE,BATON_PROFONDEUR/2.0f/TAILLE_TUILE,2*BATON_PROFONDEUR);
	}
	glEnd();
    }
    glPopMatrix();
    glDisable(GL_TEXTURE_2D);
}

/*------------------------------------------------------------------
  Fonction :	CPartie::ChargerParcours
  
  Description :	Crée le nombre de terrains associé au nom du parcours
		Appelle la fonction membre de CTerrain ChargerParcours
		Les insert dans la liste de terrains de la partie
				
  Paramètres :
	 QString Parcours : Parcours auquel on veut attribuer les valeurs
	 int NbTerrains : Nombre de terrains à attribuer à Parcours
	 
  Valeur retournée :	bool : Si le chargement fonctionne
  
  Par : 2004-3-16 Martin Bisson, Anne-Marie Buki, Mylene Denis & Jean-Francois Pérusse
  MAJ: 
------------------------------------------------------------------*/
bool CPartie::ChargerParcours(QString Parcours, int NbTerrains)
{
    int i;
    QString No("");
    QString NomTerrain("");
    CTerrain* LeTerrain;
    
    for (i=0; i<NbTerrains ; ++i)
    {
	if (i<9)
	{
	    No = "0";
	} else {
	    No = "";
	}
	
	No += QString::number(i+1);
	NomTerrain=QString("./terrains/")+Parcours;
	NomTerrain += "___" + No;
	
	LeTerrain = new CTerrain;
	//charger les terrains
	if(!LeTerrain->ChargerTerrain(NomTerrain.ascii()))
	{
	    return false;
	}
	if (i == 0) TDJ = LeTerrain;
	//ajouter le terrain à la liste
	LesTerrains.push_back(LeTerrain);
    }
    
    return true;
    
}

/*------------------------------------------------------------------
  Fonction :	CPartie::PlacerBalleSurDepart
  
  Description :	Placer la balle sur le départ à l'endroit désiré lorsqu'on commence le trou
  
  Paramètres :
	 float x : Position en x de la souris
	 float y : Position en y de la souris
	 
  Valeur retournée :	bool : Si le placement s'est bien effectué
  
  Par : 2004-3-16 Martin Bisson, Anne-Marie Buki, Mylene Denis & Jean-Francois Pérusse
  MAJ: 
------------------------------------------------------------------*/
#define HAUT_TERRAIN  TDJ->getDepart()->getPos().GetPosY() + (TDJ->getDepart()->getHeight())/2.0f - TDJ->getBalle()->getRayon()
#define BAS_TERRAIN TDJ->getDepart()->getPos().GetPosY() - (TDJ->getDepart()->getHeight())/2.0f + TDJ->getBalle()->getRayon()
#define DROITE_TERRAIN TDJ->getDepart()->getPos().GetPosX() + (TDJ->getDepart()->getWidth())/2.0f - TDJ->getBalle()->getRayon() 
#define GAUCHE_TERRAIN TDJ->getDepart()->getPos().GetPosX() - (TDJ->getDepart()->getWidth())/2.0f + TDJ->getBalle()->getRayon()

bool CPartie::PlacerBalleSurDepart(float x, float y)
{
    //x doit etre entre posx -largeur/2 + rayon/2 et posx + largeur/2 - rayon/2
    //y doit etre entre posy-hauteur/2 + rayon/2 et posy + hauteur/2 - rayon/2
    if (x > DROITE_TERRAIN) x = DROITE_TERRAIN;
    if (x < GAUCHE_TERRAIN) x = GAUCHE_TERRAIN;
    if (y > HAUT_TERRAIN) y = HAUT_TERRAIN;
    if (y < BAS_TERRAIN) y = BAS_TERRAIN;
    TDJ->getBalle()->setPos(CVector3f(x,y,TDJ->getBalle()->getPos().GetPosZ())); 
    return true;
}

/*------------------------------------------------------------------
  Fonction :	CPartie::JoueurSuivant
  
  Description :	Passe au joueur suivant
  
  Paramètres :
  
  Valeur retournée :	bool : Si il y a un joueur suivant pour le trou ou pas
  
  Par : 2004-3-16 Martin Bisson, Anne-Marie Buki, Mylene Denis & Jean-Francois Pérusse
  MAJ: 
------------------------------------------------------------------*/
bool CPartie::JoueurSuivant()
{
    if (this->JoueurCourant == (int)LesJoueurs.size())
	return false;
    this->JoueurCourant++;
    return true;
}

/*------------------------------------------------------------------
  Fonction :	CPartie::TerrainSuivant
  
  Description :	Passe au terrain suivant
  
  Paramètres :
  
  Valeur retournée :	bool : S'il y a un terrain suivant dans la partie ou pas
  
  Par : Martin Bisson, Anne-Marie Buki, Mylene Denis & Jean-Francois Pérusse
  MAJ: 
------------------------------------------------------------------*/
bool CPartie::TerrainSuivant()
{
    std::vector<CTerrain*>::iterator it = LesTerrains.begin();
    if (this->TerrainCourant == (int)LesTerrains.size()) return false;
    this->TerrainCourant++;
    it+=(TerrainCourant-1);
    TDJ = (*it);
    TDJ->getTrou()->setBallIn(false);
    return true;
}

/*------------------------------------------------------------------
  Fonction :	CPartie::TerrainPrécédent
  
  Description :	Passe au terrain précédent
  
  Paramètres :
  
  Valeur retournée :	bool : S'il y a un terrain précédent dans la partie ou pas
  
  Par : Martin Bisson, Anne-Marie Buki, Mylene Denis & Jean-Francois Pérusse
  MAJ: 
------------------------------------------------------------------*/
bool CPartie::TerrainPrecedent()
{
    std::vector<CTerrain*>::iterator it = LesTerrains.begin();
    if (this->TerrainCourant == 1) return false;
    this->TerrainCourant--;
    it+=(TerrainCourant-1);
    TDJ = (*it);
    TDJ->getTrou()->setBallIn(false);
    return true;
}

/*------------------------------------------------------------------
  Fonction :	CPartie::CoupSuivant
  
  Description :	Passe au coup suivant
  
  Paramètres :
  
  Valeur retournée :	void : 
  
  Par : 2004-3-16 Martin Bisson, Anne-Marie Buki, Mylene Denis & Jean-Francois Pérusse
  MAJ: 
------------------------------------------------------------------*/
void CPartie::CoupSuivant()
{
    this->CoupCourant++;
}

/*------------------------------------------------------------------
  Fonction :	CPartie::BallInHole
  
  Description :	Détermine si la balle est dans le trou
  
  Paramètres :
  
  Valeur retournée :	bool : Si la balle est dans le trou ou pas
  
  Par : 2004-3-16 Martin Bisson, Anne-Marie Buki, Mylene Denis & Jean-Francois Pérusse
  MAJ: 
------------------------------------------------------------------*/
bool CPartie::BallInHole()
{
    CBalle* TmpBalle = TDJ->getBalle();
    CTrou* TmpTrou = TDJ->getTrou();
    CVector3f PosBall = TmpBalle->getPos();
    PosBall.setZ(0);
    CVector3f PosTrou = TmpTrou->getPos();
    PosTrou.setZ(0);
    float Distance = (PosBall-PosTrou).GetNorm();
    if (Distance < (TmpTrou->getRayon()/TAILLE_TUILE - TmpBalle->getRayon()/TAILLE_TUILE))
    {
	TmpBalle->setSurTrou(true);
	return true;
    }
    TmpBalle->setSurTrou(false);
    return false;
}

/*------------------------------------------------------------------
  Fonction :	CPartie::BallInWater
  
  Description :	Détermine si la balle est dans l'eau
  
  Paramètres :
  
  Valeur retournée :	bool : Si la balle est dans l'eau
  
  Par : 2004-3-16 Martin Bisson, Anne-Marie Buki, Mylene Denis & Jean-Francois Pérusse
  MAJ: 
------------------------------------------------------------------*/
bool CPartie::BallInWater()
{
    return TDJ->BallInWater();
}


/*------------------------------------------------------------------
  Fonction :	CPartie::SetJoueurs
  
  Description :	Attribue un vecteur de joueurs au vecteur membre de CPartie
  
  Paramètres :
	 std::vector< CJoueur > Joueurs : Liste à attribuer
	 
  Valeur retournée :	void : 
  
  Par : 2004-3-16 Martin Bisson, Anne-Marie Buki, Mylene Denis & Jean-Francois Pérusse
  MAJ: 
------------------------------------------------------------------*/
void CPartie::SetJoueurs( std::vector< CJoueur > Joueurs )
{
    LesJoueurs = Joueurs;
}


/*------------------------------------------------------------------
  Fonction :	CPartie::AjoutPointage
  
  Description :	Augmente le pointage à chaque coup
  
  Paramètres :
  
  Valeur retournée :	void : 
  
  Par : 2004-3-16 Martin Bisson, Anne-Marie Buki, Mylene Denis & Jean-Francois Pérusse
  MAJ: 
------------------------------------------------------------------*/
void CPartie::AjoutPointage()
{
    std::vector< CJoueur >::iterator it = LesJoueurs.begin();
    it += (JoueurCourant-1);
    (*it).AjoutPointage(CoupCourant);
}


/*------------------------------------------------------------------
  Fonction :	CPartie::Trier
  
  Description :	Tri de l'ordre des joueurs selon leur score au trou précédent
  
  Paramètres :
  
  Valeur retournée :	void : 
  
  Par : 2004-3-16 Martin Bisson, Anne-Marie Buki, Mylene Denis & Jean-Francois Pérusse
  MAJ: 
------------------------------------------------------------------*/
void CPartie::Trier()
{
    std::vector<CJoueur> NewJoueurs;
    std::list<CJoueur> ListTemp;
    
    for (int i = 0; i < (int)LesJoueurs.size(); i++)
	ListTemp.push_back(LesJoueurs[i]);
    
    while(!ListTemp.empty())
    {
	std::list<CJoueur>::iterator min = ListTemp.begin();
	
	for (std::list<CJoueur>::iterator it = ListTemp.begin();
	it != ListTemp.end();
	it++)
	{
	    if ((*min).getPointage()[(*min).getPointage().size()-1] >
		(*it).getPointage()[(*it).getPointage().size()-1])
		min = it;
	}
	NewJoueurs.push_back(*min);
	ListTemp.erase(min);
    }
    
    LesJoueurs = NewJoueurs;
}

/*------------------------------------------------------------------
  Fonction :	CPartie::TrierTotal
  
  Description :	Tri de l'ordre des joueurs selon leur score total
  
  Paramètres :
  
  Valeur retournée :	void : 
  
  Par : 2004-3-16 Martin Bisson, Anne-Marie Buki, Mylene Denis & Jean-Francois Pérusse
  MAJ: 
------------------------------------------------------------------*/
void CPartie::TrierTotal()
{
    std::vector<int> totaux;
    int tempint;
    CJoueur tempjoueur;
    unsigned int i, j;
    
    for (i = 0; i < LesJoueurs.size(); i++)
    {
	totaux.push_back(LesJoueurs[i].getPointage()[0]);
	for (j = 1; j < LesJoueurs[i].getPointage().size(); j++)
	{
	    totaux[i] += LesJoueurs[i].getPointage()[j];
	}
    }
    
    // Tri des joueurs selon leur score total
    for (i = 0; i < LesJoueurs.size() - 1; i++)
    {
	for (j = i+1; j < LesJoueurs.size(); j++)
	{
	    if (totaux[j] < totaux[i])
	    {
		tempint = totaux[i];
		totaux[i] = totaux[j];
		totaux[j] = tempint;
		
		tempjoueur = LesJoueurs[i];
		LesJoueurs[i] = LesJoueurs[j];
		LesJoueurs[j] = tempjoueur;
	    }
	}
    }	
}

/*------------------------------------------------------------------
  Fonction :	CPartie::ChargeTextures
  
  Description :	Charge la texture du baton
  
  Paramètres :
  
  Valeur retournée :	void : 
  
  Par : 2004-3-16 Martin Bisson, Anne-Marie Buki, Mylene Denis & Jean-Francois Pérusse
  MAJ: 
------------------------------------------------------------------*/
void CPartie::ChargeTextures()
{
    TexBaton.LoadPNG("editeur/images/baton.png");
}

/*------------------------------------------------------------------
  Fonction :	CPartie::DechargeTextures
  
  Description :	Détruit la texture du baton
  
  Paramètres :
  
  Valeur retournée :	void : 
  
  Par : 2004-3-16 Martin Bisson, Anne-Marie Buki, Mylene Denis & Jean-Francois Pérusse
  MAJ: 
------------------------------------------------------------------*/
void CPartie::DechargeTextures()
{
    TexBaton.Unload();
}

/*------------------------------------------------------------------
  Fonction :	PlayBirdSound()
  
  Description :	Joue un son d'oiseau au hasard avec OpenAL
  
  Par : 2004-3-16 Martin Bisson, Anne-Marie Buki, Mylene Denis & Jean-Francois Pérusse
  MAJ: 
------------------------------------------------------------------*/
void CPartie::PlayBirdSound()
{
    if (!JoueOiseaux) return;
    srand(time(0));
    int rnd = rand()%NUM_BIRD_SOUNDS;
    while (rnd == LastBird) {rnd = rand()%NUM_BIRD_SOUNDS;}
    {
	LastBird = rnd;
    }
    
    alSourcei(GameSource,AL_BUFFER,BirdSoundsBuffer[rnd]);
    alSourcePlay(GameSource);  
}

/*------------------------------------------------------------------
  Fonction :	PlayWaterSound()
  
  Description :	Joue un son d'eau avec OpenAL
  
  Par : 2004-3-16 Martin Bisson, Anne-Marie Buki, Mylene Denis & Jean-Francois Pérusse
  MAJ: 
------------------------------------------------------------------*/
void CPartie::PlayWaterSound()
{
    alSourcei(WaterSource,AL_BUFFER,WaterSoundBuffer);
    alSourcePlay(WaterSource);  	
}

/*------------------------------------------------------------------
  Fonction :	ChargeSons()
  
  Description :	Charge les sons
  
  Par : 2004-3-16 Martin Bisson, Anne-Marie Buki, Mylene Denis & Jean-Francois Pérusse
  MAJ: 
------------------------------------------------------------------*/
void CPartie::ChargeSons()
{
    CTrou::ChargeSons();
    ALenum format;
    ALvoid *data;
    ALsizei size;
    ALsizei freq;
    ALboolean loop;
    
    alGenSources(1,(ALuint*)&GameSource);
    alSourcei(GameSource,AL_LOOPING,AL_FALSE);
    alGenSources(1,(ALuint*)&WaterSource);
    alSourcei(WaterSource,AL_LOOPING,AL_FALSE);
    
    alGenBuffers(NUM_BIRD_SOUNDS,(ALuint*)BirdSoundsBuffer);
    for (int i = 1; i <= NUM_BIRD_SOUNDS; i++)
    {
	string File = string("jeu/sons/bird_") + string(1,char(i+'0')) + string(".wav");
	alutLoadWAVFile((ALbyte*)File.c_str(),&format,&data,&size,&freq,&loop);
	alBufferData(BirdSoundsBuffer[i-1],format,data,size,freq);
	alutUnloadWAV(format,data,size,freq);
    }    
    alGenBuffers(1,(ALuint*)&WaterSoundBuffer);
    alutLoadWAVFile((ALbyte*)"jeu/sons/water.wav",&format,&data,&size,&freq,&loop);
    alBufferData(WaterSoundBuffer,format,data,size,freq);
    alutUnloadWAV(format,data,size,freq);
}

/*------------------------------------------------------------------
  Fonction :	UpdateAnimations()
  
  Description :	Met a jour les animations du terrain
  
  Par : 2004-4-9 Martin Bisson, Anne-Marie Buki, Mylene Denis & Jean-Francois Pérusse
  MAJ: 
------------------------------------------------------------------*/
void CPartie::UpdateAnimations()
{
    TDJ->UpdateAnimations();
}
