#ifndef SphereCalculus_H
#define SphereCalculus_H

#include <QObject>
#include <QGeoCoordinate>

// Abstract class providing methods to do calculations on objects located on a sphere (e.g. earth)
class SphereCalculus : public QObject
{
    Q_OBJECT
public:
    SphereCalculus(QObject *parent = nullptr);
    SphereCalculus(const SphereCalculus &other, QObject *parent = nullptr);
    SphereCalculus &operator=(const SphereCalculus &other);


    enum JoinPolygonError { NotSimplePolygon, Disjoint, NoError, PathSizeLow};
    enum IntersectionType { NoIntersection, EdgeIntersection, Inside};

    // Property setters
    void setEpsilonMeter(double epsilon);

    // Property getters
    double epsilonMeter() const;

    // Member Methodes
    int                 closestVertexIndex  (const QList<QGeoCoordinate> &path, const QGeoCoordinate &coordinate) const;
    QGeoCoordinate      closestVertex       (const QList<QGeoCoordinate> &path, const QGeoCoordinate &coordinate) const;
    int                 nextVertexIndex     (int index) const;
    int                 previousVertexIndex (int index) const;
    JoinPolygonError    joinPolygon         (const QList<QGeoCoordinate> &polygon1, const QList<QGeoCoordinate> &polygon2,
                                             QList<QGeoCoordinate> &joinedPolygon) const;
    IntersectionType    intersects          (const QList<QGeoCoordinate> &line1, const QList<QGeoCoordinate> &line2,
                                             QGeoCoordinate &intersectionPt)const;
    IntersectionType    intersects          (const QList<QGeoCoordinate> &polygon, const QList<QGeoCoordinate> &line,
                                             QList<QGeoCoordinate> &intersectionList,  QList<QPair<int, int>> &neighbourList)const;
    IntersectionType    intersects          (const QList<QGeoCoordinate> &polygon, const QList<QGeoCoordinate> &line) const;
    bool                dijkstraPath        (const QList<QGeoCoordinate> &polygon, const QGeoCoordinate& c1,
                                             const QGeoCoordinate& c2, QList<QGeoCoordinate>& dijkstraPath) const;
    bool                isSelfIntersecting  (const QList<QGeoCoordinate> &path);



signals:

public slots:

private:
    double          distInsidePoly          (const QGeoCoordinate& c1, const QGeoCoordinate& c2, QList<QGeoCoordinate> polygon);

    double _epsilonMeter; // The accuracy used for distance calculations (unit: m).

};

#endif // SphereCalculus_H
