#include "instructions.h"

const Uint8 SELF = 0;

// Constructor
Instructions::Instructions(SDL_Renderer *renderer, Screen *screen, Asset *asset, Lang *lang)
{
	// Copia los punteros
	this->renderer = renderer;
	this->screen = screen;
	this->asset = asset;
	this->lang = lang;

	// Reserva memoria para los punteros
	LTexture *item1 = new LTexture(renderer, asset->get("item_points1_disk.png"));
	itemTextures.push_back(item1);

	LTexture *item2 = new LTexture(renderer, asset->get("item_points2_gavina.png"));
	itemTextures.push_back(item2);

	LTexture *item3 = new LTexture(renderer, asset->get("item_points3_pacmar.png"));
	itemTextures.push_back(item3);

	LTexture *item4 = new LTexture(renderer, asset->get("item_clock.png"));
	itemTextures.push_back(item4);

	LTexture *item5 = new LTexture(renderer, asset->get("item_coffee.png"));
	itemTextures.push_back(item5);

	LTexture *item6 = new LTexture(renderer, asset->get("item_coffee_machine.png"));
	itemTextures.push_back(item6);

	eventHandler = new SDL_Event();

	sprite = new Sprite(0, 0, 16, 16, itemTextures.at(0), renderer);
	text = new Text(asset->get("smb2.png"), asset->get("smb2.txt"), renderer);

	// Crea un backbuffer para el renderizador
	backbuffer = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, GAME_WIDTH, GAME_HEIGHT);
	if (backbuffer == nullptr)
	{
		printf("Backbuffer could not be created!\nSDL Error: %s\n", SDL_GetError());
	}

	// Inicializa variables
	section.name = SELF;
	ticks = 0;
	ticksSpeed = 15;
	manualQuit = false;
	counter = 0;
	counterEnd = 600;
}

// Destructor
Instructions::~Instructions()
{
	for (auto texture : itemTextures)
	{
		texture->unload();
		delete texture;
	}
	itemTextures.clear();

	delete sprite;
	delete eventHandler;
	delete text;

	SDL_DestroyTexture(backbuffer);
}

// Actualiza las variables
void Instructions::update()
{
	// Comprueba los eventos
	checkEventHandler();

	// Actualiza las variables
	if (SDL_GetTicks() - ticks > ticksSpeed)
	{
		// Actualiza el contador de ticks
		ticks = SDL_GetTicks();

		if (mode == m_auto)
		{ // Modo automático
			counter++;

			if (counter == counterEnd)
			{
				section.name = PROG_SECTION_TITLE;
				section.subsection = TITLE_SECTION_1;
			}
		}
		else
		{ // Modo manual
			++counter %= 60000;

			if (manualQuit)
			{
				section.name = PROG_SECTION_TITLE;
				section.subsection = TITLE_SECTION_3;
			}
		}
	}
}

