#pragma once

#include <QGeoCoordinate>
#include <QList>
#include <QObject>
#include <QThread>

#include "QNemoProgress.h"
#include "SnakeTiles.h"
#include "SnakeTilesLocal.h"

#include <boost/units/systems/si.hpp>

using namespace boost::units;
using Length = quantity<si::length>;
using Area = quantity<si::area>;

class SnakeThread : public QThread {
  Q_OBJECT

  class Impl;
  using PImpl = std::unique_ptr<Impl>;

public:
  SnakeThread(QObject *parent = nullptr);
  ~SnakeThread() override;

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

  SnakeTiles tiles() const;
  SnakeTilesLocal tilesENU() const;
  QGeoCoordinate ENUOrigin() const;
  QVariantList tileCenterPoints() const;
  QVector<int> progress() const;
  bool calcInProgress() const;
  QString errorMessage() const;
  bool success() const;

  bool tilesUpdated();
  bool waypointsUpdated();
  bool progressUpdated();

  QVector<QGeoCoordinate> waypoints() const;
  QVector<QGeoCoordinate> arrivalPath() const;
  QVector<QGeoCoordinate> returnPath() const;

  Length lineDistance() const;
  void setLineDistance(Length lineDistance);

  Length minTransectLength() const;
  void setMinTransectLength(Length minTransectLength);

  Area minTileArea() const;
  void setMinTileArea(Area minTileArea);

  Length tileHeight() const;
  void setTileHeight(Length tileHeight);

  Length tileWidth() const;
  void setTileWidth(Length tileWidth);

signals:
  void calcInProgressChanged(bool inProgress);

protected:
  void run() override;

private:
  PImpl pImpl;
};
