#include "const.h"
#include "globals.h"
#include "balloon.h"

//Constructor
Balloon::Balloon()
{
	init(0, 0, NO_KIND, BALLON_VELX_POSITIVE, 0);
}

//Inicializador
void Balloon::init(int x, int y, Uint8 kind, float velx, Uint16 creationtimer)
{
	switch (kind)
	{
	case BALLOON_1:
		//Posición inicial
		mPosX = x;
		mPosY = y;

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

		//Inicializa los valores de velocidad y gravedad
		mVelX = velx;
		mVelY = 0;
		mMaxVelY = 3;
		mGravity = 0.09;
		mDefaultVelY = 3;

		//Puntos que da el globo al ser destruido
		mScore = 50;

		//Rectangulo con la imagen del sprite
		mSprite.setSpriteClip(37 + 21 + 13, 0, mWidth, mHeight);

		break;

	case BALLOON_2:
		//Posición inicial
		mPosX = x;
		mPosY = y;

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

		//Inicializa los valores de velocidad y gravedad
		mVelX = velx;
		mVelY = 0;
		mMaxVelY = 3;
		mGravity = 0.10;
		mDefaultVelY = 4;

		//Puntos que da el globo al ser destruido
		mScore = 100;

		//Rectangulo con la imagen del sprite
		mSprite.setSpriteClip(37 + 21, 0, mWidth, mHeight);

		break;

	case BALLOON_3:
		//Posición inicial
		mPosX = x;
		mPosY = y;

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

		//Inicializa los valores de velocidad y gravedad
		mVelX = velx;
		mVelY = 0;
		mMaxVelY = 3;
		mGravity = 0.10;
		mDefaultVelY = 4.5;

		//Puntos que da el globo al ser destruido
		mScore = 200;

		//Rectangulo con la imagen del sprite
		mSprite.setSpriteClip(37, 0, mWidth, mHeight);

		break;

	case BALLOON_4:
		//Posición inicial
		mPosX = x;
		mPosY = y;

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

		//Inicializa los valores de velocidad y gravedad
		mVelX = velx;
		mVelY = 0;
		mMaxVelY = 3;
		mGravity = 0.10;
		mDefaultVelY = 5;

		//Puntos que da el globo al ser destruido
		mScore = 400;

		//Rectangulo con la imagen del sprite
		mSprite.setSpriteClip(0, 0, mWidth, mHeight);

		break;

	default:
		//Posición inicial
		mPosX = x;
		mPosY = y;

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

		//Inicializa los valores de velocidad y gravedad
		mVelX = velx;
		mVelY = 0;
		mMaxVelY = 0;
		mGravity = 0;
		mDefaultVelY = 0;

		//Puntos que da el globo al ser destruido
		mScore = 0;

		//Rectangulo con la imagen del sprite
		mSprite.setSpriteClip(0, 0, mWidth, mHeight);

		break;
	}

	//Textura con los gráficos del sprite
	mSprite.setTexture(gBalloonTexture);

	//Alto y ancho del sprite
	mSprite.setWidth(mWidth);
	mSprite.setHeight(mHeight);

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

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

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

	//Inicializa variables
	mStopped = true;
	mStoppedTimer = 0;
	mBlinking = false;
	mVisible = true;
	mInvulnerable = false;
	mBeingCreated = true;
	mCreationTimer = creationtimer;

	//Tipo
	mKind = kind;
}

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

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

	//Posición X,Y del sprite
	mSprite.setPosX(getPosX());
	mSprite.setPosY(getPosY());

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

//Pinta el globo en la pantalla
void Balloon::render()
{
	if (mVisible)
	{
		mSprite.render();
	}
}

