#include "title.h"

// Constructor
Title::Title(SDL_Renderer *renderer, Screen *screen, Resource *resource, Asset *asset, options_t *options, section_t *section)
{
	// Copia la dirección de los objetos
	this->resource = resource;
	this->renderer = renderer;
	this->screen = screen;
	this->asset = asset;
	this->options = options;
	this->section = section;

	// Reserva memoria para los punteros
	eventHandler = new SDL_Event();
	if (options->palette == p_zxspectrum)
	{
		texture = resource->getTexture("loading_screen_color.png");
	}
	else if (options->palette == p_zxarne)
	{
		texture = resource->getTexture("loading_screen_color_zxarne.png");
	}
	sprite = new Sprite(0, 0, texture->getWidth(), texture->getHeight(), texture, renderer);
	text = new Text(resource->getOffset("smb2.txt"), resource->getTexture("smb2.png"), renderer);

	// Inicializa variables
	counter = 0;
	section->name = SECTION_PROG_TITLE;
	section->subsection = 0;
	ticks = 0;
	ticksSpeed = 15;
	longText = "HEY JAILERS!! IT'S 2022 AND WE'RE STILL ROCKING LIKE IT'S 1998!!! HAVE YOU HEARD IT? JAILGAMES ARE BACK!! YEEESSS BACK!! MORE THAN 10 TITLES ON JAILDOC'S KITCHEN!! THATS A LOOOOOOT OF JAILGAMES, BUT WHICH ONE WILL STRIKE FIRST? THERE IS ALSO A NEW DEVICE TO COME THAT WILL BLOW YOUR MIND WITH JAILGAMES ON THE GO: P.A.C.O. BUT WAIT! WHAT'S THAT BEAUTY I'M SEEING RIGHT OVER THERE?? OOOH THAT TINY MINIASCII IS PURE LOVE!! I WANT TO LICK EVERY BYTE OF IT!! OH SHIT! AND DON'T FORGET TO BRING BACK THOSE OLD AND FAT MS-DOS JAILGAMES TO GITHUB TO KEEP THEM ALIVE!! WHAT WILL BE THE NEXT JAILDOC RELEASE? WHAT WILL BE THE NEXT PROJECT TO COME ALIVE?? OH BABY WE DON'T KNOW BUT HERE YOU CAN FIND THE ANSWER, YOU JUST HAVE TO COMPLETE JAILDOCTOR'S DILEMMA ... COULD YOU?";
	for (int i = 0; i < (int)longText.length(); ++i)
	{
		letter_t l;
		l.letter = longText.substr(i, 1);
		l.x = 256;
		l.enabled = false;
		letters.push_back(l);
	}
	letters[0].enabled = true;
	marqueeSpeed = 3;

	// Crea el cartel de PRESS ENTER
	const std::string caption = "PRESS ENTER TO PLAY";
	const color_t textColor = stringToColor(options->palette, "white");
	const color_t strokeColor = stringToColor(options->palette, "bright_blue");

	// Crea la textura
	pressEnterTexture = new Texture(renderer);
	pressEnterTexture->createBlank(renderer, text->lenght(caption) + 2, text->getCharacterSize() + 2, SDL_TEXTUREACCESS_TARGET);
	pressEnterTexture->setAsRenderTarget(renderer);
	pressEnterTexture->setBlendMode(SDL_BLENDMODE_BLEND);
	text->writeDX(TXT_COLOR | TXT_STROKE, 1, 1, caption, 1, textColor, 1, strokeColor);

	// Crea el sprite
	pressEnterSprite = new Sprite(128 - (pressEnterTexture->getWidth() / 2), 192 / 5 * 4, pressEnterTexture->getWidth(), pressEnterTexture->getHeight(), pressEnterTexture, renderer);

	// Cambia el color del borde
	screen->setBorderColor(stringToColor(options->palette, "bright_blue"));
}

// Destructor
Title::~Title()
{
	delete eventHandler;
	delete sprite;
	delete pressEnterSprite;
	delete pressEnterTexture;
	delete text;
}

