#pragma once

#include <SDL2/SDL_render.h> // Para SDL_Renderer
#include <string>			 // Para string, basic_string
#include <vector>			 // Para vector
class Asset;
class Texture;
struct animatedSprite_t;
struct Options;
struct room_t;
struct textFile_t;

struct res_texture_t
{
	std::string name; // Nombre de la textura
	Texture *texture; // La textura
};

struct res_animation_t
{
	std::string name;			 // Nombre de la textura
	animatedSprite_t *animation; // La animación
};

struct res_textOffset_t
{
	std::string name;	  // Nombre del offset
	textFile_t *textFile; // Los offsets de la fuente
};

struct res_tileMap_t
{
	std::string name;		   // Nombre del mapa de tiles
	std::vector<int> *tileMap; // Vector con los indices del mapa de tiles
};

struct res_room_t
{
	std::string name; // Nombre de la habitación
	room_t *room;	  // Vector con las habitaciones
};

// Clase Resource. Almacena recursos de disco en memoria
class Resource
{
private:
	// [SINGLETON] Objeto privado
	static Resource *resource_;

	// Variables
	std::vector<res_texture_t> textures_;
	std::vector<res_animation_t> animations_;
	std::vector<res_textOffset_t> offsets_;
	std::vector<res_tileMap_t> tile_maps_;
	std::vector<res_room_t> rooms_;

	// Constructor
	Resource() = default;

	// Destructor
	~Resource() = default;

public:
	// [SINGLETON] Crearemos el objeto con esta función estática
	static void init();

	// [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 Resource *get();

	// Carga las texturas de una lista
	void loadTextures(std::vector<std::string> list);

	// Vuelve a cargar las texturas
	void reLoadTextures();

	// Carga las animaciones desde una lista
	void loadAnimations(std::vector<std::string> list);

	// Vuelve a cargar las animaciones
	void reLoadAnimations();

	// Carga los offsets desde una lista
	void loadOffsets(std::vector<std::string> list);

	// Vuelve a cargar los offsets
	void reLoadOffsets();

	// Carga los mapas de tiles desde una lista
	void loadTileMaps(std::vector<std::string> list);

	// Vuelve a cargar los mapas de tiles
	void reLoadTileMaps();

	// Carga las habitaciones desde una lista
	void loadRooms(std::vector<std::string> list);

	// Vuelve a cargar las habitaciones
	void reLoadRooms();

	// Vuelve a cargar todos los recursos
	void reLoad();

	// Libera las texturas
	void freeTextures();

	// Libera las animaciones
	void freeAnimations();

	// Libera los offsets
	void freeOffsets();

	// Libera los mapas de tiles
	void freeTileMaps();

	// Libera las habitaciones
	void freeRooms();

	// Libera todos los recursos
	void free();

	// Obtiene una textura
	Texture *getTexture(std::string name);

	// Obtiene una animación
	animatedSprite_t *getAnimation(std::string name);

	// Obtiene un offset
	textFile_t *getOffset(std::string name);

	// Obtiene un mapa de tiles
	std::vector<int> *getTileMap(std::string name);

	// Obtiene una habitacion
	room_t *getRoom(std::string name);

	// Obtiene todas las habitaciones
	std::vector<res_room_t> *getAllRooms();
};