#include "const.h"
#include "item.h"

//Constructor
Item::Item()
{
	mSprite = new AnimatedSprite();
	init(NO_KIND, 0, 0, nullptr, nullptr);
}

//Destructor
Item::~Item()
{
	delete mSprite;
	init(NO_KIND, 0, 0, nullptr, nullptr);
}

//Iniciador
void Item::init(Uint8 value, float x, float y, LTexture *texture, SDL_Renderer *renderer)
{
	mClass = value;
	mEnabled = true;
	mTimeToLive = 600;
	mPosX = x;
	mPosY = y;
	mWidth = 16;
	mHeight = 16;
	mVelX = -1.0f + ((rand() % 5) * 0.5f);
	mVelY = -4.0f;
	mAccelX = 0.0f;
	mAccelY = 0.2f;
	mCollider.r = mWidth / 2;
	shiftColliders();

	mSprite->init(texture, renderer);
	mSprite->setAnimationFrames(0, 0, 0, 48, mWidth, mHeight);
	mSprite->setAnimationFrames(0, 1, 0, 64, mWidth, mHeight);
	mSprite->setCurrentFrame(0);
	mSprite->setAnimationCounter(0);
	mSprite->setAnimationNumFrames(0, 2);
	mSprite->setAnimationSpeed(0, 10);
	mSprite->setAnimationLoop(0, true);
	mSprite->setSpriteClip(mSprite->getAnimationClip(0, 0));

	switch (value)
	{
	case NO_KIND:
		mEnabled = false;
		mTimeToLive = 0;
		mPosX = 0;
		mPosY = 0;
		mWidth = 0;
		mHeight = 0;
		mVelX = 0;
		mVelY = 0;
		break;
	case ITEM_POINTS_1_DISK:
		mSprite->setAnimationFrames(0, 0, 16 * 0, 48, mWidth, mHeight);
		mSprite->setAnimationFrames(0, 1, 16 * 0, 64, mWidth, mHeight);
		break;
	case ITEM_POINTS_2_GAVINA:
		mSprite->setAnimationFrames(0, 0, 16 * 1, 48, mWidth, mHeight);
		mSprite->setAnimationFrames(0, 1, 16 * 1, 64, mWidth, mHeight);
		break;
	case ITEM_POINTS_3_PACMAR:
		mSprite->setAnimationFrames(0, 0, 16 * 2, 48, mWidth, mHeight);
		mSprite->setAnimationFrames(0, 1, 16 * 2, 64, mWidth, mHeight);
		break;
	case ITEM_CLOCK:
		mSprite->setAnimationFrames(0, 0, 16 * 3, 48, mWidth, mHeight);
		mSprite->setAnimationFrames(0, 1, 16 * 3, 64, mWidth, mHeight);
		break;
	case ITEM_TNT:
		mSprite->setAnimationFrames(0, 0, 16 * 4, 48, mWidth, mHeight);
		mSprite->setAnimationFrames(0, 1, 16 * 4, 64, mWidth, mHeight);
		break;
	case ITEM_COFFEE:
		mSprite->setAnimationFrames(0, 0, 16 * 5, 48, mWidth, mHeight);
		mSprite->setAnimationFrames(0, 1, 16 * 5, 64, mWidth, mHeight);
		break;
	default:
		break;
	}
}

//Centra el globo en la posición X
void Item::allignTo(int x)
{
	mPosX = float(x - (mWidth / 2));

	if (mPosX < PLAY_AREA_LEFT)
	{
		mPosX = PLAY_AREA_LEFT + 1;
	}
	else if ((mPosX + mWidth) > PLAY_AREA_RIGHT)
	{
		mPosX = float(PLAY_AREA_RIGHT - mWidth - 1);
	}

	//Posición X,Y del sprite
	mSprite->setPosX(int(mPosX));
	mSprite->setPosY(int(mPosY));

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

//Pinta el globo en la pantalla
void Item::render()
{
	if (mEnabled)
	{
		if (mTimeToLive > 200)
		{
			mSprite->render();
		}
		else if (mTimeToLive % 20 > 10)
		{
			mSprite->render();
		}
	}
}

//Actualiza la posición y estados del globo
void Item::move()
{
	//Calcula la nueva posición
	mPosX += mVelX;
	mPosY += mVelY;

	//Aplica las aceleraciones a la velocidad
	mVelX += mAccelX;
	mVelY += mAccelY;

	//Si queda fuera de pantalla, corregimos su posición y cambiamos su sentido
	if ((mPosX < PLAY_AREA_LEFT) || (mPosX + mWidth > PLAY_AREA_RIGHT))
	{
		//Corregir posición
		mPosX -= mVelX;

		//Invertir sentido
		mVelX = -mVelX;
	}

	//Si se sale por arriba
	if (mPosY < PLAY_AREA_TOP)
	{
		//Corrige
		mPosY = PLAY_AREA_TOP;

		//Invierte el sentido
		mVelY = -mVelY;
	}

	//Si el objeto se sale por la parte inferior
	if (mPosY + mHeight > PLAY_AREA_BOTTOM)
	{
		//Corrige
		mPosY -= mVelY;

		//Detiene el objeto
		mVelY = 0;
		mVelX = 0;
		mAccelX = 0;
		mAccelY = 0;
		mPosY = PLAY_AREA_BOTTOM - mHeight;
	}

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

//Pone a cero todos los valores del objeto
void Item::erase()
{
	init(NO_KIND, 0, 0, nullptr, nullptr);
}

//Actualiza al globo a su posicion, animación y controla los contadores
void Item::update()
{
	if (mEnabled)
	{
		move();
		shiftColliders();
		mSprite->animate(0);
		updateTimeToLive();
		checkTimeToLive();
	}
}

//Actualiza el contador
void Item::updateTimeToLive()
{
	if (mTimeToLive > 0)
	{
		--mTimeToLive;
	}
}

//Comprueba si el objeto sigue vivo
void Item::checkTimeToLive()
{
	if (mTimeToLive == 0)
	{
		erase();
	}
}

//Obtiene del valor de la variable
float Item::getPosX()
{
	return mPosX;
}

//Obtiene del valor de la variable
float Item::getPosY()
{
	return mPosY;
}

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

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

//Obtiene del valor de la variable
int Item::getClass()
{
	return mClass;
}

//Obtiene el valor de la variable
bool Item::isEnabled()
{
	return mEnabled;
}

//Establece el valor de la variable
void Item::setEnabled(bool value)
{
	mEnabled = value;
}

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

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