//Actualiza la posición y estados del globo
void Balloon::move()
{
	//Comprobamos si se puede mover
	if (isStopped() == false)
	{
		//Lo movemos a izquierda o derecha
		mPosX += mVelX;

		//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;
		}

		//Mueve el globo hacia arriba o hacia abajo
		mPosY += int(mVelY);

		//Si se sale por arriba
		if (mPosY < PLAY_AREA_TOP)
		{
			//Corregimos
			mPosY -= int(mVelY);

			//Invertimos sentido
			mVelY = -mVelY;
		}

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

			//Invertimos colocando una velocidad por defecto
			mVelY = -mDefaultVelY;
		}

		//Aplica gravedad al objeto, sin pasarse de un limite establecido
		if (int(mVelY) > mMaxVelY)
		{
			mVelY = mMaxVelY;
		}
		else
		{
			mVelY += mGravity;
		}

		//Actualiza la posición del sprite
		mSprite.setPosX(getPosX());
		mSprite.setPosY(mPosY);

		//Actualiza la posición del circulo de colisión
		shiftColliders();
	}
	//Si no se puede mover:
	//Comprobar si se está creando
	else if (isBeingCreated() == true)
	{
		//Actualiza el valor de las variables
		setStop(true);
		setInvulnerable(true);

		//Todavia tiene tiempo en el contador
		if (mCreationTimer > 0)
		{
			//Desplaza lentamente el globo hacia abajo y hacia un lado
			if (mCreationTimer % 10 == 0)
			{
				++mPosY;
				mPosX += mVelX;

				//Actualiza la posición del sprite
				mSprite.setPosX(getPosX());
				mSprite.setPosY(mPosY);

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

			//Hace visible el globo de forma intermitente
			if (mCreationTimer > 100)
			{
				setVisible(mCreationTimer / 10 % 2 == 0);
			}
			else
			{
				setVisible(mCreationTimer / 5 % 2 == 0);
			}

			--mCreationTimer;
		}
		//El contador ha llegado a cero
		else
		{
			setBeingCreated(false);
			setStop(false);
			setVisible(true);
			setInvulnerable(false);
		}
	}
	//Comprobar si está detenido
	else if (isStopped() == true)
	{
		//Si todavía está detenido, reduce el contador
		if (mStoppedTimer > 0)
		{
			--mStoppedTimer;
		} //Si el contador ha llegado a cero, ya no está detenido
		else
		{
			setStop(false);
		}
	}
}

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

//Comprueba si el globo tiene algun tipo asignado
bool Balloon::isActive()
{
	if (mKind == NO_KIND)
	{
		return false;
	}
	else
	{
		return true;
	}
}

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

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

//Obtiene del valor de la variable
float Balloon::getVelY()
{
	return mVelY;
}

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

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

//Establece el valor de la variable
void Balloon::setVelY(float velY)
{
	mVelY = velY;
}

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

//Establece el valor de la variable
void Balloon::setStop(bool state)
{
	mStopped = state;
}

//Obtiene del valor de la variable
bool Balloon::isStopped()
{
	return mStopped;
}

//Establece el valor de la variable
void Balloon::setBlink(bool state)
{
	mBlinking = state;
}

//Obtiene del valor de la variable
bool Balloon::isBlinking()
{
	return mBlinking;
}

//Establece el valor de la variable
void Balloon::setVisible(bool state)
{
	mVisible = state;
}

//Obtiene del valor de la variable
bool Balloon::isVisible()
{
	return mVisible;
}

//Establece el valor de la variable
void Balloon::setInvulnerable(bool state)
{
	mInvulnerable = state;
}

//Obtiene del valor de la variable
bool Balloon::isInvulnerable()
{
	return mInvulnerable;
}

//Establece el valor de la variable
void Balloon::setBeingCreated(bool state)
{
	mBeingCreated = state;
}

//Obtiene del valor de la variable
bool Balloon::isBeingCreated()
{
	return mBeingCreated;
}

//Establece el valor de la variable
void Balloon::setStoppedTimer(Uint16 time)
{
	mStoppedTimer = time;
}

//Obtiene del valor de la variable
Uint16 Balloon::getStoppedTimer()
{
	return mStoppedTimer;
}

//Obtiene del valor de la variable
Uint16 Balloon::getScore()
{
	return mScore;
}

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

//Alinea el circulo de colisión con la posición del objeto globo
void Balloon::shiftColliders()
{
	//Align collider to center of balloon
	mCollider.x = mPosX + mCollider.r;
	mCollider.y = mPosY + mCollider.r;
}