#include "const.h"
#include "bullet.h"

// Constructor
Bullet::Bullet(int x, int y, int kind, bool poweredUp, int owner, LTexture *texture, SDL_Renderer *renderer)
{
	mSprite = new Sprite({x,y,10,10},texture, renderer);

	// Posición inicial del objeto
	mPosX = x;
	mPosY = y;

	// Alto y ancho del objeto
	mWidth = 10;
	mHeight = mWidth;

	// Velocidad inicial en el eje Y
	mVelY = -3;

	// Tipo de bala
	mKind = kind;

	// Identificador del dueño del objeto
	mOwner = owner;

	// Valores especificos según el tipo
	switch (kind)
	{
	case BULLET_UP:
		// Establece la velocidad inicial
		mVelX = 0;

		// Rectangulo con los gráficos del objeto
		if (!poweredUp)
			mSprite->setSpriteClip(0 * mWidth, 0, mSprite->getWidth(), mSprite->getHeight());
		else
			mSprite->setSpriteClip((0 + 3) * mWidth, 0, mSprite->getWidth(), mSprite->getHeight());
		break;

	case BULLET_LEFT:
		// Establece la velocidad inicial
		mVelX = -2;

		// Rectangulo con los gráficos del objeto
		if (!poweredUp)
			mSprite->setSpriteClip(1 * mWidth, 0, mSprite->getWidth(), mSprite->getHeight());
		else
			mSprite->setSpriteClip((1 + 3) * mWidth, 0, mSprite->getWidth(), mSprite->getHeight());
		break;

	case BULLET_RIGHT:
		// Establece la velocidad inicial
		mVelX = 2;

		// Rectangulo con los gráficos del objeto
		if (!poweredUp)
			mSprite->setSpriteClip(2 * mWidth, 0, mSprite->getWidth(), mSprite->getHeight());
		else
			mSprite->setSpriteClip((2 + 3) * mWidth, 0, mSprite->getWidth(), mSprite->getHeight());
		break;

	default:
		break;
	}

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

	// Alinea el circulo de colisión con el objeto
	shiftColliders();
}

// Destructor
Bullet::~Bullet()
{
	delete mSprite;
	mSprite = nullptr;
}

// Pinta el objeto en pantalla
void Bullet::render()
{
	mSprite->render();
}

// Actualiza la posición y estado del objeto en horizontal
Uint8 Bullet::move()
{
	// Variable con el valor de retorno
	Uint8 msg = BULLET_MOVE_OK;

	// Mueve el objeto a su nueva posición
	mPosX += mVelX;

	// Si el objeto se sale del area de juego por los laterales
	if ((mPosX < PLAY_AREA_LEFT) || (mPosX + mWidth > PLAY_AREA_RIGHT))
	{
		// Se deshabilita
		mKind = NO_KIND;

		// Mensaje de salida
		msg = BULLET_MOVE_OUT;
	}

	// Mueve el objeto a su nueva posición en vertical
	mPosY += int(mVelY);

	// Si el objeto se sale del area de juego por la parte superior o inferior
	if ((mPosY < PLAY_AREA_TOP) || (mPosY + mHeight > PLAY_AREA_BOTTOM))
	{
		// Se deshabilita
		mKind = NO_KIND;

		// Mensaje de salida
		msg = BULLET_MOVE_OUT;
	}

	// Actualiza la posición del sprite
	mSprite->setPosX(mPosX);
	mSprite->setPosY(mPosY);

	// Alinea el circulo de colisión con el objeto
	shiftColliders();

	return msg;
}

// Comprueba si el objeto está activo
bool Bullet::isActive()
{
	if (mKind == NO_KIND)
		return false;
	else
		return true;
}

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

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

// Establece el valor de la variable
void Bullet::setPosX(int x)
{
	mPosX = x;
}

// Establece el valor de la variable
void Bullet::setPosY(int y)
{
	mPosY = y;
}

// Obtiene el valor de la variable
int Bullet::getVelY()
{
	return mVelY;
}

// Obtiene el valor de la variable
int Bullet::getKind()
{
	return mKind;
}

// Obtiene el valor de la variable
int Bullet::getOwner()
{
	return mOwner;
}

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

// Alinea el circulo de colisión con el objeto
void Bullet::shiftColliders()
{
	mCollider.x = mPosX + mCollider.r;
	mCollider.y = mPosY + mCollider.r;
}
