#pragma once

#include <yandex/maps/wiki/topo/common.h>

#include <maps/libs/geolib/include/polyline.h>

#include <boost/noncopyable.hpp>

#include <memory>

namespace maps {
namespace wiki {
namespace topo {

typedef std::vector<Edge> EdgeVector;

class Graph;

class Edge {
public:
    Edge(EdgeID id, const geolib3::Polyline2& geom,
        NodeID startNode, NodeID endNode);

    Edge(const Edge&);
    Edge& operator=(const Edge&);

    Edge(Edge&&);
    Edge& operator=(Edge&&);

    ~Edge();

    EdgeID id() const;

    NodeID startNode() const;
    NodeID endNode() const;
    NodeID node(const IncidenceType& type) const;

    IncidentNodes incidentNodes() const;

    const geolib3::Polyline2& geom() const;

    NodeID oppositeNode(NodeID nodeId) const;

    bool isIncident(NodeID node) const;
    bool isStart(NodeID node) const;
    bool isEnd(NodeID node) const;

    /// available if loaded
    boost::optional<FaceIDSet> faceIds() const;

    /// throws if edge faces were not loaded
    bool isPartOfFace(FaceID faceId) const;

private:
    friend class Graph;
    friend class CacheImpl;

    struct Impl;

    std::unique_ptr<Impl> impl_;
};

} // namespace topo
} // namespace wiki
} // namespace maps
