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

#include <DinverCore.h>
#include <QGpGuiTools.h>
#include "ViewerParam.h"
#include "GroundModelViewer.h"
#include "DispersionViewer.h"
#include "AutocorrViewer.h"
#include "EllipticityViewer.h"
#include "RefractionViewer.h"
#include "MagnetoTelluricViewer.h"

namespace DinverDCGui {

ViewerParam::ViewerParam(QWidget * parent)
    : Dialog(parent)
{
  TRACE;
  setupUi(this);
}

void ViewerParam::select(DCModelViewer * refW, const QVector<int> * indexes)
{
  TRACE;
  setWindowTitle(tr("Viewer for selected models"));
  removeMaxMisfit();
  if(exec()==QDialog::Accepted) {
    DCModelViewer * w=createViewer(viewer->currentIndex());
    w->selectModels(refW, indexes);
    w->setWindowTitle(w->windowTitle() + tr(" %1 selected models").arg(w->modelCount()));
    w->loadModels();
  }
}

void ViewerParam::reject(DCModelViewer * refW, const QVector<int> * indexes)
{
  TRACE;
  setWindowTitle(tr("Viewer for non-discarded models"));
  removeMaxMisfit();
  if(exec()==QDialog::Accepted) {
    DCModelViewer * w=createViewer(viewer->currentIndex());
    w->rejectModels(refW, indexes);
    w->setWindowTitle(w->windowTitle() + tr(" %1 non-discarded models").arg(w->modelCount()));
    w->loadModels();
  }
}

DCModelViewer * ViewerParam::setViewer(int index, QStringList reportFileNames)
{
  TRACE;
  // TODO study other structure without those remove
  switch (index) {
  case 0:
    maxNGraphsLabel->setText(tr("Maximum number of profiles"));
    setWindowTitle(tr("Ground profiles viewer"));
    maxNGraphs->setMaximum(5);
    maxNGraphs->setValue(2);
    removeOptions();
    break;
  case 1:
    maxNGraphsLabel->setText(tr("Maximum number of modes"));
    setWindowTitle(tr("Dispersion viewer"));
    maxNGraphs->setValue(1);
    setPolarizationRL();
    removeValue();
    removeModeIndex();
    removeAxis();
    break;
  case 2:
    maxNGraphsLabel->setText(tr("Maximum number of rings"));
    setWindowTitle(tr("Autocorrelation viewer"));
    maxNGraphs->setValue(5);
    setPolarizationVRT();
    removeValue();
    removeSlowness();
    break;
  case 3:
    maxNGraphsLabel->setText(tr("Maximum number of modes"));
    setWindowTitle(tr("Ellipticity viewer"));
    maxNGraphs->setValue(1);
    removeSlowness();
    removePolarization();
    removeModeIndex();
    break;
  case 4:
    maxNGraphsLabel->setText(tr("Maximum number of sources"));
    setWindowTitle(tr("Refraction Vp viewer"));
    maxNGraphs->setValue(2);
    removeOptions();
    break;
  case 5:
    maxNGraphsLabel->setText(tr("Maximum number of sources"));
    setWindowTitle(tr("Refraction Vs viewer"));
    maxNGraphs->setValue(2);
    removeOptions();
    break;
  case 6:
    setWindowTitle(tr("Magneto-telluric viewer"));
    maxNGraphs->setValue(2);
    maxNGraphs->hide();
    maxNGraphsLabel->hide();
    removeOptions();
    break;
  default:
    break;
  }
  delete viewer;
  viewer=nullptr;
  delete viewerLabel;
  viewerLabel=nullptr;
  if(exec()==QDialog::Accepted) {
    DCModelViewer * w=createViewer(index);
    for(QStringList::iterator it=reportFileNames.begin();it!=reportFileNames.end();++it) {
      w->selectModels(*it, maxMisfit->value());
      QFileInfo fi(*it);
      w->setWindowTitle(w->windowTitle()+" "+fi.completeBaseName());
    }
    w->loadModels();
    w->setLayerComments(reportFileNames);
    return w;
  }
  return nullptr;
}

DCModelViewer * ViewerParam::createViewer(int index)
{
  TRACE;
  DCModelViewer * w;
  switch (index) {
  case 1:
    w=new DispersionViewer;
    w->setMode(mode());
    break;
  case 2:
    w=new AutocorrViewer;
    w->setMode(mode());
    w->setFrequencyAxis(xAxis->currentIndex()==0);
    break;
  case 3:
    w=new EllipticityViewer;
    w->setMode(mode());
    break;
  case 4:
    w=new RefractionVpViewer;
    break;
  case 5:
    w=new RefractionVsViewer;
    break;
  case 6:
    w=new MagnetoTelluricViewer;
    break;
  default:
    w=new GroundModelViewer;
    break;
  }
  w->initGraphs(maxNGraphs->value());
  if(DinverCoreEngine::instance()) {
    DinverCoreEngine::instance()->addSubWindow(this, w);
  } else {
    w->show();
  }
  return w;
}

void ViewerParam::on_viewer_currentIndexChanged(int)
{
  TRACE;
  if(!viewer) return;
  switch (viewer->currentIndex()) {
  case 0:
    maxNGraphsLabel->setText(tr("Maximum number of profiles"));
    setOptionsEnabled(false);
    setAxisEnabled(false);
    break;
  case 1:
    maxNGraphsLabel->setText(tr("Maximum number of modes"));
    setOptionsEnabled(true);
    setValueEnabled(false);
    setSlownessEnabled (true);
    setPolarizationRL();
    setModeIndexEnabled (false);
    setAxisEnabled(false);
    break;
  case 2:
    maxNGraphsLabel->setText(tr("Maximum number of rings"));
    setOptionsEnabled(true);
    setValueEnabled(false);
    setSlownessEnabled(false);
    setPolarizationVRT();
    setModeIndexEnabled (true);
    setAxisEnabled(true);
    break;
  case 3:
    maxNGraphsLabel->setText(tr("Maximum number of modes"));
    setOptionsEnabled(true);
    setValueEnabled(true);
    setSlownessEnabled(false);
    setAxisEnabled(false);
    break;
  default:
    break;
  }
}

void ViewerParam::removeMaxMisfit()
{
  TRACE;
  delete maxMisfit;
  maxMisfit=nullptr;
  delete maxMisfitLabel;
  maxMisfitLabel=nullptr;
}

void ViewerParam::removeOptions()
{
  TRACE;
  delete optionGroup;
  optionGroup=nullptr;

  value=nullptr;
  valueLabel=nullptr;
  slowness=nullptr;
  slownessLabel=nullptr;
  polarization=nullptr;
  polarizationLabel=nullptr;
  modeIndex=nullptr;
  modeIndexLabel=nullptr;
  xAxis=nullptr;
  xAxisLabel=nullptr;
}

void ViewerParam::removeValue()
{
  TRACE;
  delete value;
  value=nullptr;
  delete valueLabel;
  valueLabel=nullptr;
}

void ViewerParam::removeSlowness()
{
  TRACE;
  delete slowness;
  slowness=nullptr;
  delete slownessLabel;
  slownessLabel=nullptr;
}

void ViewerParam::removePolarization()
{
  TRACE;
  delete polarization;
  polarization=nullptr;
  delete polarizationLabel;
  polarizationLabel=nullptr;
}

void ViewerParam::removeModeIndex()
{
  TRACE;
  delete modeIndex;
  modeIndex=nullptr;
  delete modeIndexLabel;
  modeIndexLabel=nullptr;
}

void ViewerParam::removeAxis()
{
  TRACE;
  delete xAxis;
  xAxis=nullptr;
  delete xAxisLabel;
  xAxisLabel=nullptr;
}

void ViewerParam::setOptionsEnabled(bool e)
{
  TRACE;
  optionGroup->setEnabled(e);
}

void ViewerParam::setValueEnabled(bool e)
{
  TRACE;
  value->setEnabled(e);
  valueLabel->setEnabled(e);
}

void ViewerParam::setSlownessEnabled(bool e)
{
  TRACE;
  slowness->setEnabled(e);
  slownessLabel->setEnabled(e);
}

void ViewerParam::setModeIndexEnabled(bool e)
{
  TRACE;
  modeIndex->setEnabled(e);
  modeIndexLabel->setEnabled(e);
}

void ViewerParam::setPolarizationRL()
{
  TRACE;
  int p=polarization->currentIndex();
  if(p>=2) p=0;
  polarization->clear();
  polarization->addItem(tr("Rayleigh"));
  polarization->addItem(tr("Love"));
  polarization->setCurrentIndex(p);
}

void ViewerParam::setPolarizationVRT()
{
  TRACE;
  int p=polarization->currentIndex();
  if(p>=3) p=0;
  polarization->clear();
  polarization->addItem(tr("Vertical"));
  polarization->addItem(tr("Radial"));
  polarization->addItem(tr("Transverse"));
  polarization->setCurrentIndex(p);
}

void ViewerParam::setAxisEnabled(bool e)
{
  TRACE;
  xAxis->setEnabled(e);
  xAxisLabel->setEnabled(e);
}

int ViewerParam::exec()
{
  TRACE;
  Settings::getWidget(this, windowTitle());
  on_viewer_currentIndexChanged(0);
  if(QDialog::exec()==QDialog::Accepted) {
    Settings::setWidget(this, windowTitle());
    return QDialog::Accepted;
  } else {
    return QDialog::Rejected;
  }
}

Mode ViewerParam::mode() const
{
  TRACE;
  Mode m;
  if(optionGroup) {
    if(!value || value->currentIndex()==0) {
      m.setValue(Mode::Signed);
    } else {
      m.setValue(Mode::Absolute);
    }
    if(!slowness || slowness->currentIndex()==0) {
      m.setSlowness(Mode::Phase);
    } else {
      m.setSlowness(Mode::Group);
    }
    if(polarization) {
      if(polarization->count()==2) {
        if(polarization->currentIndex()==0)
          m.setPolarization(Mode::Rayleigh);
        else
          m.setPolarization(Mode::Love);
      } else {
        switch (polarization->currentIndex()) {
        case 1:
          m.setPolarization(Mode::Radial); break;
        case 2:
          m.setPolarization(Mode::Transverse); break;
        default:
          m.setPolarization(Mode::Vertical); break;
        }
      }
    } else {
      m.setPolarization(Mode::Rayleigh);
    }
    if(modeIndex) {
      m.setIndex(modeIndex->value());
    } else {
      m.setIndex(0);
    }
    m.setRingIndex(0);
  }
  return m;
}

} // namespace DinverDCGui
