#include <memory>

#include <WorldComponent/Wiring/FluidWiring/FluidWiring.hpp>
#include <World/LocalWorld/LocalWorld.hpp>
#include <Block/Block.hpp>

void FluidWiring::updateFrom(LocalWorld &world, std::shared_ptr<WorldGridNode> node, std::vector<Port> &ports)
{
    linksCreatedYet = true;

    links.clear();
    links.reserve(ports.size());

    for (size_t i=0; i<ports.size(); i++)
    {
        links.push_back(std::make_shared<FluidLink>(world, node, ports, i));
    }
}

size_t FluidWiring::compIndex;
std::string FluidWiring::compName = "main:fluidWiring";

FluidWiring::FluidWiring(const uint8_t *data, size_t size) : Wiring(data, size) {}

std::shared_ptr<FluidLink> FluidWiring::getLink(
    LocalWorld &world,
    glm::ivec3 pos, 
    Side side
)
{
    if (!linksCreatedYet)
    {
        updateFrom(world, world.getRootNode(), globalPorts);
    }

    size_t i;
    for (i=0; i<links.size(); i++)
    {
        std::shared_ptr<FluidLink> &link = links[i];
        if (link->pos == pos && link->side == side)
        {
            return link;
        }
    }

    return FluidLink::dummyLink;
}

void FluidWiring::onMachinePortsChanged(LocalWorld &world, std::shared_ptr<WorldGridNode> node, std::vector<Port> &ports)
{
    updateFrom(world, node, ports);
}

bool FluidWiring::isWalkableBlock(LocalWorld &world, int id)
{
    return world.getBlockById(id).name == "main:fluidPipe";
}

std::string FluidWiring::getDumpDirName()
{
    return "FluidWiring";
}