#pragma once

#include <SDL2/SDL_rect.h>	 // Para SDL_Rect
#include <SDL2/SDL_render.h> // Para SDL_Renderer
#include <string>			 // Para basic_string, string
#include <vector>			 // Para vector
#include "utils.h"			 // Para color_t
class Sprite;
class Text;
class Texture;
struct JA_Sound_t;

class Notifier
{
private:
	// [SINGLETON] Objeto notifier
	static Notifier *notifier_;

	enum notification_state_e
	{
		ns_rising,
		ns_stay,
		ns_vanishing,
		ns_finished
	};

	enum notification_position_e
	{
		upperLeft,
		upperCenter,
		upperRight,
		middleLeft,
		middleRight,
		bottomLeft,
		bottomCenter,
		bottomRight
	};

	struct notification_t
	{
		std::string text1;
		std::string text2;
		int counter;
		notification_state_e state;
		notification_position_e position;
		Texture *texture;
		Sprite *sprite;
		SDL_Rect rect;
		int y;
		int travelDist;
	};

	// Objetos y punteros
	SDL_Renderer *renderer_; // El renderizador de la ventana
	Texture *text_texture_;	 // Textura para la fuente de las notificaciones
	Texture *icon_texture_;	 // Textura para los iconos de las notificaciones
	Text *text_;			 // Objeto para dibujar texto

	// Variables
	Color bg_color_;							// Color de fondo de las notificaciones
	int wait_time_;								// Tiempo que se ve la notificación
	std::vector<notification_t> notifications_; // La lista de notificaciones activas
	JA_Sound_t *sound_;							// Sonido a reproducir cuando suena la notificación

	// Elimina las notificaciones finalizadas
	void clearFinishedNotifications();

	// Constructor
	Notifier(std::string iconFile, std::string bitmapFile, std::string textFile, std::string soundFile);

	// Destructor
	~Notifier();

public:
	// [SINGLETON] Crearemos el objeto con esta función estática
	static void init(std::string iconFile, std::string bitmapFile, std::string textFile, std::string soundFile);

	// [SINGLETON] Destruiremos el objeto con esta función estática
	static void destroy();

	// [SINGLETON] Con este método obtenemos el objeto y podemos trabajar con él
	static Notifier *get();

	// Dibuja las notificaciones por pantalla
	void render();

	// Actualiza el estado de las notificaiones
	void update();

	// Muestra una notificación de texto por pantalla;
	void show(std::string text1 = "", std::string text2 = "", int icon = -1);

	// Getters
	bool active() const { return !notifications_.empty(); }
};
