/***************************************************************************
**
**  This file is part of gpviewdcreport.
**
**  gpviewdcreport 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.
**
**  gpviewdcreport 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: 2007-12-05
**  Copyright: 2007-2019
**    Marc Wathelet
**    Marc Wathelet (LGIT, Grenoble, France)
**
***************************************************************************/

#include <DinverCore.h>
#include <DinverDCCore.h>
#include <DinverDCGui.h>
#include <QGpCoreTools.h>
#include <QGpCoreWave.h>
#include <QGpGuiTools.h>
#include "gpviewdcreportVersion.h"
#include "gpviewdcreportInstallPath.h"

PACKAGE_INFO("gpviewdcreport", GPVIEWDCREPORT)

ApplicationHelp * help();

int main(int argc, char ** argv)
{
  Application a(argc, argv, help);
  SciFigsGlobal s;

  // Options
  enum PlotType {Profile, Dispersion, Ellipticity, Autocorr, RefraVp, RefraVs};
  PlotType plotType=Profile;
  bool skipDialog=false;
  int nGraphs=1;
  double maxMisfit=1.0;
  QString exportFile;
  QString exportFormat="PAGE";
  int dpi=0;  // No dpi force
  QString targetFile;
  Mode mode;
  // Check arguments
  int i, j=1;
  for(i=1; i<argc; i++) {
    QByteArray arg=argv[i];
    if(arg[0]=='-') {
      if(arg=="-profile") {
        plotType=Profile;
      } else if(arg=="-dispersion") {
        plotType=Dispersion;
      } else if(arg=="-ellipticity") {
        plotType=Ellipticity;
      } else if(arg=="-autocorr") {
        plotType=Autocorr;
      } else if(arg=="-refraVp") {
        plotType=RefraVp;
      } else if(arg=="-refraVs") {
        plotType=RefraVs;
      } else if(arg=="-m") {
        CoreApplication::checkOptionArg(i, argc, argv);
        maxMisfit=atof(argv[i]);
        skipDialog=true;
      } else if(arg=="-n") {
        CoreApplication::checkOptionArg(i, argc, argv);
        nGraphs=atoi(argv[i]);
        skipDialog=true;
      } else if(arg=="-s") {
        CoreApplication::checkOptionArg(i, argc, argv);
        mode.setSlowness(Mode::slowness(argv[i]));
        skipDialog=true;
      } else if(arg=="-p") {
        CoreApplication::checkOptionArg(i, argc, argv);
        mode.setPolarization(Mode::polarization(argv[i]));
        skipDialog=true;
      } else if(arg=="-target") {
        Application::checkOptionArg(i, argc, argv);
        targetFile=argv[i];
      } else if(arg=="-export" || arg=="-e") {
        Application::checkOptionArg(i, argc, argv);
        exportFile=argv[i];
      } else if(arg=="-format" || arg=="-f") {
        Application::checkOptionArg(i, argc, argv);
        exportFormat=argv[i];
      } else if(arg=="-dpi") {
        Application::checkOptionArg(i, argc, argv);
        dpi=atoi(argv[i]);
        if(dpi>1200) dpi=1200;
        else if(dpi<0) dpi=0;
      } else {
        App::log(tr("gpviewdcreport: bad option %1, see --help\n").arg(argv[i]) );
        return 2;
      }
    } else {
      argv[j++]=argv[i];
    }
  }
  if(j < argc) {
    argv[j]=nullptr;
    argc=j;
  }

  QStringList reportList;
  i=1;
  while(i<argc) {
    reportList.append(argv[i]);
    i++;
  }
  if(reportList.isEmpty()) {
    reportList=Message::getOpenFileNames(tr("View report files"),
                                            tr("Report file (*.report)"));
    if(reportList.isEmpty()) {
      App::log(tr("gpviewdcreport: no report files provided\n") );
      return 2;
    }
  }
  DCModelViewer * w;
  SAFE_UNINITIALIZED(w,nullptr)
  if(skipDialog) {
    switch(plotType) {
    case Profile:
      w=new GroundModelViewer;
      break;
    case Dispersion:
      w=new DispersionViewer;
      w->setMode(mode);
      break;
    case Ellipticity:
      w=new EllipticityViewer;
      break;
    case Autocorr:
      w=new AutocorrViewer;
      w->setMode(mode);
      w->setFrequencyAxis(true);
      break;
    case RefraVp:
      w=new RefractionVpViewer;
      break;
    case RefraVs:
      w=new RefractionVsViewer;
      break;
    }
    w->initGraphs(nGraphs);
    for(QStringList::iterator it=reportList.begin();it!=reportList.end();++it) {
      w->selectModels(*it, maxMisfit);
      QFileInfo fi(*it);
      w->setWindowTitle(w->windowTitle()+" "+fi.completeBaseName());
    }
    w->loadModels();
  } else {
    ViewerParam * d=new ViewerParam();
    switch(plotType) {
    case Profile:
      w=d->groundProfile(reportList);
      break;
    case Dispersion:
      w=d->dispersion(reportList);
      break;
    case Ellipticity:
      w=d->ellipticity(reportList);
      break;
    case Autocorr:
      w=d->autocorr(reportList);
      break;
    case RefraVp:
      w=d->refractionVp(reportList);
      break;
    case RefraVs:
      w=d->refractionVs(reportList);
      break;
    }
    delete d;
  }
  if(!w) return 2;
  if(!targetFile.isEmpty()) {
    TargetList * tl=new TargetList;
    XMLVirtualPlugin plugin(tl, "DispersionCurve");
    XMLDinverHeader hdr(&plugin);
    if(hdr.xml_restoreFile(targetFile)!=XMLClass::NoError) {
      delete w;
      delete tl;
      return 2;
    }
    w->setTarget(tl);
  }

  if( !exportFile.isEmpty()) {
    w->sheet()->exportFile(exportFile, exportFormat, dpi);
    delete w;
    return 0;
  } else if(skipDialog) {
    w->show();
  }

  int appReturn=a.exec();
  return appReturn;
}

