#include <SDL/SDL.h>
#include <SDL/SDL_opengl.h>
#include <GL/gl.h>
#include <GL/glu.h>

#include <stdlib.h>
#include <stdexcept>
#include <math.h>
#include <vector>

using namespace std;

#include "PersoPrincipal.h"

#include "Sorts.h"

#include "Moteur.h"
#include "Map.h"

int TexSortBouleFeu[10];
int TexSortSoin1[10];
int TexSortSoin2[10];
int TexSortSoin3[10];

void LoadSorts()
{
	char ch[50];
	for(int i = 0; i < 10; ++i)
	{
		sprintf(ch, "./Images/Sorts/BouleFeu%d.png", (i + 1));
		TexSortBouleFeu[i] = Moteur.NouvelleTexture(ch);
	}
	
	for(int i = 0; i < 10; ++i)
	{
		sprintf(ch, "./Images/Sorts/Soin1_%d.png", (i + 1));
		TexSortSoin1[i] = Moteur.NouvelleTexture(ch);
	}
	
	for(int i = 0; i < 10; ++i)
	{
		sprintf(ch, "./Images/Sorts/Soin2_%d.png", (i + 1));
		TexSortSoin2[i] = Moteur.NouvelleTexture(ch);
	}
	
	for(int i = 0; i < 10; ++i)
	{
		sprintf(ch, "./Images/Sorts/Soin3_%d.png", (i + 1));
		TexSortSoin3[i] = Moteur.NouvelleTexture(ch);
	}
	
	
}

//FONCTIONS DE LA CLASSE CSORT:
CSort::CSort()
{
	//Construteur de CSort!!!
}

CSort::~CSort()
{
	//Destructeur de CSort!
}

bool CSort::DessineSort(bool Pause)
{
	//Quand la fonction n'est pas définie pour la classe dérivé, on éxécute rien du tout ...
	//On demande la suppression ...
	return false;// Le return représente la valeur boolénienne de savoir si on conserve le sort ...
}



//FONCTIONS DE LA CLASSE CSORTBOULEFEU:
CSortBouleFeu::CSortBouleFeu(bool Droite, int px, int py, CPerso* maitre)
{
	//Constructeur de la classe CSortBouleFeu pour le sort boule de feu, dérivée de CSort:
	LastCalc = DebutVie = SDL_GetTicks();
	VersLaDroite = Droite;
	px += 50;
	PosDepartX = PosX = px;
	PosDepartY = py;
	Maitre = maitre;
	
}

CSortBouleFeu::~CSortBouleFeu()
{
	//Destructeur de la classe CSortBouleFeu pour le sort boule de feu, dérivée de CSort:
}

bool CSortBouleFeu::DessineSort(bool Pause)
{
	//Calcul du sort ...
	if(!Pause)
	{
		while(SDL_GetTicks() > LastCalc)
		{
			PosX += VersLaDroite ? 5 : -5;
			if(abs(PosX - PosDepartX) > 500) return false;
		
			if(!Map.AutAcces(PosX - 37, PosDepartY + 12) || Map.DiedAcces(PosX - 37, PosDepartY + 12) || !Map.AutAcces(PosX + 37, PosDepartY + 12) || Map.DiedAcces(PosX + 37, PosDepartY + 12) || !Map.AutAcces(PosX - 37, PosDepartY + 38) || Map.DiedAcces(PosX - 37, PosDepartY + 38) || !Map.AutAcces(PosX + 37, PosDepartY + 38) || Map.DiedAcces(PosX + 37, PosDepartY + 38))
			{
				return false;
			}
		
			CPerso* perso;
			int px;
			for(int i = 0; i <= Personnages.size(); ++i)
			{
				perso = (i == Personnages.size()) ? PersoPrincipal : Personnages[i];
			
				px = PosX;
				if(!VersLaDroite)	px -= 50;
			
				if(perso != Maitre && sqrt((((px-perso->ReturnPosX())*(px-perso->ReturnPosX())) + ((PosDepartY-perso->ReturnPosY())*(PosDepartY-perso->ReturnPosY())))) < 32)
				{
					if(perso->CampAllie() != Maitre->CampAllie())
					{
						perso->AnimDegat(500);
						perso->PerteVie(50 + (int)(((double) rand() / RAND_MAX) * 50.0));
					}
					return false;
				}
			}
		
			LastCalc += 15;
		}
	}
	else
	{
		LastCalc = SDL_GetTicks();
	}
	
	//Dessin du sort
	
	Moteur.AfficheTexture(TexSortBouleFeu[(int)(((DebutVie - LastCalc) % 1000) / 100)], PosX - 50, PosDepartY, VersLaDroite ? 100 : - 100, 50);
	
	return true;
}