// Comprueba el manejador de eventos
void Title::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 = SECTION_PROG_QUIT;
			break;
		}

		// Comprueba las teclas que se han pulsado
		if ((eventHandler->type == SDL_KEYDOWN && eventHandler->key.repeat == 0) || (eventHandler->type == SDL_JOYBUTTONDOWN))
		{
			if (eventHandler->type == SDL_JOYBUTTONDOWN)
			{
				section->name = SECTION_PROG_GAME;
				section->subsection = 0;
			}

			switch (eventHandler->key.keysym.scancode)
			{
			case SDL_SCANCODE_ESCAPE:
				section->name = SECTION_PROG_QUIT;
				break;

			case SDL_SCANCODE_RETURN:
				section->name = SECTION_PROG_GAME;
				section->subsection = 0;
				break;

			case SDL_SCANCODE_B:
				screen->switchBorder();
				resource->reLoadTextures();
				break;

			case SDL_SCANCODE_F:
				screen->switchVideoMode();
				resource->reLoadTextures();
				break;

			case SDL_SCANCODE_F1:
				screen->setWindowSize(1);
				resource->reLoadTextures();
				break;

			case SDL_SCANCODE_F2:
				screen->setWindowSize(2);
				resource->reLoadTextures();
				break;

			case SDL_SCANCODE_F3:
				screen->setWindowSize(3);
				resource->reLoadTextures();
				break;

			case SDL_SCANCODE_F4:
				screen->setWindowSize(4);
				resource->reLoadTextures();
				break;

			case SDL_SCANCODE_F5:
				switchPalette();
				break;

#ifdef DEBUG
			case SDL_SCANCODE_F6:
				screen->showNotification("MAMA MIRA! SIN MANOS!");
				break;
#endif

			default:
				break;
			}
		}
	}
}

// Actualiza la marquesina
void Title::updateMarquee()
{
	for (int i = 0; i < (int)letters.size(); ++i)
	{
		if (letters[i].enabled)
		{
			letters[i].x -= marqueeSpeed;
			if (letters[i].x < -10)
			{
				letters[i].enabled = false;
			}
		}
		else
		{
			if (i > 0 && letters[i - 1].x < 256 && letters[i - 1].enabled)
			{
				letters[i].enabled = true;
				letters[i].x = letters[i - 1].x + text->lenght(letters[i - 1].letter) + 1;
			}
		}
	}
}

// Dibuja la marquesina
void Title::renderMarquee()
{
	for (auto l : letters)
	{
		if (l.enabled)
		{
			text->writeColored(l.x, 184, l.letter, stringToColor(options->palette, "white"));
		}
	}
}

// Actualiza las variables
void Title::update()
{
	// Comprueba que la diferencia de ticks sea mayor a la velocidad del juego
	if (SDL_GetTicks() - ticks > ticksSpeed)
	{
		// Actualiza el contador de ticks
		ticks = SDL_GetTicks();

		// Comprueba el manejador de eventos
		checkEventHandler();

		// Incrementa el contador
		counter++;

		// Actualiza la marquesina
		updateMarquee();

		// Actualiza las notificaciones
		screen->updateNotifier();

		// Comprueba si ha terminado la marquesina y acaba con el titulo
		if (letters[letters.size() - 1].x < -10)
		{
			section->name = SECTION_PROG_CREDITS;
			section->subsection = 0;
		}
	}
}

// Dibuja en pantalla
void Title::render()
{
	// Prepara para empezar a dibujar en la textura de juego
	screen->start();

	// Dibuja el fondo del titulo
	sprite->render();

	// Dibuja el texto de PRESS ENTER TO PLAY
	if (counter % 80 < 60)
	{
		pressEnterSprite->render();
	}

	// Dibuja la marquesina
	renderMarquee();

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

// Bucle para el logo del juego
void Title::run()
{
	while (section->name == SECTION_PROG_TITLE)
	{
		update();
		render();
	}
}

// Recarga las texturas
void Title::reLoadTextures()
{
	// Carga la textura adecuada
	if (options->palette == p_zxspectrum)
	{
		// texture->loadFromFile(asset->get("loading_screen_color.png"), renderer);
		texture = resource->getTexture("loading_screen_color.png");
	}
	else if (options->palette == p_zxarne)
	{
		// texture->loadFromFile(asset->get("loading_screen_color_zxarne.png"), renderer);
		texture = resource->getTexture("loading_screen_color_zxarne.png");
	}

	texture->reLoad();
}

// Cambia la paleta
void Title::switchPalette()
{
	if (options->palette == p_zxspectrum)
	{
		options->palette = p_zxarne;
		sprite->setTexture(resource->getTexture("loading_screen_color_zxarne.png"));
	}
	else
	{
		options->palette = p_zxspectrum;
		sprite->setTexture(resource->getTexture("loading_screen_color.png"));
	}

	// Cambia el color del borde
	screen->setBorderColor(stringToColor(options->palette, "bright_blue"));
}