#include "entrance_searcher.h"

#include <maps/libs/geolib/include/conversion.h>
#include <maps/libs/geolib/include/distance.h>

namespace maps::wiki::pedestrian {

const double ENTRANCE_SEARCH_RADIUS_METERS = 1.;

EntranceSearcher::EntranceSearcher(const std::vector<Entrance>& entrances) :
    entrances_(entrances)
{
    entranceBoxes_.reserve(entrances_.size());

    for (const auto& entrance : entrances_) {
        double boxWidthMerc = geolib3::toMercatorUnits(
            2 * ENTRANCE_SEARCH_RADIUS_METERS,
            entrance.positionMerc
        );
        entranceBoxes_.emplace_back(entrance.positionMerc, boxWidthMerc, boxWidthMerc);
        searcher_.insert(&entranceBoxes_.back(), &entrance);
    }

    searcher_.build();
}

std::vector<Entrance>
EntranceSearcher::getBuildingEntrances(const Building& building) const
{
    std::vector<Entrance> result;

    auto inBoundingBox = searcher_.find(building.polygonMerc.boundingBox());
    for (auto it = inBoundingBox.first; it != inBoundingBox.second; ++it) {
        const Entrance* candidateEntrance = it->value();

        double distanceInMeters = geolib3::toMeters(
            geolib3::distance(building.polygonMerc, candidateEntrance->positionMerc),
            candidateEntrance->positionMerc
        );

        if (distanceInMeters < ENTRANCE_SEARCH_RADIUS_METERS) {
            result.push_back(*candidateEntrance);
        }
    }

    return result;
}


} // namespace maps::wiki::pedestrian