// Pinta en pantalla
void Instructions::render()
{
	// Pinta en pantalla
	SDL_Rect window = {0, 0, GAME_WIDTH, GAME_HEIGHT};
	SDL_Rect srcRect = {0, 0, 16, 16};

	const color_t orangeColor = {0xFF, 0x7A, 0x00};

	const SDL_Rect destRect1 = {60, 88 + (16 * 0), 16, 16}; // Disquito
	const SDL_Rect destRect2 = {60, 88 + (16 * 1), 16, 16}; // Gavineixon
	const SDL_Rect destRect3 = {60, 88 + (16 * 2), 16, 16}; // Pacmar
	const SDL_Rect destRect4 = {60, 88 + (16 * 3), 16, 16}; // Time Stopper
	const SDL_Rect destRect5 = {60, 88 + (16 * 4), 16, 16}; // Coffee

	// Pinta en el backbuffer el texto y los sprites
	SDL_SetRenderTarget(renderer, backbuffer);
	SDL_SetRenderDrawColor(renderer, bgColor.r, bgColor.g, bgColor.b, 255);
	SDL_RenderClear(renderer);

	// Escribe el texto
	text->writeDX(TXT_CENTER | TXT_COLOR | TXT_SHADOW, SCREEN_CENTER_X, 8, lang->getText(11), 1, orangeColor, 1, shdwTxtColor);
	text->writeDX(TXT_CENTER | TXT_COLOR | TXT_SHADOW, SCREEN_CENTER_X, 24, lang->getText(12), 1, noColor, 1, shdwTxtColor);
	text->writeDX(TXT_CENTER | TXT_COLOR | TXT_SHADOW, SCREEN_CENTER_X, 34, lang->getText(13), 1, noColor, 1, shdwTxtColor);
	text->writeDX(TXT_CENTER | TXT_COLOR | TXT_SHADOW, SCREEN_CENTER_X, 48, lang->getText(14), 1, noColor, 1, shdwTxtColor);
	text->writeDX(TXT_CENTER | TXT_COLOR | TXT_SHADOW, SCREEN_CENTER_X, 58, lang->getText(15), 1, noColor, 1, shdwTxtColor);
	text->writeDX(TXT_CENTER | TXT_COLOR | TXT_SHADOW, SCREEN_CENTER_X, 75, lang->getText(16), 1, orangeColor, 1, shdwTxtColor);

	text->writeShadowed(84, 92, lang->getText(17), shdwTxtColor);
	text->writeShadowed(84, 108, lang->getText(18), shdwTxtColor);
	text->writeShadowed(84, 124, lang->getText(19), shdwTxtColor);
	text->writeShadowed(84, 140, lang->getText(20), shdwTxtColor);
	text->writeShadowed(84, 156, lang->getText(21), shdwTxtColor);

	if ((mode == m_manual) && (counter % 50 > 14))
	{
		text->writeDX(TXT_CENTER | TXT_COLOR | TXT_SHADOW, SCREEN_CENTER_X, GAME_HEIGHT - 12, lang->getText(22), 1, orangeColor, 1, shdwTxtColor);
	}

	// Disquito
	sprite->setTexture(itemTextures.at(0));
	sprite->setPos(destRect1);
	srcRect.y = 16 * (((counter + 12) / 36) % 2);
	sprite->setSpriteClip(srcRect);
	sprite->render();

	// Gavineixon
	sprite->setTexture(itemTextures.at(1));
	sprite->setPos(destRect2);
	srcRect.y = 16 * (((counter + 9) / 36) % 2);
	sprite->setSpriteClip(srcRect);
	sprite->render();

	// Pacmar
	sprite->setTexture(itemTextures.at(2));
	sprite->setPos(destRect3);
	srcRect.y = 16 * (((counter + 6) / 36) % 2);
	sprite->setSpriteClip(srcRect);
	sprite->render();

	// Time Stopper
	sprite->setTexture(itemTextures.at(3));
	sprite->setPos(destRect4);
	srcRect.y = 16 * (((counter + 3) / 36) % 2);
	sprite->setSpriteClip(srcRect);
	sprite->render();

	// Coffee
	sprite->setTexture(itemTextures.at(4));
	sprite->setPos(destRect5);
	srcRect.y = 16 * (((counter + 0) / 36) % 2);
	sprite->setSpriteClip(srcRect);
	sprite->render();

	// Cambia el destino de renderizado
	SDL_SetRenderTarget(renderer, nullptr);

	// Prepara para empezar a dibujar en la textura de juego
	screen->start();

	// Limpia la pantalla
	screen->clean(bgColor);

	// Establece la ventana del backbuffer
	if (mode == m_auto)
	{
		window.y = std::max(8, GAME_HEIGHT - counter + 100);
	}
	else
	{
		window.y = 0;
	}

	// Copia el backbuffer al renderizador
	SDL_RenderCopy(renderer, backbuffer, nullptr, &window);

	// Vuelca el contenido del renderizador en pantalla
	screen->blit();
}

// Comprueba los eventos
void Instructions::checkEventHandler()
{
	// Comprueba los eventos que hay en la cola
	while (SDL_PollEvent(eventHandler) != 0)
	{
		// Evento de salida de la aplicación
		if (eventHandler->type == SDL_QUIT)
		{
			section.name = PROG_SECTION_QUIT;
			break;
		}

		if ((eventHandler->type == SDL_KEYUP) || (eventHandler->type == SDL_JOYBUTTONUP))
		{
			if (mode == m_auto)
			{
				JA_StopMusic();
				section.name = PROG_SECTION_TITLE;
				section.subsection = TITLE_SECTION_1;
			}
			else
			{
				if (counter > 30)
				{
					manualQuit = true;
				}
			}
		}
	}
}

// Bucle para la pantalla de instrucciones
section_t Instructions::run(mode_e mode)
{
	this->mode = mode;

	while (section.name == SELF)
	{
		update();
		render();
	}

	return section;
}
