#pragma once

#include <SDL2/SDL_rect.h>	 // for SDL_Rect
#include <SDL2/SDL_render.h> // for SDL_Renderer, SDL_Texture
#include <SDL2/SDL_stdinc.h> // for Uint8, Uint16
#include <vector>			 // for vector

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

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

// Clase Fade
class Fade
{
private:
	// Objetos y punteros
	SDL_Renderer *renderer;	 // El renderizador de la ventana
	SDL_Texture *backbuffer; // Textura para usar como backbuffer con SDL_TEXTUREACCESS_TARGET

	// Variables
	FadeType type;				  // Tipo de fade a realizar
	FadeMode mode;				  // Modo de fade a realizar
	Uint16 counter;				  // Contador interno
	bool enabled;				  // Indica si el fade está activo
	bool finished;				  // Indica si ha terminado la transición
	Uint8 r, g, b, a;			  // Colores para el fade
	SDL_Rect rect1;				  // Rectangulo usado para crear los efectos de transición
	SDL_Rect rect2;				  // Rectangulo usado para crear los efectos de transición
	int numSquaresWidth;		  // Cantidad total de cuadraditos en horizontal para el FadeType::RANDOM_SQUARE
	int numSquaresHeight;		  // Cantidad total de cuadraditos en vertical para el FadeType::RANDOM_SQUARE
	std::vector<SDL_Rect> square; // Vector con los indices de los cuadrados para el FadeType::RANDOM_SQUARE
	int fadeRandomSquaresDelay;	  // Duración entre cada pintado de cuadrados
	int fadeRandomSquaresMult;	  // Cantidad de cuadrados que se pintaran cada vez
	int postDuration;			  // Duración posterior del fade tras finalizar
	int postCounter;			  // Contador para la duración posterior

	// Inicializa las variables
	void init();

	// Limpia el backbuffer
	void cleanBackbuffer(Uint8 r, Uint8 g, Uint8 b, Uint8 a);

public:
	// Constructor
	Fade(SDL_Renderer *renderer);

	// Destructor
	~Fade();

	// Resetea algunas variables para volver a hacer el fade sin perder ciertos parametros
	void reset();

	// Pinta una transición en pantalla
	void render();

	// Actualiza las variables internas
	void update();

	// Activa el fade
	void activate();

	// Comprueba si ha terminado la transicion
	bool hasEnded() const;

	// Comprueba si está activo
	bool isEnabled() const;

	// Establece el tipo de fade
	void setType(FadeType type);

	// Establece el modo de fade
	void setMode(FadeMode mode);

	// Establece el color del fade
	void setColor(Uint8 r, Uint8 g, Uint8 b);

	// Establece la duración posterior
	void setPost(int value);
};