#include "ifdefs.h"
#include "const.h"
#include "text.h"
#include "menu.h"

//Constructor
Menu::Menu()
{
	init(0, 0, 0, nullptr, nullptr, nullptr);
}

Menu::~Menu()
{
	mRenderer = nullptr;
	mText = nullptr;
}

//Inicializador
void Menu::init(int x, int y, int backgroundType, LTexture *texture, SDL_Renderer *renderer, Text *text)
{
	//Inicia variables
	mSelectorIndex = 0;
	mTotalItems = 0;
	mItemSelected = MENU_NO_OPTION;
	mPosX = x;
	mPosY = y;
	mRect.x = 0;
	mRect.y = 0;
	mRect.w = 0;
	mRect.h = 0;
	mRectR = 0;
	mRectG = 0;
	mRectB = 0;
	mBackgroundType = backgroundType;
	mText = text;
	mRenderer = renderer;

	//Sprite con los graficos del selector
	mSelectorSprite.setWidth(8);
	mSelectorSprite.setHeight(8);
	mSelectorSprite.setPosX(0);
	mSelectorSprite.setPosY(0);
	mSelectorSprite.setTexture(texture);
	mSelectorSprite.setRenderer(renderer);
	mSelectorSprite.setSpriteClip(0, 0, mSelectorSprite.getWidth(), mSelectorSprite.getHeight());

	//Elementos del menu
	for (int i = 0; i < 10; i++)
	{
		mMenuItem[i].label = "";
		mMenuItem[i].x = x;
		mMenuItem[i].y = y + (10 * i);
	}

	//Mueve el grafico del selector al elemento seleccionado
	moveSelectorSprite(mSelectorIndex);
}

//Obtiene el valor de la variable
Uint8 Menu::getItemSelected()
{
	return mItemSelected;
}

//Mueve el grafico del selector al elemento seleccionado
void Menu::moveSelectorSprite(int pos)
{
	mSelectorSprite.setPosX(mMenuItem[pos].x - (BLOCK * 1));
	mSelectorSprite.setPosY(mMenuItem[pos].y);
}

//Deja el menu apuntando al primer elemento
void Menu::resetMenu()
{
	mItemSelected = MENU_NO_OPTION;
	mSelectorIndex = 0;
	moveSelectorSprite(mSelectorIndex);
}

//Deja el menu apuntando al siguiente elemento
void Menu::increaseSelectorIndex()
{
	if (mSelectorIndex < (mTotalItems - 1))
	{
		++mSelectorIndex;
	}
}

//Deja el menu apuntando al elemento anterior
void Menu::decreaseSelectorIndex()
{
	if (mSelectorIndex > 0)
	{
		--mSelectorIndex;
	}
}

//Comprueba la entrada (teclado, gamepad) y actua en consecuencia
void Menu::checkInput(Uint8 input)
{
	switch (input)
	{
	case INPUT_UP:
		decreaseSelectorIndex();
		moveSelectorSprite(mSelectorIndex);
		break;
	case INPUT_DOWN:
		increaseSelectorIndex();
		moveSelectorSprite(mSelectorIndex);
		break;
	case INPUT_ACCEPT:
		mItemSelected = mSelectorIndex;
		break;
	case INPUT_CANCEL:
		resetMenu();
		break;
	}
}

//Pinta el menu en pantalla
void Menu::render()
{
	//Render color filled quad
	if (mBackgroundType == MENU_BACKGROUND_SOLID)
	{
		SDL_SetRenderDrawColor(mRenderer, mRectR, mRectG, mRectB, mRectA);
		SDL_RenderFillRect(mRenderer, &mRect);
	}

	//Render text
	mSelectorSprite.render();
	for (Uint8 i = 0; i < mTotalItems; i++)
	{
		mText->write(mMenuItem[i].x, mMenuItem[i].y, mMenuItem[i].label, 0);
	}
}

//Establece el rectangulo de fondo del menu
void Menu::setRectSize()
{
	Uint8 i = 0;
	Uint16 maxLength = 0;

	//La altura se corresponde al numero de items mas un hueco arriba y otro abajo
	mRect.h = (mTotalItems + 2) * mText->getSize();

	//La anchura es la de la cadena mas larga mas tres bloques, uno por la derecha
	//y dos por la izquierda, uno de ellos para el selector
	for (i = 0; i < mTotalItems; i++)
	{
		if (mText->lenght(mMenuItem[i].label, 0) > maxLength)
		//if (mMenuItem[i].label.length() > maxLength)
		{
			//maxLength = mMenuItem[i].label.length();
			maxLength = mText->lenght(mMenuItem[i].label, 0);
		}
	}
	//mRect.w = int((maxLength + 3) * BLOCK);
	mRect.w = maxLength + (mText->getSize() * 3);

	mRect.x = mPosX - (BLOCK * 2);
	mRect.y = mPosY - BLOCK;
}

//Establece el valor de la variable
void Menu::setTotalItems(int num)
{
	mTotalItems = num;
}

//Establece el color del rectangulo de fondo
void Menu::setBackgroundColor(int r, int g, int b, int alpha)
{
	mRectR = r;
	mRectG = g;
	mRectB = b;
	mRectA = alpha;
}

//Centra el menu en pantalla
void Menu::centerMenu(int value)
{
	//Actualiza el rectangulo de fondo para recalcular las dimensiones
	setRectSize();

	//Establece la nueva posición centrada en funcion del ancho
	//de la pantalla y del ancho del rectangulo
	mPosX = (value) - (mRect.w / 2) + (mText->getSize() * 2);

	//Reposiciona los elementos del menu
	for (Uint8 i = 0; i < 10; i++)
	{
		mMenuItem[i].x = mPosX;
	}

	//Recalcula el rectangulo de fondo
	setRectSize();

	//Recoloca el selector
	moveSelectorSprite(mSelectorIndex);
}

//Centra los elementos del menu respecto a un punto
void Menu::centerMenuElements(int value)
{
	for (Uint8 i = 0; i < mTotalItems; i++)
	{
		mMenuItem[i].x = (value - ((mText->lenght(mMenuItem[i].label,0))/2));
	}

	//Mueve el grafico del selector al elemento seleccionado
	moveSelectorSprite(mSelectorIndex);
}

//Añade un item al menu
void Menu::addItem(std::string text)
{
	if (mTotalItems < 10)
	{
		mMenuItem[mTotalItems].label = text;
		setTotalItems(mTotalItems + 1);
		setRectSize();
	}
}