#pragma once

#include <string> // para string, basic_string
#include <vector> // para vector
#include "utils.h"

enum class AssetType : int
{
	BITMAP,
	MUSIC,
	SOUND,
	FONT,
	LANG,
	DATA,
	ANIMATION,
	PALETTE,
	ITEM,
	MAX_ASSET_TYPE,
};

// Clase Asset
class Asset
{
private:
	// [SINGLETON] Objeto asset privado para Don Melitón
	static Asset *asset_;

	// Estructura para definir un item
	struct AssetItem
	{
		std::string file; // Ruta del fichero desde la raíz del directorio
		AssetType type;	  // Indica el tipo de recurso
		bool required;	  // Indica si es un fichero que debe de existir

		// Constructor
		AssetItem(const std::string &filePath, AssetType assetType, bool isRequired)
			: file(filePath), type(assetType), required(isRequired) {}
	};

	// Variables
	int longest_name_ = 0;			   // Contiene la longitud del nombre de fichero mas largo
	std::vector<AssetItem> file_list_; // Listado con todas las rutas a los ficheros
	std::string executable_path_;	   // Ruta al ejecutable

	// Comprueba que existe un fichero
	bool checkFile(const std::string &path) const;

	// Devuelve el nombre del tipo de recurso
	std::string getTypeName(AssetType type) const;

	// Constructor
	explicit Asset(const std::string &executable_path)
		: executable_path_(getPath(executable_path)) {}

	// Destructor
	~Asset() = default;

public:
	// [SINGLETON] Crearemos el objeto screen con esta función estática
	static void init(const std::string &executable_path);

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

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

	// Añade un elemento a la lista
	void add(const std::string &file, AssetType type, bool required = true, bool absolute = false);

	// Devuelve la ruta completa a un fichero a partir de una cadena
	std::string get(const std::string &text) const;

	// Comprueba que existen todos los elementos
	bool check() const;

	// Devuelve la lista de recursos de un tipo
	std::vector<std::string> getListByType(AssetType type) const;
};