ApplicationHelp * help()
{
  ApplicationHelp * h=new ApplicationHelp;
  h->setOptionSummary( "[OPTIONS] [FILE]..." );
  h->setComments( "Display ground profiles, dispersion curves, ellipticity curves, autocorrelation curves or refraction curves "
                  "read from .report files. It is strictly equivalent to the 'view' options in dinver graphical interface. "
                  "If options '-m', '-n' or other related options are specified the initial dialog box is skipped." );
  h->addGroup("gpviewdcreport", "gpviewdcreport");
  h->addOption("-profile", "Plot ground profiles (default)");
  h->addOption("-dispersion", "Plot dispersion curves");
  h->addOption("-ellipticity", "Plot ellipticity curves");
  h->addOption("-autocorr", "Plot autocorrelation curves");
  h->addOption("-refraVp", "Plot refraction curves for Vp");
  h->addOption("-refraVs", "Plot refraction curves for Vs");
  h->addOption("-m <MISFIT>","Maximum misfit to display");
  h->addOption("-target <TARGET>","Set target shown above models read from .report files.");
  h->addOption("-e, -export <FILE>", "Export sheet contents to FILE. See 'figue -h' for more details.");
  h->addOption("-f, -format <FORMAT>", "Specify format for option '-export'. See 'figue -h' for more details.");
  h->addOption("-dpi <DPI>", "Forces resolution to DPI(dot per inch) in export file. See 'figue -h' for more details.");
  h->addGroup("Profile","profile");
  h->addOption("-n <N>", "Number of profiles");
  h->addGroup("Dispersion","dispersion");
  h->addOption("-n <N>", "Number of modes");
  h->addOption("-s <SLOWNESS>", "Slowness type: Group or Phase");
  h->addOption("-p <POLARISATION>", "Polarization: Rayleigh or Love");
  h->addGroup("Ellipticity","ellipticity");
  h->addOption("-n <N>", "Number of modes");
  h->addGroup("Autocorr","autocorr");
  h->addOption("-n <N>", "Number of rigns");
  h->addOption("-p <POLARISATION>", "Polarization: Vertical, Transverse or Radial");
  h->addGroup("Refra","refra");
  h->addOption("-n <N>", "Number of sources");
  return h;
}
