#include <memory>

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

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

size_t DataWiring::compIndex;
std::string DataWiring::compName = "main:dataWiring";

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

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

    return DataLink::dummyLink;
}

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

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

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