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

#include <DinverDCCore.h>
#include <QGpCoreWave.h>
#include <QGpGuiTools.h>
#include <QGpGuiWave.h>
#include <SciFigs.h>
#include "RefractionViewer.h"

namespace DinverDCGui {

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

  Full description of class still missing
*/

RefractionViewer::RefractionViewer(QWidget * parent)
    : DCModelViewer(parent)
{
  TRACE;
  // Tools menu
  QMenu * m;
  QAction * a;

  m=addMenu(tr( "&Tools" ));

  a=new QAction(tr( "Current target" ), this);
  a->setCheckable(true);
  a->setChecked(true);
  a->setStatusTip(tr( "Show/hide the current target onto the inverted refraction curves" ));
  connect(a, SIGNAL(toggled(bool)), this, SLOT(showTarget(bool)) );
  m->addAction(a);
}

RefractionVpViewer::RefractionVpViewer(QWidget * parent)
   : RefractionViewer(parent)
{
  TRACE;
  setObjectName("RefractionVpViewer");
  setWindowTitle(tr("Refraction Vp:"));
}

RefractionVpViewer::~RefractionVpViewer()
{
  TRACE;
}

RefractionVsViewer::RefractionVsViewer(QWidget * parent)
   : RefractionViewer(parent)
{
  TRACE;
  setObjectName("RefractionVsViewer");
  setWindowTitle(tr("Refraction Vs:"));
}

RefractionVsViewer::~RefractionVsViewer()
{
  TRACE;
}

AbstractLine * RefractionViewer::targetReferenceLine() const
{
  TRACE;
  RefractionLine * line=new RefractionLine;
  line->setPen(Pen( Qt::black, 0.6) );
  line->setSymbol(Symbol( Symbol::Circle, 1.2, Pen(Qt::black, 0.0),
                              Brush(Qt::black, Qt::SolidPattern) ));
  return line;
}

void RefractionViewer::setTitles(int i)
{
  TRACE;
  AxisWindow * w=_graphs[i];
  w->yAxis()->setTitle(tr("Time (ms)"));
  w->yAxis()->setTitleInversedScale( "" );
  w->yAxis()->setUnitFactor(1000.0);
  w->xAxis()->setTitle(tr("Distance (m)"));
  w->xAxis()->setTitleInversedScale( "" );
  w->setObjectName(QString("refra_%1").arg(i));
}

bool RefractionVpViewer::hasCurves(DCReportBlock& dcBlock, int)
{
  TRACE;
  return dcBlock.refractionVp();
}

bool RefractionVsViewer::hasCurves(DCReportBlock& dcBlock, int)
{
  TRACE;
  return dcBlock.refractionVs();
}

void RefractionViewer::setSampleCount(DCModelInfo * info, DCReportBlock& dcBlock)
{
  TRACE;
  // Read number of sources and receivers
  int nSrc, nRec;
  dcBlock.stream() >> nSrc >> nRec;
  if(nSrc>_nGraphs) nSrc=_nGraphs;
  int i;
  for(i=0;i<nSrc;i++) {
    info->setSampleCount(i,nRec);
  }
  for(;i<_nGraphs;i++) info->setSampleCount(i,0);
}

void RefractionViewer::report2plot(DCReportBlock& dcBlock, Point2D ** points, const DCModelInfo& info)
{
  TRACE;
  RefractionFactory f;
  f.readReport(dcBlock.stream());
  if(_sources.isEmpty()) {
    _sources=f.sources();
  }
  const QVector<double>& xRec=f.receivers();
  int n=_nGraphs;
  if(n>_sources.count()) n=_sources.count();
  for(int iSrc=0; iSrc < n; iSrc++ ) {
    Point2D * srcPoints=points[iSrc]+info.offset(iSrc);
    const RealValue * values=f.source(iSrc);
    for(int iRec=0; iRec < f.receiverCount(); iRec++ ) {
      Point2D& p=srcPoints[iRec];
      p.setX(xRec[iRec] );
      p.setY(values[iRec].value());
    }
  }
}

void RefractionViewer::setLimits(int i, const Rect& r)
{
  TRACE;
  _graphs[ i ] ->xAxis()->setRange(r.x1() * 0.95, r.x2() * 1.05);
  _graphs[ i ] ->yAxis()->setRange(0.0, r.y2() * 1.05);
}

void RefractionVpViewer::setTarget(const TargetList * tl)
{
  TRACE;
  const QList<RefractionCurve>& curves=tl->refractionVpTarget().curves();
  int n=_nGraphs;
  if(n>_sources.count()) n=_sources.count();
  for(int i=0;i<n;i++) {
    for(QList<RefractionCurve>::const_iterator it=curves.begin(); it!=curves.end(); it++ ) {
      if(it->source()==_sources.at(i)) {
        static_cast<RefractionLine *>(_targetLayers[i]->addLine())->setCurve( *it);
      }
    }
    addText(i, tr("Source at %1 m").arg(_sources.at(i)) );
  }
}

void RefractionVsViewer::setTarget(const TargetList * tl)
{
  TRACE;
  const QList<RefractionCurve>& curves=tl->refractionVsTarget().curves();
  int n=_nGraphs;
  if(n>_sources.count()) n=_sources.count();
  for(int i=0;i<n;i++) {
    for(QList<RefractionCurve>::const_iterator it=curves.begin(); it!=curves.end(); it++ ) {
      if(it->source()==_sources.at(i)) {
        static_cast<RefractionLine *>(_targetLayers[i]->addLine())->setCurve( *it);
      }
    }
    addText(i, tr("Source at %1 m").arg(_sources.at(i)) );
  }
}

} // namespace DinverDCGui
