#pragma once

#include <QObject>
#include <QVariant>
#include <QThread>
#include <QVector>
#include <QGeoCoordinate>
#include <QMutex>

#include <vector>
#include <memory>

#include "GeoPolygonArray.h"
#include "PolygonArray.h"
#include "SnakeWorker.h"
#include "QNemoProgress.h"


typedef QList<QVariant> QVariantList;

namespace snake {
    class Scenario;
    class Flightplan;
}

struct SnakeData{
    SnakeData();

    QVector<QGeoCoordinate> waypoints;
    QVector<QGeoCoordinate> arrivalPath;
    QVector<QGeoCoordinate> returnPath;
    QGeoCoordinate          ENUorigin;
    QVector<QGeoCoordinate> waypointsENU;
    QVector<QGeoCoordinate> arrivalPathENU;
    QVector<QGeoCoordinate> returnPathENU;
    GeoPolygonArray         tiles;
    QVariantList            tileCenterPoints;
    PolygonArray            tilesENU;
    QVector<QGeoCoordinate> tileCenterPointsENU;
    QString                 errorMessage;
    mutable QMutex          m;

    void clear();
};

class SnakeDataManager : public QThread{
    Q_OBJECT

public:

    using ProgressPtr   = std::shared_ptr<std::vector<int>>;
    using ScenarioPtr   = std::shared_ptr<snake::Scenario>;
    using FlightPlanPtr = std::shared_ptr<snake::Flightplan>;
    using SnakeDataPtr  = std::shared_ptr<SnakeData>;

    SnakeDataManager(QObject *parent = nullptr);
    ~SnakeDataManager() override;


    void setMeasurementArea     (const QList<QGeoCoordinate>  &measurementArea);
    void setServiceArea         (const QList<QGeoCoordinate>  &serviceArea);
    void setCorridor            (const QList<QGeoCoordinate>  &corridor);

    SnakeDataPtr snakeData();

    double lineDistance() const;
    void setLineDistance(double lineDistance);

    double minTransectLength() const;
    void setMinTransectLength(double minTransectLength);

    double minTileArea() const;
    void setMinTileArea(double minTileArea);

    double tileHeight() const;
    void setTileHeight(double tileHeight);

    double tileWidth() const;
    void setTileWidth(double tileWidth);

protected:
    void run() override;

private:
    bool precondition() const;

    std::vector<QGeoCoordinate> _mArea;
    std::vector<QGeoCoordinate> _sArea;
    std::vector<QGeoCoordinate> _corridor;
    ScenarioPtr                 _pScenario;
    ProgressPtr                 _pProgress;
    FlightPlanPtr               _pFlightplan;
    SnakeDataPtr                _pData;
};









