#pragma once

#include <SDL3/SDL_rect.h>
#include <SDL3/SDL_render.h>
#include <SDL3/SDL_stdinc.h>
#include <vector>

// Tipos de fundido
enum class FadeType : Uint8
{
	FULLSCREEN = 0,
	CENTER = 1,
	RANDOM_SQUARE = 2,
	VENETIAN = 3,
};

// Modos de fundido
enum class FadeMode : Uint8
{
	IN = 0,
	OUT = 1,
};

// Estados del objeto
enum class FadeState : Uint8
{
	NOT_ENABLED = 0,
	PRE = 1,
	FADING = 2,
	POST = 3,
	FINISHED = 4,
};

class Fade
{
public:
	// --- Constructores y destructor ---
	Fade();
	~Fade();

	// --- Métodos principales ---
	void reset();	 // Resetea variables para reutilizar el fade
	void render();	 // Dibuja la transición en pantalla
	void update();	 // Actualiza el estado interno
	void activate(); // Activa el fade

	// --- Configuración ---
	void setColor(Uint8 r, Uint8 g, Uint8 b);
	void setType(FadeType type) { type_ = type; }
	void setMode(FadeMode mode) { mode_ = mode; }
	void setPostDuration(int value) { post_duration_ = value; }
	void setPreDuration(int value) { pre_duration_ = value; }

	// --- Getters ---
	int getValue() const { return value_; }
	bool isEnabled() const { return state_ != FadeState::NOT_ENABLED; }
	bool hasEnded() const { return state_ == FadeState::FINISHED; }

private:
	// --- Objetos y punteros ---
	SDL_Renderer *renderer_;  // Renderizador de la ventana
	SDL_Texture *backbuffer_; // Backbuffer para efectos

	// --- Variables de estado ---
	FadeType type_;							   // Tipo de fade
	FadeMode mode_;							   // Modo de fade
	FadeState state_ = FadeState::NOT_ENABLED; // Estado actual
	Uint16 counter_;						   // Contador interno

	// --- Parámetros de color y geometría ---
	Uint8 r_, g_, b_, a_;	  // Color del fade
	SDL_FRect rect1_, rect2_; // Rectángulos para efectos

	// --- Parámetros para RANDOM_SQUARE ---
	int num_squares_width_;			// Cuadrados en horizontal
	int num_squares_height_;		// Cuadrados en vertical
	std::vector<SDL_FRect> square_; // Vector de cuadrados
	int fade_random_squares_delay_; // Delay entre cuadrados
	int fade_random_squares_mult_;	// Cuadrados por paso

	// --- Temporizadores ---
	int post_duration_ = 0, post_counter_ = 0;
	int pre_duration_ = 0, pre_counter_ = 0;

	// --- Valor de progreso ---
	int value_ = 0; // Estado del fade (0-100)

	// --- Métodos internos ---
	void init();											  // Inicializa variables
	void cleanBackbuffer(Uint8 r, Uint8 g, Uint8 b, Uint8 a); // Limpia el backbuffer
	int calculateValue(int min, int max, int current);		  // Calcula el valor del fade
};