#ifndef MCRATE_HPP_
#define MCRATE_HPP_

#include <vector>

#include <Machine/Machine.hpp>
#include <ItemStack/ItemStack.hpp>
#include <Item/IInventory.hpp>
#include <Machine/IBeltMachine.hpp>

/**
 * @brief The "crate" machine, stores items.
 */
class MCrate :
    public Machine,
    public IInventory,
    public IBeltMachine
{
private:
    enum class ExtractionMode : uint32_t
    {
        FirstItem = 0,
        AlternatingSlots = 1,
    };

    std::vector<ItemStack> stacks;
    uint32_t nextExtractionSlot = 0;

public:
    MCrate(LocalWorld &world, glm::ivec3 pos);

    virtual void serializeState(std::vector<uint8_t> &outBytes) override;
    virtual void deserializeState(const uint8_t *data, size_t size) override;
    virtual int getNumSlots() override;
    virtual ItemStack getStackInSlot(int slot) override;
    virtual void setStackInSlot(int slot, ItemStack stack) override;
    virtual bool isAllowedStackInSlot(int slot, ItemStack stack) override;
    virtual void onItemStackEntering(Side side, ItemStack &stack) override;
    virtual ItemStack tryExtractItem(Side side, ItemFilter &filter, uint32_t modeCode) override;
    virtual bool canConnectExtractor(Side side) override;
    virtual void getExtractionModes(Side side, std::vector<ExtractionModeSpec> &specs) override;
};

#endif