/***************************************************************************
**
**  This file is part of dinverdc.
**
**  dinverdc 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.
**
**  dinverdc 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-18
**  Copyright: 2010-2019
**    Marc Wathelet (LGIT, Grenoble, France)
**
***************************************************************************/

#include <DinverDCGui.h>

#include "MagnetoTelluricTargetWidget.h"

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

  Full description of class still missing
*/

/*!
  Description of constructor still missing
*/
MagnetoTelluricTargetWidget::MagnetoTelluricTargetWidget(QWidget * parent)
    : CurveBrowser(parent)
{
  TRACE;
  QWidget * w=new QWidget(this);
  QVBoxLayout * graphLayout=new QVBoxLayout(w);
  graphLayout->setMargin(0);
  graphLayout->setSpacing(0);
  AxisWindow * graph=new AxisWindow(this);
  graph->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
  graphLayout->addWidget(graph);
  QHBoxLayout * comboLayout=new QHBoxLayout;
  graphLayout->addLayout(comboLayout);
  comboLayout->setMargin(9);
  comboLayout->setSpacing(6);
  QLabel * comboLabel=new QLabel;
  comboLabel->setText(tr("Display mode"));
  comboLayout->addWidget(comboLabel);
  _complexMode=new QComboBox(w);
  _complexMode->addItem(tr("Apparent resistivity"));
  _complexMode->addItem(tr("Impedance, absolute value"));
  _complexMode->addItem(tr("Phase (degrees)"));
  _complexMode->addItem(tr("Phase (radians)"));
  _complexMode->addItem(tr("Impedance, real part"));
  _complexMode->addItem(tr("Impedance, imaginary part"));
  comboLayout->addWidget(_complexMode);
  connect(_complexMode, SIGNAL(currentIndexChanged(int)), this, SLOT(setComplexMode(int)));
  QSpacerItem * spacerItem=new QSpacerItem(20, 20, QSizePolicy::Expanding, QSizePolicy::Minimum);
  comboLayout->addItem(spacerItem);
  dock(w);

  setProxy(new MagnetoTelluricProxy);

  setWindowTitle(tr("Magnetotelluric target"));

  setPlotProxy(new MagnetoTelluricPlotProxy);
  LineLayer * l=new LineLayer(graph);
  initLayer(l);
  setCurrentLayer(l);
}

/*!
  Description of destructor still missing
*/
MagnetoTelluricTargetWidget::~MagnetoTelluricTargetWidget()
{
  TRACE;
  WidgetRect::saveRect(this);
}

void MagnetoTelluricTargetWidget::resizeEvent(QResizeEvent * e)
{
  TRACE;
  WidgetRect::record(this);
  CurveBrowser::resizeEvent(e);
}

/*!
  Use this function rather than CurveBrowser::initLayer( ).
*/
void MagnetoTelluricTargetWidget::initLayer(LineLayer * curveLayer)
{
  TRACE;
  CurveBrowser::initLayer(curveLayer);
  setCurrentLayer(curveLayer);
  // Restrict layer to plot only MagnetoTelluricLine
  MagnetoTelluricLine * l=new MagnetoTelluricLine;
  l->setPen(Pen( Qt::black, 0.6) );
  l->setSymbol(Symbol(Symbol::Circle, 1.2, Pen(Qt::black, 0.0),
                       Brush(Qt::black, Qt::SolidPattern) ));
  curveLayer->setReferenceLine(l);

  _pointOptions=new MagnetoTelluricPointOptions(MagnetoTelluricPointOptions::ApparentResistivity);
  curveLayer->setPointOptions(_pointOptions);
  setComplexMode(0);
}

MagnetoTelluricCurve& MagnetoTelluricTargetWidget::curve(int index) const
{
  TRACE;
  MagnetoTelluricLine * line=static_cast<MagnetoTelluricLine *>(currentLayer()->line(index));
  return line->curve();
}

