#include <Block/SpriteBlock/MultiBlock/ChemicalReactor/ChemicalReactor.hpp>
#include <Controller/InventoryController/ChemicalReactorController/ChemicalReactorController.hpp>
#include <Entity/PhysicsEntity/CameraEntity/Player/Player.hpp>
#include <World/LocalWorld/LocalWorld.hpp>

ChemicalReactor::ChemicalReactor(std::string name) : MultiBlock(name, "Chemical reactor", {"cold", "hot"})
{
    int u, v, z;
    
    // Add the roof and floor.
    for (u=-2; u<=2; u++)
    {
        for (v=0; v<=4; v++)
        {
            structure.add(u, v, -2, "main:tinCasing");
            structure.add(u, v, 2, "main:tinCasing");
        }
    }

    // Add the walls.
    for (z=-1; z<=1; z++)
    {
        // Create the left-right walls.
        for (v=0; v<=4; v++)
        {
            structure.add(-2, v, z, "main:tinCasing");
            structure.add(2, v, z, "main:tinCasing");
        }

        // Create the front and back walls; don't include the already-added left and right sections.
        for (u=-1; u<=1; u++)
        {
            structure.add(u, 4, z, "main:tinCasing");

            // Don't add the interface block itself.
            if (u != 0 || z != 0)
            {
                structure.add(u, 0, z, "main:tinCasing");
            }
        }
    }

    withMetalSounds();
}

void ChemicalReactor::getHarvestedStacks(LocalWorld &world, glm::ivec3 pos, std::vector<ItemStack> &stacks)
{
    MultiBlock::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);
            }
        }
    }
}

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

glm::vec3 ChemicalReactor::getLightColor(uint8_t meta)
{
    if (meta & (1 << 2))
    {
        return glm::vec3(1.0f, 0.1f, 0.1f);
    }
    else
    {
        return glm::vec3(0.0f);
    }
}

glm::ivec3 ChemicalReactor::getLightOffset(uint8_t meta)
{
    return glm::ivec3(4) - 4 * Structure::getIntoVector(meta & 3);
}

Sound& ChemicalReactor::getBackgroundSound(uint8_t meta)
{
    if (meta & (1 << 2))
    {
        return Sound::chemicalReactor;
    }

    return Sound::NONE;
}