#pragma once

#include <QFutureWatcher>
#include <QObject>
#include <QTimer>

#include "WimaArea.h"

#include "SettingsFact.h"

class WimaMeasurementArea : public WimaArea {
  Q_OBJECT
public:
  WimaMeasurementArea(QObject *parent = nullptr);
  WimaMeasurementArea(const WimaMeasurementArea &other,
                      QObject *parent = nullptr);
  WimaMeasurementArea &operator=(const WimaMeasurementArea &other);
  ~WimaMeasurementArea();

  Q_PROPERTY(Fact *tileHeight READ tileHeight CONSTANT)
  Q_PROPERTY(Fact *tileWidth READ tileWidth CONSTANT)
  Q_PROPERTY(Fact *minTileArea READ minTileArea CONSTANT)
  Q_PROPERTY(Fact *transectDistance READ transectDistance CONSTANT)
  Q_PROPERTY(Fact *minTransectLength READ minTransectLength CONSTANT)
  Q_PROPERTY(Fact *showTiles READ showTiles CONSTANT)
  Q_PROPERTY(QmlObjectListModel *tiles READ tiles NOTIFY tilesChanged)
  Q_PROPERTY(int maxTiles READ maxTiles NOTIFY maxTilesChanged)

  // Overrides from WimaPolygon
  QString mapVisualQML(void) const;
  QString editorQML(void) const;

  Fact *tileHeight();
  Fact *tileWidth();
  Fact *minTileArea();
  Fact *transectDistance();
  Fact *minTransectLength();
  Fact *showTiles();
  QmlObjectListModel *tiles();
  int maxTiles();
  bool ready();

  // Member Methodes
  void saveToJson(QJsonObject &json);
  bool loadFromJson(const QJsonObject &json, QString &errorString);

  // Friends
  friend void print(const WimaMeasurementArea &area, QString outputStr);
  friend void print(const WimaMeasurementArea &area);

  // Static Variables
  static const char *settingsGroup;
  static const char *tileHeightName;
  static const char *tileWidthName;
  static const char *minTileAreaName;
  static const char *transectDistanceName;
  static const char *minTransectLengthName;
  static const char *showTilesName;
  static const char *WimaMeasurementAreaName;

signals:
  void tilesChanged();
  void maxTilesChanged();

public slots:

private slots:
  void doUpdate();
  void deferUpdate();
  void storeTiles();

private:
  // Member Methodes
  void init();

  // Members
  QMap<QString, FactMetaData *> _metaDataMap;

  SettingsFact _tileHeight;
  SettingsFact _tileWidth;
  SettingsFact _minTileArea;
  SettingsFact _transectDistance;
  SettingsFact _minTransectLength;
  SettingsFact _showTiles;

  // Tile stuff.
  QTimer _timer;
  using TilesPtr = std::shared_ptr<QmlObjectListModel>;
  TilesPtr _pTiles;
  QList<QGeoCoordinate> _polygon;
  QFutureWatcher<TilesPtr> _watcher;
  bool _calculating;
  bool _polygonValid;
};