QList<MagnetoTelluricCurve> MagnetoTelluricTargetWidget::curves() const
{
  TRACE;
  QList<MagnetoTelluricCurve> l;
  int n=count();
  for(int i=0;i<n;i++) {
    MagnetoTelluricCurve& c=curve(i);
    l.append(c);
  }
  return l;
}

void MagnetoTelluricTargetWidget::addCurve(const MagnetoTelluricCurve& curve)
{
  TRACE;
  MagnetoTelluricLine * line=static_cast<MagnetoTelluricLine *>(currentLayer()->addLine());
  line->setCurve(curve);
}

void MagnetoTelluricTargetWidget::addCurves(const QList<MagnetoTelluricCurve>& curves)
{
  TRACE;
  int curvesCount=count();
  for(QList<MagnetoTelluricCurve>::const_iterator it=curves.begin();it!=curves.end();it++) {
    addCurve(*it);
  }
  if(curvesCount==0) setLimits();
}

void MagnetoTelluricTargetWidget::setComplexMode(int index)
{
  TRACE;
  LineLayer * layer=currentLayer();
  AxisWindow * graph=layer->graph();
  Axis * yAxis=graph->yAxis();

  switch(index) {
  default:
    _pointOptions->setMode(MagnetoTelluricPointOptions::ApparentResistivity);
    yAxis->setUnitFactor(1.0);
    break;
  case 1:
    _pointOptions->setMode(MagnetoTelluricPointOptions::AbsoluteValue);
    yAxis->setUnitFactor(1e-3);
    break;
  case 2:
    _pointOptions->setMode(MagnetoTelluricPointOptions::PhaseDegrees);
    yAxis->setUnitFactor(1.0);
    break;
  case 3:
    _pointOptions->setMode(MagnetoTelluricPointOptions::PhaseRadians);
    yAxis->setUnitFactor(1.0);
    break;
  case 4:
    _pointOptions->setMode(MagnetoTelluricPointOptions::Real);
    yAxis->setUnitFactor(1e-3);
    break;
  case 5:
    _pointOptions->setMode(MagnetoTelluricPointOptions::Imaginary);
    yAxis->setUnitFactor(1e-3);
    break;
  }
  MagnetoTelluricProxy * p=static_cast<MagnetoTelluricProxy *>(proxy());
  p->setYMode(_pointOptions->mode());

  yAxis->setTitle(p->yTitle());

  setLimits();
  graph->deepUpdate();
}

void MagnetoTelluricTargetWidget::load()
{
  TRACE;
  MessageContext();
  QStringList fileNames=Message::getOpenFileNames(tr("Load magnetotelluric data to fit"),
                                                       tr("All files (*);;"
                                                          "Text file (*);;"
                                                          "Dinver targets (*.target);;"
                                                          "Dinver environment (*.dinver);;"));
  if( !fileNames.isEmpty()) {
    int curvesCount=count();
    ColumnTextParser * parser=0;
    int n=fileNames.count();
    for(int i=0;i<n;i++) {
      QString fileName=fileNames.at(i);
      QFileInfo fi(fileName);
      if(fi.suffix()=="target" || fi.suffix()=="dinver") {
        loadTarget(fileName);
      } else {
        loadMultiColumns(fileName, i==n-1, parser);
      }
    }
    delete parser;
    if(currentLayer()) {
      if(curvesCount==0) setLimits();
    }
  }
}

void MagnetoTelluricTargetWidget::loadTarget(QString fileName)
{
  TRACE;
  TargetList tl;
  XMLVirtualPlugin plugin(&tl, "DispersionCurve");
  XMLDinverHeader hdr(&plugin);
  if(hdr.xml_restoreFile(fileName)!= XMLClass::NoError) {
    Message::warning(MSG_ID, tr( "Loading Dinver target/environment ..." ),
                         tr( "Error while reading file %1" ).arg(fileName), Message::cancel());
    return ;
  }
  addCurves(tl.magnetoTelluricTarget().curves());
}
