/***************************************************************************
**
**  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: 2010-05-26
**  Copyright: 2010-2019
**    Marc Wathelet (LGIT, Grenoble, France)
**
***************************************************************************/

#include "MagnetoTelluricViewer.h"

namespace DinverDCGui {

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

  Full description of class still missing
*/

/*!
  Description of constructor still missing
*/
MagnetoTelluricViewer::MagnetoTelluricViewer(QWidget * parent)
    : DCModelViewer(parent)
{
  TRACE;
  setObjectName("MagnetoTelluricViewer");
  setWindowTitle(tr("Magneto-telluric curves:"));

  // 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 magneto-telluric curves" ));
  connect(a, SIGNAL(toggled(bool)), this, SLOT(showTarget(bool)) );
  m->addAction(a);
}

MagnetoTelluricViewer::~MagnetoTelluricViewer()
{
  TRACE;
}

AbstractLine * MagnetoTelluricViewer::targetReferenceLine() const
{
  TRACE;
  MagnetoTelluricLine * line=new MagnetoTelluricLine;
  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 MagnetoTelluricViewer::setTitles(int i)
{
  TRACE;
  AxisWindow * w=_graphs[i];
  w->xAxis()->setTitle( "Frequency (kHz)" );
  w->xAxis()->setTitleInversedScale( "Period (ms)" );
  w->xAxis()->setScaleType(Scale::Log);
  w->xAxis()->setReversedScale(true);
  w->xAxis()->setAutoTicks(false);
  w->xAxis()->setMajorTicks(5.0);
  w->xAxis()->setMinorTicks(1.0);
  w->xAxis()->setUnitFactor(1e-3);
  w->setObjectName(QString("res_%1").arg(i));
  switch(i) {
  default:
    w->yAxis()->setTitle(tr("Apparent resistivity (ohm m)"));
    w->yAxis()->setTitleInversedScale(tr("Apparent conductivity (S/m)"));
    break;
  case 1:
    w->yAxis()->setTitle(tr("Phase (degrees)"));
    w->yAxis()->setTitleInversedScale(tr("1/Phase (1/degrees)"));
    break;
  }
}

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

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

void MagnetoTelluricViewer::report2plot(DCReportBlock& dcBlock, Point2D ** points, const DCModelInfo& info)
{
  TRACE;
  MagnetoTelluricFactory f;
  f.readReport(dcBlock.stream());
  const QVector<double>& x=f.angularFrequencies();
  int nFrequencies=x.count();
  const ComplexValue * values=f.impedanceXY();
  MagnetoTelluricPointOptions options;
  double frequencyFactor=1.0/(2.0*M_PI);
  for(int ig=0; ig < _nGraphs; ig++ ) {
    switch(ig) {
    default:
      options.setMode(MagnetoTelluricPointOptions::ApparentResistivity);
      break;
    case 1:
      options.setMode(MagnetoTelluricPointOptions::PhaseDegrees);
      break;
    }
    Point2D * gPoints=points[ig]+info.offset(ig);
    for(int is=0; is < nFrequencies; is++ ) {
      Point2D& p=gPoints[is];
      p.setX(frequencyFactor*x.at(is));
      p.setY(options.toDouble(p.x(), values[is].value()));
    }
  }
}

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

void MagnetoTelluricViewer::setTarget(const TargetList * tl)
{
  TRACE;
  const QList<MagnetoTelluricCurve>& curves=tl->magnetoTelluricTarget().curves();
  for(int ig=0;ig<_nGraphs;ig++) {
    for(QList<MagnetoTelluricCurve>::const_iterator it=curves.begin();it!=curves.end(); it++) {
      static_cast<MagnetoTelluricLine *>(_targetLayers[ig]->addLine())->setCurve(*it);
    }
    MagnetoTelluricPointOptions::OutputMode m;
    switch(ig) {
    default:
      m=MagnetoTelluricPointOptions::ApparentResistivity;
      break;
    case 1:
      m=MagnetoTelluricPointOptions::PhaseDegrees;
      break;
    }
    _targetLayers[ig]->setPointOptions(new MagnetoTelluricPointOptions(m));
  }
}

} // namespace DinverDCGui
