#include "MeasurementTile.h"

#include <QDebug>

const char *MeasurementTile::settingsGroup = "MeasurementTile";
const char *MeasurementTile::nameString = "MeasurementTile";

MeasurementTile::MeasurementTile(QObject *parent)
    : GeoArea(parent), _progress(0), _id(MeasurementTile::randomId()) {
  init();
}

MeasurementTile::MeasurementTile(const MeasurementTile &other, QObject *parent)
    : GeoArea(other, parent), _progress(other._progress), _id(other._id) {
  init();
}

MeasurementTile::~MeasurementTile() {}

MeasurementTile &MeasurementTile::operator=(const MeasurementTile &other) {
  GeoArea::operator=(other);
  setProgress(other._progress);
  setId(other._id);
  return *this;
}

QString MeasurementTile::mapVisualQML() const { return QStringLiteral(""); }

QString MeasurementTile::editorQML() const { return QStringLiteral(""); }

MeasurementTile *MeasurementTile::clone(QObject *parent) const {
  return new MeasurementTile(*this, parent);
}

void MeasurementTile::push_back(const QGeoCoordinate &c) {
  this->appendVertex(c);
}

void MeasurementTile::init() { this->setObjectName(nameString); }

QString MeasurementTile::id() const { return _id; }

void MeasurementTile::setId(const QString &id) {
  if (_id != id) {
    _id = id;
    emit idChanged();
  }
}

QList<QGeoCoordinate> MeasurementTile::tile() const { return coordinateList(); }

QString MeasurementTile::randomId(int length) {
  static const QString values(
      "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789");
  static std::uint64_t counter = 0;
  static auto firstCall = std::chrono::high_resolution_clock::now();

  auto delta = std::chrono::duration_cast<std::chrono::nanoseconds>(
                   std::chrono::high_resolution_clock::now() - firstCall)
                   .count();

  std::srand((unsigned int)delta ^ counter);
  QString str;
  for (int i = 0; i < length; ++i) {
    int index = std::rand() % values.length();
    QChar c = values.at(index);
    str.append(c);
  }

  ++counter;
  return str;
}

double MeasurementTile::progress() const { return _progress; }

void MeasurementTile::setProgress(double progress) {
  if (_progress != progress) {
    _progress = progress;
    emit progressChanged();
  }
}
