#include <memory>

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

void ElectricWiring::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<ElectricLink>(world, node, ports, i));
    }
}

size_t ElectricWiring::compIndex;
std::string ElectricWiring::compName = "main:electricWiring";

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

std::shared_ptr<ElectricLink> ElectricWiring::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<ElectricLink> &link = links[i];
        if (link->pos == pos && link->side == side)
        {
            return link;
        }
    }

    return ElectricLink::dummyLink;
}

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

bool ElectricWiring::isWalkableBlock(LocalWorld &world, int id)
{
    return world.getBlockById(id).isSuffixed("Wire");
}

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