#ifndef ITEM_REGISTRY_HPP_
#define ITEM_REGISTRY_HPP_

#include <unordered_map>

#include <Item/Item.hpp>

/**
 * @brief Represents the item registry.
 * 
 * There must only be one instance: the global `itemRegistry`.
 */
class ItemRegistry
{
private:
    std::unordered_map<std::string, Item*> items;

    template<typename TItem, typename... TArgs>
    TItem& registerItem(std::string name, TArgs&& ...args)
    {
        TItem *item = new TItem(name, args...);
        items[name] = item;
        return *item;
    }

public:
    ~ItemRegistry();

    /**
     * @brief This is called from the preloader; register all items.
     */
    void registerAllItems();

    /**
     * @brief Get a pointer to an `Item` implementation by name.
     * 
     * @param name The name.
     * @return The pointer on success, `nullptr` if the item does not exist.
     */
    Item* getItemByName(std::string name);

    /**
     * @brief Get stacks for every item (including blocks).
     * 
     * @param stacks Stacks will be added here.
     */
    void getAllStacks(std::vector<ItemStack> &stacks);

    int getTotalItems();
};

/**
 * @brief The singleton item registry instance.
 */
extern ItemRegistry itemRegistry;

#endif