#include <Machine/MElectricLamp/MElectricLamp.hpp>
#include <Serialize/Serialize.hpp>
#include <FuelRuleRegistry/FuelRuleRegistry.hpp>
#include <World/LocalWorld/LocalWorld.hpp>
#include <Block/Block.hpp>
#include <SmeltingRuleRegistry/SmeltingRuleRegistry.hpp>
#include <Block/SpriteBlock/ElectricLamp/ElectricLamp.hpp>
#include <MachineComponent/ElectricComponent/ElectricComponent.hpp>

MElectricLamp::MElectricLamp(LocalWorld &world, glm::ivec3 pos) :
    Machine(world, pos),
    ticksLeft(0)
{
    attach<ElectricComponent>();
}

void MElectricLamp::serializeState(std::vector<uint8_t> &outBytes)
{
    serializeInto(outBytes, ticksLeft);
}

void MElectricLamp::deserializeState(const uint8_t *data, size_t size)
{
    deserialize(data, size, ticksLeft);
}

void MElectricLamp::update()
{
    if (ticksLeft == 0)
    {
        ElectricComponent &electricComp = getComponent<ElectricComponent>();
        for (const Side &side : Side::all)
        {
            electricComp.rechargeFrom(side, 1);
            if (electricComp.tryConsume(1))
            {
                ticksLeft = 20;
                break;
            }
        }
    }

    uint8_t oldMeta = *m_world.getBlockMeta(pos);
    uint8_t newMeta = oldMeta & ~ElectricLamp::metaOn;

    if (ticksLeft != 0)
    {
        newMeta |= ElectricLamp::metaOn;
        ticksLeft--;
    }

    if (newMeta != oldMeta)
    {
        m_world.setBlockMeta(pos, newMeta);
    }
}

bool MElectricLamp::canConnectElectricWire(Side side)
{
    return true;
}