#include <Block/SpriteBlock/Barrel/Barrel.hpp>
#include <Entity/PhysicsEntity/CameraEntity/Player/Player.hpp>
#include <Controller/InventoryController/BarrelController/BarrelController.hpp>
#include <World/LocalWorld/LocalWorld.hpp>

std::string Barrel::getTexName(BarrelTier tier)
{
    switch (tier)
    {
    case BarrelTier::Wooden: return "wooden";
    case BarrelTier::Steel: return "steel";
    default: return "lead";
    }
}

Barrel::Barrel(std::string name, std::string displayName, float hardness, BarrelTier tier) :
    SpriteBlock(
        name,
        displayName,
        hardness,
        formatString("barrel/$+/side", getTexName(tier)),
        {
            {
                {
                    formatString("barrel/$+/side", getTexName(tier)),
                    formatString("barrel/$+/side", getTexName(tier)),
                    formatString("barrel/$+/side", getTexName(tier)),
                    formatString("barrel/$+/side", getTexName(tier)),
                    formatString("barrel/$+/bottom", getTexName(tier)),
                    formatString("barrel/$+/top", getTexName(tier)),
                },
                {
                    {1, 1, 0, 7, 7, 8}
                },
                "default"
            }
        }
    ),
    tier(tier)
{
    if (tier == BarrelTier::Wooden)
    {
        withWoodSounds();
    }
    else
    {
        withMetalSounds();
    }
}

bool Barrel::canManuallyDig()
{
    return true;
}

void Barrel::onInteract(LocalWorld &world, Player &player, glm::ivec3 pos, Side side, const RGBABytes &collisionKey)
{
    player.connectController<BarrelController>(
        "main:BarrelController",
        world.getMachine(pos)
    );
}

void Barrel::getHarvestedStacks(LocalWorld &world, glm::ivec3 pos, std::vector<ItemStack> &stacks)
{
    SpriteBlock::getHarvestedStacks(world, pos, stacks);
    
    std::shared_ptr<IInventory> inv = std::dynamic_pointer_cast<IInventory>(world.getMachine(pos));
    if (inv != nullptr)
    {
        int i;
        for (i=0; i<inv->getNumSlots(); i++)
        {
            ItemStack stack = inv->getStackInSlot(i);
            if (!stack.isEmpty())
            {
                stacks.push_back(stack);
            }
        }
    }
}