/*Copyright (C) 2010 Deveaux Duncan

This file is part of Hikou no mizu.

Hikou no mizu is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

Hikou no mizu is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with Hikou no mizu.  If not, see <http://www.gnu.org/licenses/>.
*/

#include "Joueur.hpp"

Joueur::Joueur(std::string pNom, int pVies, int pEnergie, int pPuissance, int pVitesse, MoteurPhysique *pMoteurPhysique) :
nom(pNom), maxVies(pVies), maxEnergie(pEnergie), puissance(pPuissance), vitesse(pVitesse), moteurPhysique(pMoteurPhysique)
{
	oldVies = vies = maxVies;
	oldEnergie = energie = maxEnergie;
	baseEnergieSaut = energieSaut = 33;
	
	std::string cheminAnimations = "data/gfx/personnages/" + nom + "/";
	gestionAnimations = new GestionnaireAnimation(cheminAnimations, cheminAnimations + "animations.xml");
}

Joueur::~Joueur()
{
	delete gestionAnimations;
}

void Joueur::executeActions(const sf::Input &pTouches)
{	
	gestionAnimations->executeAnimation();
	
	Animation *animationActuelle = gestionAnimations->getActAnimation();
	if (etat.isAttacking() && animationActuelle->getActFrame() == animationActuelle->getNbFrames() - 2)
	{	//Fin d'une attaque
		ObjetPhysique *objetTouche = moteurPhysique->testCollisionObjet(this);
		if (objetTouche != NULL) //touché
			objetTouche->prendreCoup(getPuissance());
		
		etat.setAttaque(false);
	}
	
	//Saut
	if (etat.isJumping())
	{
		if (energieSaut != 0)
		{
			moteurPhysique->deplaceObjetY(this, getPositionY() - energieSaut);
			energieSaut--;
		}
		
		if (moteurPhysique->isATerre(this))
		{
			etat.setSaut(false);
			energieSaut = baseEnergieSaut;
		}
	}
	
	if (pTouches.IsKeyDown(sf::Key::F)) bouger(0);
	else if (pTouches.IsKeyDown(sf::Key::H)) bouger(1);
	else arreter();
	
	if (pTouches.IsKeyDown(sf::Key::W) && nom != "Hikou") sauter();
	if (pTouches.IsKeyDown(sf::Key::A) && nom != "Hikou") attaquer();
}

void Joueur::bouger(int pSens)
{
	if (pSens == 0)
		moteurPhysique->deplaceObjetX(this, getPositionX() - vitesse);
	else if (pSens == 1)
		moteurPhysique->deplaceObjetX(this, getPositionX() + vitesse);
	
	if (getSens() != pSens)
		setSens(pSens);
	
	gestionAnimations->lanceAnimation(1);
}

void Joueur::arreter()
{
	gestionAnimations->lanceAnimation(0);
}

void Joueur::sauter()
{
	if (!etat.isJumping() && moteurPhysique->isATerre(this))
		etat.setSaut(true);
}

void Joueur::attaquer()
{
	if (!gestionAnimations->getAnimBloquanteLancee() && !etat.isAttacking())
	{
		etat.setAttaque(true);
		gestionAnimations->lanceAnimation(2, true);
	}
}

void Joueur::prendreCoup(int pPuissance)
{
	int viesRestantes = getVies() - pPuissance;
	if (viesRestantes < 0)
		viesRestantes = 0;
			
	setVies(viesRestantes);
	
	if (!gestionAnimations->getAnimBloquanteLancee() && !etat.isAttacking())
		gestionAnimations->lanceAnimation(3, true);
}

//Graphics methods
void Joueur::demarreAffichage(MoteurGraphique &pMoteurRendu)
{
	gestionAnimations->demarreAffichage(pMoteurRendu);
}

void Joueur::supprimeAffichage(MoteurGraphique &pMoteurRendu)
{
	gestionAnimations->supprimeAffichage(pMoteurRendu);
}

//Physics methods
void Joueur::setMoteurPhysique(MoteurPhysique *pMoteurPhysique)
{
	moteurPhysique = pMoteurPhysique;
}

MoteurPhysique *Joueur::getMoteurPhysique() const
{
	return moteurPhysique;
}

//get-set methods
std::string Joueur::getNom() const
{
	return nom;
}

void Joueur::setVies(int pVies)
{
	vies = pVies;
}

int Joueur::getVies() const
{
	return vies;
}

void Joueur::setMaxVies(int pMaxVies)
{
	maxVies = pMaxVies;
}

int Joueur::getMaxVies() const
{
	return maxVies;
}

void Joueur::setEnergie(int pEnergie)
{
	energie = pEnergie;
}

int Joueur::getEnergie() const
{
	return energie;
}

void Joueur::setMaxEnergie(int pMaxEnergie)
{
	maxEnergie = pMaxEnergie;
}

int Joueur::getMaxEnergie() const
{
	return maxEnergie;
}

void Joueur::setPuissance(int pPuissance)
{
	puissance = pPuissance;
}

int Joueur::getPuissance() const
{
	return puissance;
}

void Joueur::setVitesse(int pVitesse)
{
	vitesse = pVitesse;
}

int Joueur::getVitesse() const
{
	return vitesse;
}

void Joueur::setSens(int pSens)
{
	if (pSens == 0 || pSens == 1)
	{
		gestionAnimations->setSensAnimations(pSens);
	}
}

int Joueur::getSens() const
{
	return gestionAnimations->getSensAnimations();
}

//events methods
bool Joueur::vieChangee()
{
	if (oldVies != vies)
	{
		oldVies = vies;
		return true;
	}
	
	return false;
}

bool Joueur::energieChangee()
{
	if (oldEnergie != energie)
	{
			oldEnergie = energie;
			return true;
	}
	
	return false;
}

//ObjetPhysique virtual methods
const sf::Vector2f &Joueur::getOrigin() const
{
	return gestionAnimations->getOrigineAnimation();
}

float Joueur::getLargeur() const
{
	return gestionAnimations->getLargeurAnimation();
}

float Joueur::getHauteur() const
{
	return gestionAnimations->getHauteurAnimation();
}

void Joueur::setPositionX(float pPosition)
{
	gestionAnimations->setPositionAnimationsX(pPosition);
}

float Joueur::getPositionX() const
{
	return gestionAnimations->getPositionAnimationsX();
}

void Joueur::setPositionY(float pPosition)
{
	gestionAnimations->setPositionAnimationsY(pPosition);
}

float Joueur::getPositionY() const
{
	return gestionAnimations->getPositionAnimationsY();
}