#ifndef MOIL_REFINERY_HPP_
#define MOIL_REFINERY_HPP_

#include <vector>
#include <Machine/Machine.hpp>
#include <ItemStack/ItemStack.hpp>
#include <Item/IInventory.hpp>
#include <Machine/IFluidMachine.hpp>
#include <Machine/IElectricMachine.hpp>

/**
 * @brief The oil refinery machine.
 */
class MOilRefinery :
    public Machine,
    public IInventory,
    public IFluidMachine,
    public IElectricMachine
{
private:
    std::vector<ItemStack> stacks;
    bool isSwitchedOnPriv;

    ItemStack& oilInputSlot();
    ItemStack& petrolOutputSlot();
    ItemStack& rechargeSlot();

    void refine();
    Side getInputSide();
    Side getOutputSide();

public:
    static constexpr int fluidCapacity = 20000;
    static constexpr int energyCapacity = 1000;
    static constexpr int powerUsage = 10;
    static constexpr int petrolPerOil = 20;

    MOilRefinery(LocalWorld &world, glm::ivec3 pos);

    /**
     * @brief Returns true if this oil refinery is switched on.
     */
    bool isSwitchedOn();

    /**
     * @brief Returns the current amount of oil (ml).
     */
    int getOilAmount();

    /**
     * @brief Returns the current amount of petrol (ml).
     */
    int getPetrolAmount();

    /**
     * @brief Returns the current amount of stored energy (J).
     */
    int getStoredEnergy();

    /**
     * @brief Set whether the refinery is on or off.
     */
    void setSwitch(bool on);

    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 update() override;
    virtual bool canConnectFluidPipe(Side side) override;
    virtual int getMaxFluidToAccept(std::optional<Side> side, std::string fluidName) override;
    virtual int getMaxFluidToRelease(std::optional<Side> side, std::string fluidName) override;
    virtual bool canConnectElectricWire(Side side) override;
    virtual void saveMainConfig(MachineConfig &config) override;
    virtual void loadMainConfig(const MachineConfig &config, bool consumed) override;
};

#endif