#include "plain_index.h"

#include <set>


namespace maps {
namespace wiki {
namespace topo {
namespace index {

void PlainIndex::addNode(NodeID id, const geolib3::Point2& pos)
{
    nodes_[id] = pos;
}

void PlainIndex::addEdge(EdgeID id, const geolib3::Polyline2& geom)
{
     edges_[id] = geom;
}

void PlainIndex::deleteNode(NodeID id)
{
    nodes_.erase(id);
}

void PlainIndex::deleteEdge(EdgeID id)
{
    edges_.erase(id);
}

OptionalNodeID PlainIndex::nodeAt(const geolib3::Point2& pos,
    double maxDistance, const NodeIDSet& ignoredNodeIds) const
{
    return objectAtPoint(nodes_, pos, maxDistance, ignoredNodeIds);
}

boost::optional<EdgeID> PlainIndex::edgeAt(const geolib3::Point2& pos,
    double maxDistance, const EdgeIDSet& ignoredEdgeIds) const
{
    return objectAtPoint(edges_, pos, maxDistance, ignoredEdgeIds);
}

NodeIDVector PlainIndex::nearestNodes(const geolib3::Point2& point,
    double distance, const NodeIDSet& ignoredNodeIds) const
{
    return nearestObjects<NodeMap, NodeIDSet, geolib3::Point2, NodeIDVector>
        (nodes_, point, distance, ignoredNodeIds);
}

EdgeIDVector PlainIndex::nearestEdges(const geolib3::Point2& point,
    double distance, const EdgeIDSet& ignoredEdgeIds) const
{
    return nearestObjects<EdgeMap, EdgeIDSet, geolib3::Point2, EdgeIDVector>
        (edges_, point, distance, ignoredEdgeIds);
}

EdgeIDVector PlainIndex::nearestEdges(const geolib3::Polyline2& polyline, double distance,
    const EdgeIDSet& ignoredEdgeIds) const
{
    return nearestObjects<EdgeMap, EdgeIDSet, geolib3::Polyline2, EdgeIDVector>
        (edges_, polyline, distance, ignoredEdgeIds);
}

NodeIDVector PlainIndex::nearestNodes(const geolib3::Polyline2& polyline,
    double distance, const NodeIDSet& ignoredNodeIds) const
{
    return nearestObjects<NodeMap, NodeIDSet, geolib3::Polyline2, NodeIDVector>
        (nodes_, polyline, distance, ignoredNodeIds);
}

EdgeIDVector PlainIndex::intersectingEdges(const geolib3::Polyline2& polyline)
    const
{
    EdgeIDVector result;
    for (const auto& edge : edges_) {
        if (geolib3::intersects(edge.second, polyline)) {
            result.push_back(edge.first);
        }
    }
    return result;
}

} // namespace maps::wiki::topo::index
} // namespace maps::wiki::topo
} // namespace maps::wiki
} // namespace maps
