#include "const.h"
#include "globals.h"
#include "player.h"

//Constructor
Player::Player()
{
	init();
}

//Iniciador
void Player::init()
{	
	//Establece la altura y el ancho del jugador
	mWidth = 3 * BLOCK;
	mHeight = 3 * BLOCK;

	//Establece la posición inicial del jugador
	mPosX = PLAY_AREA_LEFT + (PLAY_AREA_WIDTH / 2) - (mWidth / 2);
	mPosY = PLAY_AREA_BOTTOM - mHeight;

	//Establece el tamaño del circulo de colisión
	mCollider.r = 7;

	//Actualiza la posición del circulo de colisión
	shiftColliders();

	//Establece la velocidad inicial
	mVelX = 0;
	mVelY = 0;

	//Establece la velocidad base
	mBaseSpeed = 1.5;

	//Establece el numero inicial de vidas
	mStartingLives = 3;
	mLives = mStartingLives;

	//Establece la puntuación inicial
	mScore = 0;

	//Inicia el contador
	mCooldown = 10;

	//Inicia el sprite
	mSprite.init();

	//Set width and height of the player sprite
	mSprite.setWidth(mWidth);
	mSprite.setHeight(mHeight);

	//Set sprite position
	mSprite.setPosX(mPosX);
	mSprite.setPosY(mPosY);

	//Set sprite sheet
	mSprite.setTexture(gPlayerTexture);

	//Set status
	mStatus = PLAYER_STATE_STOPPED;

	//Initialize animation variables
	mSprite.setCurrentFrame(0);
	mSprite.setAnimationCounter(0);

	mSprite.setAnimationNumFrames(PLAYER_STATE_STOPPED, 1);
	mSprite.setAnimationNumFrames(PLAYER_STATE_WALKING_LEFT, 4);
	mSprite.setAnimationNumFrames(PLAYER_STATE_WALKING_RIGHT, 4);
	
	mSprite.setAnimationSpeed(PLAYER_STATE_STOPPED, 10);
	mSprite.setAnimationSpeed(PLAYER_STATE_WALKING_LEFT, 5);
	mSprite.setAnimationSpeed(PLAYER_STATE_WALKING_RIGHT, 5);

	//Set animation clips
	mSprite.setAnimationFrames(PLAYER_STATE_WALKING_LEFT, 0, mSprite.getWidth() * 0, mSprite.getWidth() * 0, mSprite.getWidth(), mSprite.getHeight());
	mSprite.setAnimationFrames(PLAYER_STATE_WALKING_LEFT, 1, mSprite.getWidth() * 1, mSprite.getWidth() * 0, mSprite.getWidth(), mSprite.getHeight());
	mSprite.setAnimationFrames(PLAYER_STATE_WALKING_LEFT, 2, mSprite.getWidth() * 2, mSprite.getWidth() * 0, mSprite.getWidth(), mSprite.getHeight());
	mSprite.setAnimationFrames(PLAYER_STATE_WALKING_LEFT, 3, mSprite.getWidth() * 3, mSprite.getWidth() * 0, mSprite.getWidth(), mSprite.getHeight());
	mSprite.setAnimationFrames(PLAYER_STATE_WALKING_RIGHT, 0, mSprite.getWidth() * 0, mSprite.getHeight() * 1, mSprite.getWidth(), mSprite.getHeight());
	mSprite.setAnimationFrames(PLAYER_STATE_WALKING_RIGHT, 1, mSprite.getWidth() * 1, mSprite.getHeight() * 1, mSprite.getWidth(), mSprite.getHeight());
	mSprite.setAnimationFrames(PLAYER_STATE_WALKING_RIGHT, 2, mSprite.getWidth() * 2, mSprite.getHeight() * 1, mSprite.getWidth(), mSprite.getHeight());
	mSprite.setAnimationFrames(PLAYER_STATE_WALKING_RIGHT, 3, mSprite.getWidth() * 3, mSprite.getHeight() * 1, mSprite.getWidth(), mSprite.getHeight());
	mSprite.setAnimationFrames(PLAYER_STATE_STOPPED, 0, mSprite.getWidth() * 0, mSprite.getHeight() * 2, mSprite.getWidth(), mSprite.getHeight());

	//Set window for sprite sheet
	mSprite.setSpriteClip(mSprite.getAnimationClip(PLAYER_STATE_STOPPED, 0));
}

