#pragma once

#include <SDL2/SDL_rect.h>	 // para SDL_Rect
#include <SDL2/SDL_render.h> // para SDL_Renderer, SDL_Texture
#include <SDL2/SDL_stdinc.h> // para Uint8, Uint16
#include <vector>			 // para 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,
};

// 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 num_squares_width_;			// Cantidad total de cuadraditos en horizontal para el FadeType::RANDOM_SQUARE
	int num_squares_height_;		// 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 fade_random_squares_delay_; // Duración entre cada pintado de cuadrados
	int fade_random_squares_mult_;	// Cantidad de cuadrados que se pintaran cada vez
	int post_duration_;				// Duración posterior del fade tras finalizar
	int post_counter_;				// 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();

	// 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);
};