#include "DeconstructionSystem.h"

#include <vector>

#include "Building.h"
#include "tracing.h"

void startFrontDeconstruction(FactoryState& state, const GameConfig& config,
                              Tick currentTick)
{
    if (state.deconstructionQueue.empty()) { return; }
    DeconstructionEntry& front = state.deconstructionQueue.front();
    if (front.completesAt == 0)
    {
        front.completesAt =
            currentTick + secondsToTicks(config.world.deconstructionTimeSeconds);
    }
}


void DeconstructionSystem::tick(FactoryState& state, Tick currentTick)
{
    TRACE();
    if (state.deconstructionQueue.empty())
    {
        return;
    }

    DeconstructionEntry& front = state.deconstructionQueue.front();

    // Guard: if the front entry's timer was never started, start it now.
    if (front.completesAt == 0)
    {
        startFrontDeconstruction(state, m_config, currentTick);
        return;
    }

    if (currentTick < front.completesAt)
    {
        return;
    }

    // Remove the building from the world and credit its refund (REQ-BLD-DECONSTRUCT).
    // Belt/tunnel/splitter tiles were already unregistered when the building was
    // queued (see deconstruct), so only tile occupancy and the record remain.
    for (std::vector<Building>::iterator it = state.buildings.begin();
         it != state.buildings.end();
         ++it)
    {
        if (it->id != front.id) { continue; }

        const BuildingDef* def = m_config.buildings.findBuildingDef(it->type);
        state.grid.release(it->bodyCells);
        state.buildings.erase(it);
        if (def)
        {
            state.buildingBlocksStock +=
                def->cost * m_config.world.refundPercentage / 100;
        }
        break;
    }

    state.deconstructionQueue.pop_front();

    // Start the next queued deconstruction, if any.
    startFrontDeconstruction(state, m_config, currentTick);
}

