#include "logo.h"
#include <SDL3/SDL_events.h> // Para SDL_PollEvent, SDL_Event
#include <SDL3/SDL_timer.h>	 // Para SDL_GetTicks
#include <utility>			 // Para move
#include "global_events.h"	 // Para check
#include "global_inputs.h"	 // Para check, update
#include "audio.h"			 // Para JA_FadeOutMusic, JA_PlaySound, JA_StopC...
#include "param.h"			 // Para Param, ParamGame, param
#include "resource.h"		 // Para Resource
#include "screen.h"			 // Para Screen
#include "section.h"		 // Para Name, name
#include "sprite.h"			 // Para Sprite
#include "texture.h"		 // Para Texture
#include "utils.h"			 // Para Color, Zone

// Constructor
Logo::Logo()
	: since_texture_(Resource::get()->getTexture("logo_since_1998.png")),
	  since_sprite_(std::make_unique<Sprite>(since_texture_)),
	  jail_texture_(Resource::get()->getTexture("logo_jailgames.png"))
{

	// Inicializa variables
	section::name = section::Name::LOGO;
	dest_.x = param.game.game_area.center_x - jail_texture_->getWidth() / 2;
	dest_.y = param.game.game_area.center_y - jail_texture_->getHeight() / 2;
	since_sprite_->setPosition(SDL_FRect{
		static_cast<float>((param.game.width - since_texture_->getWidth()) / 2),
		static_cast<float>(83 + jail_texture_->getHeight() + 5),
		static_cast<float>(since_texture_->getWidth()),
		static_cast<float>(since_texture_->getHeight())});
	since_sprite_->setY(dest_.y + jail_texture_->getHeight() + 5);
	since_sprite_->setSpriteClip(0, 0, since_texture_->getWidth(), since_texture_->getHeight());
	since_texture_->setColor(0x00, 0x00, 0x00);

	// Crea los sprites de cada linea
	for (int i = 0; i < jail_texture_->getHeight(); ++i)
	{
		auto temp = std::make_unique<Sprite>(jail_texture_, 0, i, jail_texture_->getWidth(), 1);
		temp->setSpriteClip(0, i, jail_texture_->getWidth(), 1);
		const int POS_X = (i % 2 == 0) ? param.game.width + (i * 3) : -jail_texture_->getWidth() - (i * 3);
		temp->setX(POS_X);
		temp->setY(dest_.y + i);
		jail_sprite_.push_back(std::move(temp));
	}

	// Inicializa el vector de colores
	color_.push_back(Color(0x00, 0x00, 0x00)); // Black
	color_.push_back(Color(0x00, 0x00, 0xd8)); // Blue
	color_.push_back(Color(0xd8, 0x00, 0x00)); // Red
	color_.push_back(Color(0xd8, 0x00, 0xd8)); // Magenta
	color_.push_back(Color(0x00, 0xd8, 0x00)); // Green
	color_.push_back(Color(0x00, 0xd8, 0xd8)); // Cyan
	color_.push_back(Color(0xd8, 0xd8, 0x00)); // Yellow
	color_.push_back(Color(0xFF, 0xFF, 0xFF)); // Bright white
}

// Destructor
Logo::~Logo()
{
	jail_texture_->setColor(255, 255, 255);
	since_texture_->setColor(255, 255, 255);
	Audio::get().stopAllSounds();
}

// Comprueba el manejador de eventos
void Logo::checkEvents()
{
	SDL_Event event;
	while (SDL_PollEvent(&event))
	{
		globalEvents::check(event);
	}
}

// Comprueba las entradas
void Logo::checkInput()
{
	globalInputs::check();
}

// Gestiona el logo de JAILGAMES
void Logo::updateJAILGAMES()
{
	if (counter_ == 30)
	{
		Audio::get().playSound("logo.wav");
	}

	if (counter_ > 30)
	{
		for (int i = 0; i < (int)jail_sprite_.size(); ++i)
		{
			if (jail_sprite_[i]->getX() != dest_.x)
			{
				if (i % 2 == 0)
				{
					jail_sprite_[i]->incX(-SPEED);
					if (jail_sprite_[i]->getX() < dest_.x)
					{
						jail_sprite_[i]->setX(dest_.x);
					}
				}
				else
				{
					jail_sprite_[i]->incX(SPEED);
					if (jail_sprite_[i]->getX() > dest_.x)
					{
						jail_sprite_[i]->setX(dest_.x);
					}
				}
			}
		}
	}

	// Comprueba si ha terminado el logo
	if (counter_ == END_LOGO_COUNTER_MARK + POST_LOGO_DURATION)
	{
		section::name = section::Name::INTRO;
	}
}

// Gestiona el color de las texturas
void Logo::updateTextureColors()
{
	constexpr int inc = 4;

	// Manejo de 'sinceTexture'
	for (int i = 0; i <= 7; ++i)
	{
		if (counter_ == SHOW_SINCE_SPRITE_COUNTER_MARK + inc * i)
		{
			since_texture_->setColor(color_[i].r, color_[i].g, color_[i].b);
		}
	}

	// Manejo de 'jailTexture' y 'sinceTexture' en el fade
	for (int i = 0; i <= 6; ++i)
	{
		if (counter_ == INIT_FADE_COUNTER_MARK + inc * i)
		{
			jail_texture_->setColor(color_[6 - i].r, color_[6 - i].g, color_[6 - i].b);
			since_texture_->setColor(color_[6 - i].r, color_[6 - i].g, color_[6 - i].b);
		}
	}
}

// Actualiza las variables
void Logo::update()
{
	if (SDL_GetTicks() - ticks_ > param.game.speed)
	{
		// Actualiza el contador de ticks
		ticks_ = SDL_GetTicks();

		// Actualiza el objeto screen
		Screen::get()->update();

		// Comprueba las entradas
		checkInput();

		updateJAILGAMES();
		updateTextureColors();

		// Gestiona el contador
		++counter_;
	}
}

// Dibuja en pantalla
void Logo::render()
{
	Screen::get()->start();
	Screen::get()->clean();

	renderJAILGAMES();

	Screen::get()->render();
}

// Bucle para el logo del juego
void Logo::run()
{
	Audio::get().fadeOutMusic(300);
	while (section::name == section::Name::LOGO)
	{
		checkInput();
		update();
		checkEvents(); // Tiene que ir antes del render
		render();
	}
}

// Renderiza el logo de JAILGAMES
void Logo::renderJAILGAMES()
{
	// Dibuja los sprites
	for (auto &sprite : jail_sprite_)
	{
		sprite->render();
	}

	if (counter_ >= SHOW_SINCE_SPRITE_COUNTER_MARK)
	{
		since_sprite_->render();
	}
}