/***************************************************************************
**
**  This file is part of TapePositioningSystem.
**
**  TapePositioningSystem is free software: you can redistribute it and/or modify
**  it under the terms of the GNU General Public License as published by
**  the Free Software Foundation, either version 3 of the License, or
**  (at your option) any later version.
**
**  TapePositioningSystem is distributed in the hope that it will be useful,
**  but WITHOUT ANY WARRANTY; without even the implied warranty of
**  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
**  GNU General Public License for more details.
**
**  You should have received a copy of the GNU General Public License
**  along with Foobar.  If not, see <http://www.gnu.org/licenses/>
**
**  See http://www.geopsy.org for more information.
**
**  Created: 2012-11-15
**  Copyright: 2012-2019
**    Marc Wathelet (ISTerre, Grenoble, France)
**
***************************************************************************/

#ifndef TRIANGULATOR_H
#define TRIANGULATOR_H

#include <QGpCoreMath.h>

#include "TapePositioningSystemDLLExport.h"

namespace TapePositioningSystem {

  class Node;
  class Cluster;

  class TAPEPOSITIONINGSYSTEM_EXPORT Triangulator
  {
  public:
    Triangulator();
    ~Triangulator();

    void setProgess(AbstractProgress * p) {_progress=p;}

    Node * addNode(const QString& name);
    Node * node(const QString& name) const;
    QList<Node *> nodes() const {return _nodes.values();}

    void addDistance(const QString& node1, const QString& node2, double value);

    void aggregate(int clusterCount, double stddev);
    void setCoordinates(Node * origin, Node * north, Node * eastward);
    void setPosteriorPrecision(double precision);
    void setPriorCoordinates(const QMap<QString, Point>& c, double precision);

    const QList<Cluster *>& clusters() const {return _clusters;}
    QSet<Point2D> solutions(const QString& nodeName) const;
    Covariance covariance(const QString& nodeName) const;
    void printClusters();
    double computedDistance(const QString& node1, const QString& node2) const;
  private:
    void orderedAggregate(QList<Cluster *> quads);
    bool exhaustiveAggregate(Cluster * parent, QList<Cluster *> quads);
    void randomAggregate(int clusterCount, QList<Cluster *> quads);
    QVector<int> randomIndex(Random& generator, int n);

    double _maxStddev;
    QMap<QString, Node *> _nodes;
    QList<Cluster *> _clusters;
    AbstractProgress * _progress;
  };

} // namespace TapePositioningSystem

#endif // TRIANGULATOR_H
