#include <ItemContainer/ItemContainer.hpp>

ItemContainer& ItemContainer::withStackUpdatedCallback(const StackUpdatedCallback &callback)
{
    onStackUpdated = callback;
    return *this;
}

ItemStore& ItemContainer::store(const std::string &id)
{
    return stores.at(id);
}

ItemContainer::iterator ItemContainer::begin()
{
    return stores.begin();
}

ItemContainer::iterator ItemContainer::end()
{
    return stores.end();
}

ItemContainer::const_iterator ItemContainer::cbegin() const
{
    return stores.cbegin();
}

ItemContainer::const_iterator ItemContainer::cend() const
{
    return stores.cend();
}

ItemContainer::const_iterator ItemContainer::begin() const
{
    return stores.begin();
}

ItemContainer::const_iterator ItemContainer::end() const
{
    return stores.end();
}

void SerialCodec<ItemContainer>::encode(std::vector<uint8_t> &outBytes, const ItemContainer &obj)
{
    serializeInto(outBytes, obj.stores);
}

size_t SerialCodec<ItemContainer>::decode(const uint8_t *data, size_t size, ItemContainer &obj)
{
    uint32_t count;
    size_t consumed = deserialize(data, size, count);

    while (count--)
    {
        std::string id;
        consumed += deserialize(data + consumed, size - consumed, id);

        auto it = obj.stores.find(id);
        if (it != obj.stores.end())
        {
            consumed += deserialize(data + consumed, size - consumed, it->second);
        }
        else
        {
            std::vector<ItemStack> discardedStacks;
            consumed += deserialize(data + consumed, size - consumed, discardedStacks);
        }
    }

    return consumed;
}