//
// Created by Dan Crosby on 8/31/23.
//

#include "AIMinimumDistanceAndTarget.hpp"

namespace shardok {
namespace {

auto CoordsIndex(const Coords &coords, const int columnCount) -> int {
    return coords.row() * columnCount + coords.column();
}

auto CoordsFromIndex(const size_t index, const int columnCount) -> Coords {
    return Coords(
            static_cast<int8_t>(index / static_cast<size_t>(columnCount)),
            static_cast<int8_t>(index % static_cast<size_t>(columnCount)));
}

}  // namespace

auto MinimumDistanceAndTarget(
        const ActionPointDistances *apd,
        const Coords &origin,
        const CoordsSet &destinations) -> CoordsAndDistance {
    CoordsAndDistance min{Coords(-1, -1), ActionPointDistances::IMPOSSIBLE};
    const int columnCount = destinations.ColumnCount();
    const int originIndex = CoordsIndex(origin, columnCount);

    for (const auto destIndex : destinations.indexIterator()) {
        const DIST_T dist = apd->Distance(originIndex, static_cast<int>(destIndex));
        if (dist == ActionPointDistances::IMPOSSIBLE) continue;
        if (dist < min.distance) {
            min = CoordsAndDistance{CoordsFromIndex(destIndex, columnCount), dist};
        }
    }

    return min;
}

auto MinimumDistance(
        const ActionPointDistances *apd,
        const Coords &origin,
        const CoordsSet &destinations) -> int {
    return MinimumDistanceAndTarget(apd, origin, destinations).distance;
}
}  // namespace shardok
