#pragma once

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

class LoadingScreen
{
private:
	// Objetos y punteros
	SDL_Renderer *renderer;			// El renderizador de la ventana
	Screen *screen;					// Objeto encargado de dibujar en pantalla
	Resource *resource;				// Objeto con los recursos
	Asset *asset;					// Objeto con los ficheros de recursos
	Input *input;					// Objeto pata gestionar la entrada
	Texture *loadingScreenTexture1; // Textura con la pantalla de carga en blanco y negro
	Texture *loadingScreenTexture2; // Textura con la pantalla de carga en color
	SDL_Event *eventHandler;		// Manejador de eventos
	Sprite *sprite1;				// Sprite para manejar la textura loadingScreenTexture1
	Sprite *sprite2;				// Sprite para manejar la textura loadingScreenTexture2
	options_t *options;				// Puntero a las opciones del juego
	section_t *section;				// Estado del bucle principal para saber si continua o se sale

	// Variables
	int preCounter;			   // Contador previo para realizar una pausa inicial
	int counter;			   // Contador
	Uint32 ticks;			   // Contador de ticks para ajustar la velocidad del programa
	Uint32 ticksSpeed;		   // Velocidad a la que se repiten los bucles del programa
	int loadCounter;		   // Contador para controlar las cargas
	bool loadingFirstPart;	   // Para saber en que parte de la carga se encuentra
	JA_Music_t *loadingSound1; // Sonidos para imitar la carga tipo spectrum
	JA_Music_t *loadingSound2; // Sonidos para imitar la carga tipo spectrum
	JA_Music_t *loadingSound3; // Sonidos para imitar la carga tipo spectrum
	int lineIndex[192];		   // El orden en el que se procesan las 192 lineas de la pantalla de carga
	SDL_Rect loadRect;		   // 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();

	// Cambia la paleta
	void switchPalette();

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

public:
	// Constructor
	LoadingScreen(SDL_Renderer *renderer, Screen *screen, Resource *resource, Asset *asset, Input *input, options_t *options, section_t *section);

	// Destructor
	~LoadingScreen();

	// Bucle principal
	void run();
};