/***************************************************************************
**
**  This file is part of dinver.
**
**  dinver 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.
**
**  dinver 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: 2005-10-31
**  Copyright: 2005-2019
**    Marc Wathelet
**    Marc Wathelet (LGIT, Grenoble, France)
**
***************************************************************************/

#ifndef PROCESSSTATUS_H
#define PROCESSSTATUS_H

#include <SciFigs.h>

#include "ui_ProcessStatus.h"
#include "ModelThreadInfo.h"

class StatusThreadInfo
{
public:
  StatusThreadInfo() {
    nVisitedModels=0;
    nValidModels=0;
    nActiveModels=0;
    nr=0;
    nGiveUp=0;
    nRejected=0;
    deltaNModels=0;
    deltaNRejected=0;
    bestMisfit=std::numeric_limits<double>::infinity();
    lastVisitedIndex=0;
    lastValidIndex=0;
    line=0;
  }

  int nVisitedModels;
  int nValidModels;
  int nActiveModels;
  int nr;
  int nGiveUp;
  int nRejected;
  int deltaNModels;
  int deltaNRejected;
  double bestMisfit;
  PlotLine2D * line;
  int lastValidIndex;
  int lastVisitedIndex;
  int deltaTime;
  QElapsedTimer time;
};

typedef QMap<InversionThread *, StatusThreadInfo *> StatusThreadMap;

class StatusThreadItem : public QAbstractItemModel
{
  Q_OBJECT
public:
  StatusThreadItem(StatusThreadMap * threads, QObject * parent=nullptr);
  ~StatusThreadItem();

  virtual int rowCount(const QModelIndex &parent=QModelIndex()) const;
  virtual int columnCount(const QModelIndex &parent=QModelIndex()) const;
  virtual QVariant data(const QModelIndex &index, int role) const;
  virtual QVariant headerData(int section, Qt::Orientation orientation, int role=Qt::DisplayRole) const;
  virtual QModelIndex parent (const QModelIndex & index) const;
  virtual QModelIndex index (int, int column, const QModelIndex & parent=QModelIndex()) const;
public slots:
  void beginChange();
  void endChange();
private:
  StatusThreadMap * _threads;
};

class ProcessStatus : public QWidget, public Ui::ProcessStatus
{
  Q_OBJECT
public:
  ProcessStatus(QWidget *parent=nullptr, Qt::WindowFlags f=Qt::Widget);
  ~ProcessStatus();

  void clear();
  void clearThread(InversionThread * t);
  void removeThread(InversionThread * t);
  Legend& legend() {return _legend;}
public slots:
  void synchronize();
  void changeLegend();
protected:
  bool setMisfitRange();

  Legend _legend;
  StatusThreadMap _threads;
  bool _threadsInitialized;
  LineLayer * _curveLayer;

  void updateMisfitCurve(InversionThread * t);
  void updatePens();
};

class ProcessStatusDelegate : public QItemDelegate
{
  Q_OBJECT
public:
  ProcessStatusDelegate(ProcessStatus * parent) : QItemDelegate(parent) {}

  virtual void paint (QPainter * painter, const QStyleOptionViewItem & option,
                       const QModelIndex & index) const;
  virtual QSize sizeHint (const QStyleOptionViewItem & option, const QModelIndex & index) const;
};

#endif // QTBPROCESSSTATUS_H
