#pragma once

#include <SDL2/SDL_events.h> // Para SDL_Event
#include <SDL2/SDL_rect.h>	 // Para SDL_Rect
#include <SDL2/SDL_render.h> // Para SDL_Renderer
#include <SDL2/SDL_stdinc.h> // Para Uint32
class Asset;
class Input;
class Resource;
class Screen;
class Sprite;
class Texture;
struct JA_Music_t;
struct Options;
struct SectionState;

class LoadingScreen
{
private:
	// Objetos y punteros
	Screen *screen_;						// Objeto encargado de dibujar en pantalla
	SDL_Renderer *renderer_;				// El renderizador de la ventana
	Resource *resource_;					// Objeto con los recursos
	Asset *asset_;							// Objeto con los ficheros de recursos
	Input *input_;							// Objeto pata gestionar la entrada
	Texture *mono_loading_screen_texture_;	// Textura con la pantalla de carga en blanco y negro
	Texture *color_loading_screen_texture_; // Textura con la pantalla de carga en color
	Sprite *mono_loading_screen_sprite_;	// Sprite para manejar la textura loadingScreenTexture1
	Sprite *color_loading_screen_sprite_;	// Sprite para manejar la textura loadingScreenTexture2

	// Variables
	int pre_counter_ = 0;				 // Contador previo para realizar una pausa inicial
	int counter_ = 0;					 // Contador
	Uint32 ticks_ = 0;					 // Contador de ticks para ajustar la velocidad del programa
	Uint32 ticks_speed_ = 15;			 // Velocidad a la que se repiten los bucles del programa
	int load_counter_ = 0;				 // Contador para controlar las cargas
	bool loading_first_part_ = true;	 // Para saber en que parte de la carga se encuentra
	JA_Music_t *loading_sound1_;		 // Sonidos para imitar la carga tipo spectrum
	JA_Music_t *loading_sound2_;		 // Sonidos para imitar la carga tipo spectrum
	JA_Music_t *loading_sound3_;		 // Sonidos para imitar la carga tipo spectrum
	int line_index_[192];				 // El orden en el que se procesan las 192 lineas de la pantalla de carga
	SDL_Rect load_rect_ = {0, 0, 51, 1}; // Rectangulo para dibujar la pantalla de carga

	// Actualiza las variables
	void update();

	// Dibuja en pantalla
	void render();

	// Comprueba el manejador de eventos
	void checkEvents();

	// Comprueba las entradas
	void checkInput();

	// Gestiona el contador interno
	void updateCounter();

	// Gestiona el contador de carga
	void updateLoad();

	// Dibuja la pantalla de carga
	void renderLoad();

	// Dibuja el efecto de carga en el borde
	void renderBorder();

	// Reconstruye la pantalla de carga
	void recreateLoadingScreen();

public:
	// Constructor
	LoadingScreen();

	// Destructor
	~LoadingScreen();

	// Bucle principal
	void run();
};