/***************************************************************************
**
**  This file is part of gpfksimulator.
**
**  gpfksimulator 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.
**
**  gpfksimulator 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-02-20
**  Copyright: 2010-2019
**    Marc Wathelet (ISTerre, Grenoble, France)
**
***************************************************************************/

#include <QGpGuiMath.h>
#include <SciFigs.h>

#include "Simulator.h"
#include "gpfksimulatorVersion.h"
#include "gpfksimulatorInstallPath.h"

PACKAGE_INFO("gpfksimulator", GPFKSIMULATOR)

ApplicationHelp * help();

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

  // Options
  QString stationFile;
  QString parserFile;
  QString sourceFile;
  QStringList scanSources;
  bool globalMax=false, crossSection=false;
  double sampling=5.0;
  // Check arguments
  int i, j=1;
  for(i=1; i<argc; i++) {
    QByteArray arg=argv[i];
    if(arg[0]=='-') {
      if(arg=="-p") {
        CoreApplication::checkOptionArg(i, argc, argv);
        parserFile=argv[i];
      } else if(arg=="-sources") {
          CoreApplication::checkOptionArg(i, argc, argv);
          sourceFile=argv[i];
      } else if(arg=="-scan") {
          CoreApplication::checkOptionArg(i, argc, argv);
          scanSources.append(argv[i]);
      } else if(arg=="-sampling") {
          CoreApplication::checkOptionArg(i, argc, argv);
          sampling=atof(argv[i]);
      } else if(arg=="-global-max") {
        globalMax=true;
      } else if(arg=="-cross-section") {
        crossSection=true;
      } else {
        App::log(tr("gpfksimulator: bad option %1, see -help\n").arg(argv[i]) );
        return 2;
      }
    } else {
      argv[j++]=argv[i];
    }
  }
  if(j<argc) {
    argv[j]=nullptr;
    argc=j;
  }
  if(argc>1) {
    stationFile=argv[1];
  }

  // Load station coordinates
  QList<NamedPoint> points;
  if(stationFile.isEmpty() || parserFile.isEmpty()) {
    CoordinateFileWidget cf;
    if(cf.read(stationFile)) {
      points=cf.points();
      QFileInfo fi(cf.fileName());
      stationFile=fi.fileName();
    } else {
      return 2;
    }
  } else {
    CoordinateFile cf;
    cf.setParserFile(parserFile);
    cf.setFile(stationFile);
    while(!cf.wait()) {}
    points=cf.points();
  }
  QVector<Point2D> stations;
  for(QList<NamedPoint>::iterator it=points.begin(); it!=points.end();it++) {
    stations.append(Point2D(*it));
  }
  if(stations.count()<2) {
    Message::critical(MSG_ID, tr("Loading coordinates"), tr("Less than 2 stations in your array"));
    return 2;
  }
  // Find gravity center of the array
  Point2D center;
  for(QVector<Point2D>::iterator it=stations.begin();it!=stations.end();it++) {
    center+=*it;
  }
  center.setX(center.x()/stations.count());
  center.setY(center.y()/stations.count());
  // Center the array around 0,0
  for(QVector<Point2D>::iterator it=stations.begin();it!=stations.end();it++) {
    (*it)-=center;
  }

  SciFigsGlobal s;
  Simulator * w=new Simulator;
  w->setWindowTitle(w->windowTitle()+" - "+stationFile);
  w->show();
  Settings::getWidget(w, "Simulator");
  w->init(stations, sampling);
  w->setGlobalMax(globalMax);
  w->setCrossSection(crossSection);
  if(!sourceFile.isEmpty()) {
    w->load(sourceFile);
  }
  int appReturn;
  if(!scanSources.isEmpty()) {
    w->scan(scanSources);
    appReturn=0;
  } else {
    appReturn=a.exec();
  }
  Settings::setWidget(w, "Simulator");
  delete w;
  return appReturn;
}

ApplicationHelp * help()
{
  TRACE;
  ApplicationHelp * h=new ApplicationHelp;
  h->setOptionSummary( "[OPTIONS] <STATIONS>" );
  h->setComments( "Educational tool for FK array response." );
  h->addGroup("gpfksimulator", "gpfksimulator");
  h->addOption("-p <PARSER_FILE>","Parser to read station file (default=graphical dialog box).");
  h->addOption("-sources <SOURCE_FILE>","Load a list of sources.");
  h->addOption("-scan <SOURCE_NAME>","Loop over azimuth and phase for source SOURCE_NAME. Several scan option can be specified.");
  h->addOption("-global-max","Only plot the global maximum (default=search for all maxima above 90% of the global maximum).");
  h->addOption("-cross-section","Output cross-section along X axis.");
  h->addOption("-sampling <S>","Number of pixels between two function estimates, can be a float (default=5).\n"
                               "The sampling is also used to control the coarse search step for maxima.");
  return h;
}
