#include <Block/SpriteBlock/BlockPlacer/BlockPlacer.hpp>
#include <Block/SpriteBlock/SpriteBlock.hpp>
#include <BoundingBox/BoundingBox.hpp>
#include <Side/Side.hpp>
#include <Utilities/Utilities.hpp>
#include <Entity/PhysicsEntity/CameraEntity/Player/Player.hpp>
#include <World/LocalWorld/LocalWorld.hpp>
#include <memory>

std::vector<BlockPlacer::Sprite> BlockPlacer::makeSprites()
{
    std::vector<Sprite> sprites;

    for (int i = 0; i < 4; i++)
    {
        Sprite sprite{
            {"blockPlacer/side", "blockPlacer/side", "blockPlacer/side", "blockPlacer/side", "blockPlacer/bottom", "blockPlacer/top"},
            {
                BoundingBox<int>{0, 0, 0, 8, 8, 8},
            },
            formatString("placing$+", Side(i).name()),
        };

        sprite.texturesOnSides[i] = "blockPlacer/placing";

        sprites.push_back(sprite);
    }

    return sprites;
}

BlockPlacer::BlockPlacer(std::string name) : SpriteBlock(
    name,
    "Block Placer",
    60.0f,
    "blockPlacer/icon",
    makeSprites()
)
{
    withMetalSounds();
}

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

void BlockPlacer::onInteract(LocalWorld &world, Player &player, glm::ivec3 pos, Side side, const RGBABytes &collisionKey)
{
    if (!player.isHoldingScrewdriver())
    {
        return;
    }

    world.setBlockMeta(pos, (*world.getBlockMeta(pos) + 1) & 3, true);
}

bool BlockPlacer::canPlace(LocalWorld &world, IWorldActor &actor, glm::ivec3 pos, Side side, uint8_t &meta)
{
    meta = actor.getSideFacing2D().asNumber();
    return true;
}
