#include "BeltSlot.h"

#include <cstddef>

void advanceBeltSlots(std::vector<BeltItemSlot>& slots, double progressPerTick)
{
    for (std::size_t i = 0; i < slots.size(); ++i)
    {
        slots[i].progress += progressPerTick;

        // Absolute cap: slot i cannot exceed 1.0 - i * 0.25.
        const double absoluteCap = 1.0 - static_cast<double>(i) * 0.25;
        if (slots[i].progress > absoluteCap)
        {
            slots[i].progress = absoluteCap;
        }

        // Gap constraint: must stay 0.25 behind the slot ahead.
        if (i > 0)
        {
            const double gapCap = slots[i - 1].progress - 0.25;
            if (slots[i].progress > gapCap)
            {
                slots[i].progress = (gapCap < 0.0 ? 0.0 : gapCap);
            }
        }
    }
}

QPointF beltSlotWorldPos(QPoint tile, Rotation dir, double progress)
{
    // Map progress [0, 1] along the belt direction to a fractional tile-unit position.
    // Progress 0 = entered from opposite side; 1 = at output edge.
    const double baseX = tile.x() + 0.5;
    const double baseY = tile.y() + 0.5;

    switch (dir)
    {
        case Rotation::North: return {baseX, baseY - (progress - 0.5)};
        case Rotation::East:  return {baseX + (progress - 0.5), baseY};
        case Rotation::South: return {baseX, baseY + (progress - 0.5)};
        case Rotation::West:  return {baseX - (progress - 0.5), baseY};
    }
    return {baseX, baseY};
}
