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

#include <QGpCoreTools.h>
#include <SciFigs.h>

#include "CurvesThread.h"

/*!
  \class CurvesThread CurvesThread.h
  \brief Brief description of class still missing

  Full description of class still missing
*/

/*!
  Description of constructor still missing
*/
CurvesThread::CurvesThread(QObject * parent)
    : ResultsThread(parent)
{
  TRACE;
  _layer=0;
  connect(this, SIGNAL(finished()), this, SLOT(showCurves()), Qt::QueuedConnection);
}

/*!
  Description of constructor still missing
*/
CurvesThread::CurvesThread(const CurvesThread& o)
    : ResultsThread(o.parent())
{
  TRACE;
  _layer=0;
  connect(this, SIGNAL(finished()), this, SLOT(showCurves()), Qt::QueuedConnection);
  _x=o._x;
}

/*!
  Description of destructor still missing
*/
CurvesThread::~CurvesThread()
{
  TRACE;
}

void CurvesThread::initResultsGraphs(GraphicSheet * sheet)
{
  TRACE;
  AxisWindow * w=new AxisWindow;
  w->setGeometry(sheet->printRight(), 0.5, 10.0, 8.0);
  sheet->addObject(w);
  sheet->showObject(w);
  sheet->autoResizeContent();

  _layer=new LineLayer(w);
  _layer->setObjectName(objectName()+" curves");
  _layer->setReferenceLine(new PlotLine2D);
  QObject::connect(legend(), SIGNAL(changed( Legend) ), _layer, SLOT(setLegend( Legend) ));
}

void CurvesThread::initResultsGraphs(const ResultsThread& o)
{
  TRACE;
  const CurvesThread& oc=static_cast<const CurvesThread&>(o);
  _layer=new LineLayer(oc._layer->graph());
  _layer->setObjectName(objectName()+" curves");
  _layer->setReferenceLine(new PlotLine2D);
  connect(legend(), SIGNAL(changed( Legend) ), _layer, SLOT(setLegend( Legend) ));
}

bool CurvesThread::setParameters(int& argc, char ** argv)
{
  TRACE;
  SamplingOption samplingType=LogScale;
  int nSamples=100;
  double minRange=0.2;
  double maxRange=20.0;
  int i, j=1;
  for(i=1; i<argc; i++) {
    QByteArray arg=argv[i];
    if(arg[0]=='-') {
      if(arg=="-s") {
        CoreApplication::checkOptionArg(i, argc, argv);
        if(strcmp(argv[i],"period")==0) {
          samplingType=InversedScale;
        } else if(strcmp(argv[i],"frequency")==0) {
          samplingType=LinearScale;
        } else {
          samplingType=LogScale;
        }
      } else if(arg=="-min") {
        CoreApplication::checkOptionArg(i, argc, argv);
        minRange=atof(argv[i]);
      } else if(arg=="-max") {
        CoreApplication::checkOptionArg(i, argc, argv);
        maxRange=atof(argv[i]);
      } else if(arg=="-n") {
        CoreApplication::checkOptionArg(i, argc, argv);
        nSamples=atoi(argv[i]);
        if(nSamples<=0) {
          App::log(tr("gpdclive: negative or null number of samples (option -n)\n") );
          return false;
        }
      } else {
        argv[j++]=argv[i];
      }
    } else {
      argv[j++]=argv[i];
    }
  }
  if(j < argc) {
    argv[j]=nullptr;
    argc=j;
  }
  // Compute common sampling scale
  Curve<Point1D> c;
  c.line(minRange, maxRange);
  c.resample(nSamples, minRange, maxRange, samplingType);
  c.xMultiply(2*M_PI); // convert to angular frequency
  _x=c.xVector();
  return true;
}

void CurvesThread::showCurves()
{
  TRACE;
  if(isRunning()) return;
  _layer->clear();
  PlotLine2D * line;
  const Legend& leg=legend()->legend();
  int n=_curves.count();
  for(int i=0;i<n; i++) {
    line=static_cast<PlotLine2D *>(_layer->addLine(leg.pen(i), leg.symbol(i)) );
    line->curve()=_curves.at(i);
  }
  if(automaticLimits()) setResultsLimits();
  _layer->graph()->deepUpdate();
}

void CurvesThread::clear()
{
  TRACE;
  _layer->clear();
  resultsDeepUpdate();
}

void CurvesThread::run()
{
  TRACE;
  _curves.clear();
  QList<GeophysicalModel *>::iterator it;
  for(it=_models.begin(); it!=_models.end(); it++) {
    if(terminated()) break;
    run(*it);
  }
  qDeleteAll(_models);
}

void CurvesThread::setResultsLimits()
{
  TRACE;
  Rect r=_layer->boundingRect();
  if(!r.isNull()) {
    _layer->graph()->xAxis()->setRange(r.x1(), r.x2());
    _layer->graph()->yAxis()->setRange(r.y1()*0.9, r.y2()*1.1);
  }
}

void CurvesThread::resultsDeepUpdate()
{
  TRACE;
  _layer->graph()->deepUpdate();
}
