/***************************************************************************
**
**  This file is part of QGpCoreMath.
**
**  This library is free software; you can redistribute it and/or
**  modify it under the terms of the GNU Lesser General Public
**  License as published by the Free Software Foundation; either
**  version 2.1 of the License, or (at your option) any later version.
**
**  This file 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 Lesser General Public
**  License for more details.
**
**  You should have received a copy of the GNU Lesser General Public
**  License along with this library; if not, write to the Free Software
**  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
**
**  See http://www.geopsy.org for more information.
**
**  Created: 2017-06-28
**  Copyright: 2017-2019
**    Marc Wathelet (ISTerre, Grenoble, France)
**
***************************************************************************/

#ifndef CURVESPLITTER_H
#define CURVESPLITTER_H

#include <QtCore>

#include "QGpCoreMathDLLExport.h"

namespace QGpCoreMath {

  class QGPCOREMATH_EXPORT CurveSplitter
  {
  public:
    CurveSplitter();
    ~CurveSplitter();

    void addPair(int i1, int i2, double y0, double dx, double y1);
    void clusterize(double maxErr);
  private:
    class Item;
    class ItemFriend;

    int indexOf(int index) const;
    Item * item(int index) {return &_items[index];}

    class Cluster
    {
    public:
      Cluster();

      void add(Item * it);
      bool isEmpty() const {return _items.isEmpty();}
      int count() const {return _items.count();}
      Item * at(int index) const {return _items.at(index);}

      QVector<Item *> _items;
    };

    class Item
    {
    public:
      Item();

      void sortFriends(double maxErr);
      bool hasFriend(int index) const;
      void addToCluster(Cluster * cluster, CurveSplitter * parent);
      static bool lessThan(const QPair<int, double>& f1, const QPair<int, double>& f2);

      int _index;
      double _y;
      Cluster * _cluster;
      QVector<ItemFriend> _friends;
    };

    class ItemFriend
    {
    public:
      ItemFriend() {
        _index=0;
        _slope=0.0;
        _dx=0.0;
        _y=0.0;
      }
      ItemFriend(int i, double slope, double dx, double value) {
        _index=i;
        _slope=slope;
        _dx=dx;
        _y=value;
      }
      ItemFriend(const ItemFriend& o) {
        _index=o._index;
        _slope=o._slope;
        _dx=o._dx;
        _y=o._y;
      }

      int _index;
      double _slope, _dx, _y;
    };

    QVector<Item> _items;
    QVector<Cluster *> _clusters;
  public:
    int clusterCount() const {return _clusters.count();}
    int valueCount(int clusterIndex) const {return _clusters.at(clusterIndex)->count();}
    int index(int clusterIndex, int index) const {return _clusters.at(clusterIndex)->at(index)->_index;}
  };

} // namespace QGpCoreMath

#endif // CURVESPLITTER_H

