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

// Constructor
Item::Item(Uint8 kind, float x, float y, Texture *texture, std::vector<std::string> *animation, SDL_Renderer *renderer)
{
	sprite = new AnimatedSprite(texture, renderer, "", animation);

	this->kind = kind;
	enabled = true;
	timeToLive = 600;
	accelX = 0.0f;
	floorCollision = false;

	if (kind == ITEM_COFFEE_MACHINE)
	{
		width = 23;
		height = 29;
		posX = (((int)x + (PLAY_AREA_WIDTH / 2)) % (PLAY_AREA_WIDTH - width - 5)) + 2;
		posY = PLAY_AREA_TOP - height;
		velX = 0.0f;
		velY = -0.1f;
		accelY = 0.1f;
		collider.r = 10;
	}
	else
	{
		width = 16;
		height = 16;
		posX = x;
		posY = y;
		velX = -1.0f + ((rand() % 5) * 0.5f);
		velY = -4.0f;
		accelY = 0.2f;
		collider.r = width / 2;
	}

	sprite->setPosX(posX);
	sprite->setPosY(posY);
	shiftColliders();
}

// Destructor
Item::~Item()
{
	delete sprite;
}

// Centra el objeto en la posición X
void Item::allignTo(int x)
{
	posX = float(x - (width / 2));

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

	// Posición X,Y del sprite
	sprite->setPosX(int(posX));
	sprite->setPosY(int(posY));

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

// Pinta el objeto en la pantalla
void Item::render()
{
	if (enabled)
	{
		if (timeToLive > 200)
		{
			sprite->render();
		}
		else if (timeToLive % 20 > 10)
		{
			sprite->render();
		}
	}
}

// Actualiza la posición y estados del objeto
void Item::move()
{
	floorCollision = false;

	// Calcula la nueva posición
	posX += velX;
	posY += velY;

	// Aplica las aceleraciones a la velocidad
	velX += accelX;
	velY += accelY;

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

		// Invertir sentido
		velX = -velX;
	}

	// Si se sale por arriba rebota (excepto la maquina de café)
	if ((posY < PLAY_AREA_TOP) && !(kind == ITEM_COFFEE_MACHINE))
	{
		// Corrige
		posY -= velY;

		// Invierte el sentido
		velY = -velY;
	}

	// Si el objeto se sale por la parte inferior
	if (posY + height > PLAY_AREA_BOTTOM)
	{
		// Corrige
		posY -= velY;

		// Detiene el objeto
		velY = 0;
		velX = 0;
		accelX = 0;
		accelY = 0;
		posY = PLAY_AREA_BOTTOM - height;
		if (kind == ITEM_COFFEE_MACHINE)
		{
			floorCollision = true;
		}
	}

	// Actualiza la posición del sprite
	sprite->setPosX(int(posX));
	sprite->setPosY(int(posY));
	shiftColliders();
}

// Pone a cero todos los valores del objeto
void Item::disable()
{
	enabled = false;
}

// Actualiza el objeto a su posicion, animación y controla los contadores
void Item::update()
{
	move();
	sprite->animate();
	updateTimeToLive();
	checkTimeToLive();
}

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

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

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

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

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

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

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

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

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

// Alinea el circulo de colisión con la posición del objeto
void Item::shiftColliders()
{
	collider.x = int(posX + (width / 2));
	collider.y = int(posY + (height / 2));
}

// Informa si el objeto ha colisionado con el suelo
bool Item::isOnFloor()
{
	return floorCollision;
}