//Comprueba el teclado y actua en consecuencia
void Player::checkInput(Uint8 input)
{
	switch (input)
	{
	case INPUT_LEFT:
		mVelX = -mBaseSpeed;
		setStatus(PLAYER_STATE_WALKING_LEFT);
		break;

		case INPUT_RIGHT:
		mVelX = mBaseSpeed;
		setStatus(PLAYER_STATE_WALKING_RIGHT);
		break;
	
	default:
	mVelX = 0;
		setStatus(PLAYER_STATE_STOPPED);
		break;
	}
}

//Mueve el jugador a la posición y animación que le corresponde
void Player::move()
{
	//Move the player left or right
	mPosX += mVelX;

	//If the player went too far to the left or right
	if ((mPosX < PLAY_AREA_LEFT) || (mPosX + mWidth > PLAY_AREA_RIGHT))
	{
		//Move back
		mPosX -= mVelX;
	}

	//Move the player up or down
	mPosY += mVelY;

	//If the player went too far up or down
	if ((mPosY < PLAY_AREA_TOP) || (mPosY + mHeight > PLAY_AREA_BOTTOM))
	{
		//Move back
		mPosY -= mVelY;
	}

	//Update sprite position
	mSprite.setPosX(getPosX());
	mSprite.setPosY(mPosY);
}

//Pinta el jugador en pantalla
void Player::render()
{
	mSprite.render();
}

//Establece el estado del jugador
void Player::setStatus(int status)
{
	//Si cambiamos de estado, reiniciamos la animación
	if (mStatus != status)
	{
		mStatus = status;
		mSprite.setCurrentFrame(0);
	}
}

//Establece la animación correspondiente al estado
void Player::setAnimation()
{
	mSprite.animate(mStatus);
}

//Obtiene el valor de la variable
int Player::getPosX()
{
	return int(mPosX);
}

//Obtiene el valor de la variable
int Player::getPosY()
{
	return mPosY;
}

//Obtiene el valor de la variable
int Player::getWidth()
{
	return mWidth;
}

//Obtiene el valor de la variable
int Player::getHeight()
{
	return mHeight;
}

//Indica si el jugador puede disparar
bool Player::canFire()
{
	//Si el contador a llegado a cero, podemos disparar. En caso contrario decrementamos el contador
	if (mCooldown > 0)
	{
		return false;
	}
	else
	{
		return true;
	}
}

//Establece el valor de la variable
void Player::setFireCooldown(int time)
{
	mCooldown = time;
}

//Actualiza el valor de la variable
void Player::updateCooldown()
{
	if (mCooldown > 0)
	{
		--mCooldown;
	}
}

//Actualiza al jugador a su posicion, animación y controla los contadores
void Player::update()
{
	move();
	setAnimation();
	shiftColliders();	
	updateCooldown();
}

//Obtiene la puntuación del jugador
int Player::getScore()
{
	return mScore;
}

//Establece la puntuación del jugador
void Player::setScore(int score)
{
	mScore = score;
}

//Añade a la puntuación del jugador
void Player::addScore(int score)
{
	mScore += score;
}

//Obtiene el circulo de colisión
Circle &Player::getCollider()
{
	return mCollider;
}

//Actualiza el circulo de colisión a la posición del jugador
void Player::shiftColliders()
{
	//Align collider to center of player
	mCollider.x = mPosX + (mWidth / 2);
	mCollider.y = mPosY + (mHeight / 2);
}