//FONCTIONS DE LA CLASSE CSORTSOIN1
CSortSoin1::CSortSoin1(CPerso* maitre)
{
	//Constructeur de la classe CSortSoin1 pour le sort Soin 1, dérivée de CSort:
	LastCalc = SDL_GetTicks();
	Maitre = maitre;
	Duree = 0;
}

CSortSoin1::~CSortSoin1()
{
	//Destructeur de la classe CSortSoin1 pour le sort Soin 1, dérivée de CSort:
}

bool CSortSoin1::DessineSort(bool Pause)
{
	//Calcul du sort ...
	if(!Pause)
	{
		while(SDL_GetTicks() > LastCalc + (int)(1000/SOIN1_RECUPVIE))
		{
			LastCalc += (int)(1000/SOIN1_RECUPVIE);
			Duree += (int)(1000/SOIN1_RECUPVIE);
			Maitre->GainVie(1);
		}
	}
	else
	{
		LastCalc = SDL_GetTicks();
	}
	
	//Dessin du sort
	int nbtex = (int)(Duree / 100);
	if(nbtex > 9) nbtex = 9;
	
	Moteur.AfficheTexture(TexSortSoin1[nbtex], Maitre->ReturnPosX(), Maitre->ReturnPosY(), Maitre->ReturnVersLaDroite() ? 64 : - 64, 64);
	
	return (Duree < 999);
}


//FONCTIONS DE LA CLASSE CSORTSOIN2
CSortSoin2::CSortSoin2(CPerso* maitre)
{
	//Constructeur de la classe CSortSoin2 pour le sort Soin 2, dérivée de CSort:
	LastCalc = SDL_GetTicks();
	Maitre = maitre;
	Duree = 0;
}

CSortSoin2::~CSortSoin2()
{
	//Destructeur de la classe CSortSoin2 pour le sort Soin 2, dérivée de CSort:
}

bool CSortSoin2::DessineSort(bool Pause)
{
	//Calcul du sort ...
	if(!Pause)
	{
		while(SDL_GetTicks() > LastCalc + (int)(1000/SOIN2_RECUPVIE))
		{
			LastCalc += (int)(1000/SOIN2_RECUPVIE);
			Duree += (int)(1000/SOIN2_RECUPVIE);
			Maitre->GainVie(1);
		}
	}
	else
	{
		LastCalc = SDL_GetTicks();
	}
	
	//Dessin du sort
	int nbtex = (int)(Duree / 100);
	if(nbtex > 9) nbtex = 9;
	
	Moteur.AfficheTexture(TexSortSoin2[nbtex], Maitre->ReturnPosX(), Maitre->ReturnPosY(), Maitre->ReturnVersLaDroite() ? 64 : - 64, 64);
	
	return (Duree < 999);
}


//FONCTIONS DE LA CLASSE CSORTSOIN3
CSortSoin3::CSortSoin3(CPerso* maitre)
{
	//Constructeur de la classe CSortSoin3 pour le sort Soin 3, dérivée de CSort:
	LastCalc = SDL_GetTicks();
	Maitre = maitre;
	Duree = 0;
}

CSortSoin3::~CSortSoin3()
{
	//Destructeur de la classe CSortSoin3 pour le sort Soin 3, dérivée de CSort:
}

bool CSortSoin3::DessineSort(bool Pause)
{
	//Calcul du sort ...
	if(!Pause)
	{
		while(SDL_GetTicks() > LastCalc + (int)(1000/SOIN3_RECUPVIE))
		{
			LastCalc += (int)(1000/SOIN3_RECUPVIE);
			Duree += (int)(1000/SOIN3_RECUPVIE);
			Maitre->GainVie(1);
		}
	}
	else
	{
		LastCalc = SDL_GetTicks();
	}
	
	//Dessin du sort
	int nbtex = (int)(Duree / 100);
	if(nbtex > 9) nbtex = 9;
	
	Moteur.AfficheTexture(TexSortSoin3[nbtex], Maitre->ReturnPosX(), Maitre->ReturnPosY(), Maitre->ReturnVersLaDroite() ? 64 : - 64, 64);
	
	return (Duree < 999);
}



