#pragma once

#include <yandex/maps/wiki/validator/content/geom_objects_view.h>
#include <yandex/maps/wiki/validator/objects/edge.h>
#include <yandex/maps/wiki/validator/objects/face.h>

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

namespace maps {
namespace wiki {
namespace validator {
namespace utils {

struct FaceNode {
    TId id;
    geolib3::Point2 geom;
};

class FaceBuilder
{
public:
    struct Segment {
        FaceNode startNode;
        TId edgeId;

        // returns points of the corresponding edge in correct order -
        // that is, starting with node startNode.
        geolib3::PointsVector points(
                const GeomObjectsView<Edge>& edgesView) const;
    };

    FaceBuilder(const Face* face, const GeomObjectsView<Edge>& edgesView);

    const Face* face() const { return face_; }

    bool valid() const;
    void checkValid() const;

    const std::vector<Segment>& segments() const;

    // Return points of the linear ring representing geometry of this
    // face. Geolib Polygon2 can be directly constructed from the
    // output of this method.
    geolib3::PointsVector points() const;


    const std::vector<FaceNode>& componentRepresentatives() const
    { return componentRepresentatives_; }

    const std::vector<FaceNode>& openBounds() const
    { return openBounds_; }

    const std::vector<FaceNode>& selfIntersections() const
    { return selfIntersections_; }

private:
    const Face* face_;
    const GeomObjectsView<Edge>& edgesView_;

    std::vector<Segment> segments_;
    std::vector<FaceNode> componentRepresentatives_;
    std::vector<FaceNode> openBounds_;
    std::vector<FaceNode> selfIntersections_;
};


} // namespace utils
} // namespace validator
} // namespace wiki
} // namespace maps
