#pragma once

#include <SDL3/SDL_rect.h>	 // Para SDL_FPoint, SDL_FRect
#include <SDL3/SDL_render.h> // Para SDL_Texture, SDL_Renderer
#include <SDL3/SDL_stdinc.h> // Para Uint32
#include <memory>			 // Para unique_ptr, shared_ptr
#include <vector>			 // Para vector

class Fade;
class Sprite;
class Text;
class Texture;
class TiledBG;

/*
	Esta clase gestiona un estado del programa. Se encarga de poner en pantalla
	un texto explicativo para entender cómo se juega.

	Además muestra algunos items y explica para qué sirven.

	Utiliza dos texturas de apoyo, una con el texto ya escrito y otra donde se combina
	tanto el texto de la primera textura como los sprites de los items.

	Finalmente, una ventana recorre la textura para dar el efecto de que todo se desplaza
	por la pantalla sobre el mosaico de fondo (gestionado por el correspondiente objeto).
*/

// Estructura para almacenar información de línea animada
struct Line
{
	int y;			  // Coordenada Y de la línea
	float x;		  // Coordenada X inicial (usamos float para mayor precisión en el suavizado)
	int direction;	  // Dirección de movimiento: -1 para izquierda, 1 para derecha
	Uint32 startTime; // Tiempo de inicio del movimiento

	// Constructor de Line
	Line(int y, float x, int direction)
		: y(y), x(x), direction(direction), startTime(0) {}
};

// Clase Instructions
class Instructions
{
public:
	// Constructor
	Instructions();

	// Destructor
	~Instructions();

	// Bucle principal
	void run();

private:
	// --- Objetos y punteros ---
	SDL_Renderer *renderer_;  // El renderizador de la ventana
	SDL_Texture *texture_;	  // Textura fija con el texto
	SDL_Texture *backbuffer_; // Textura para usar como backbuffer

	std::vector<std::shared_ptr<Texture>> item_textures_; // Vector con las texturas de los items
	std::vector<std::unique_ptr<Sprite>> sprites_;		  // Vector con los sprites de los items
	std::shared_ptr<Text> text_;						  // Objeto para escribir texto
	std::unique_ptr<TiledBG> tiled_bg_;					  // Objeto para dibujar el mosaico animado de fondo
	std::unique_ptr<Fade> fade_;						  // Objeto para renderizar fades

	// --- Variables ---
	int counter_ = 0;					 // Contador para manejar el progreso en la pantalla de instrucciones
	Uint64 ticks_ = 0;					 // Contador de ticks para ajustar la velocidad del programa
	SDL_FRect view_;					 // Vista del backbuffer que se va a mostrar por pantalla
	SDL_FPoint sprite_pos_ = {0, 0};	 // Posición del primer sprite en la lista
	float item_space_ = 2.0;			 // Espacio entre los items en pantalla
	std::vector<Line> lines_;			 // Vector que contiene las líneas animadas en la pantalla
	bool all_lines_off_screen_ = false;	 // Indica si todas las líneas han salido de la pantalla
	Uint32 start_delay_time_ = 0;		 // Tiempo de inicio del retraso para mover las líneas
	bool start_delay_triggered_ = false; // Bandera para determinar si el retraso ha comenzado

	// --- Métodos internos ---
	void update();																					// Actualiza las variables
	void render();																					// Pinta en pantalla
	void checkEvents();																				// Comprueba los eventos
	void checkInput();																				// Comprueba las entradas
	void fillTexture();																				// Rellena la textura de texto
	void fillBackbuffer();																			// Rellena el backbuffer
	void iniSprites();																				// Inicializa los sprites de los items
	void updateSprites();																			// Actualiza los sprites
	std::vector<Line> initializeLines(int height);													// Inicializa las líneas animadas
	bool moveLines(std::vector<Line> &lines, int width, float duration, Uint32 startDelay);			// Mueve las líneas
	void renderLines(SDL_Renderer *renderer, SDL_Texture *texture, const std::vector<Line> &lines); // Renderiza las líneas
	void updateBackbuffer();																		// Gestiona la textura con los gráficos
};