/***************************************************************************
**
**  This file is part of gppoisson.
**
**  gppoisson 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.
**
**  gppoisson 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-04-14
**  Copyright: 2006-2019
**    Marc Wathelet
**    Marc Wathelet (LGIT, Grenoble, France)
**
***************************************************************************/

#include <math.h>

#include <QGpCoreTools.h>
#include "gppoissonVersion.h"
#include "gppoissonInstallPath.h"

PACKAGE_INFO("gppoisson", GPPOISSON)

ApplicationHelp * help();

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

  // Options
  int mode=0;
  // Check arguments
  int i, j=1;
  for(i=1; i<argc; i++) {
    QByteArray arg=argv[i];
    if(arg[0]=='-') {
      if(arg=="-nu") {
        mode=0;
      } else if(arg=="-vp") {
        mode=1;
      } else if(arg=="-vs") {
        mode=2;
      } else {
        App::log(tr("gppoisson: bad option %1, see --help\n").arg(argv[i]) );
        return 2;
      }
    } else {
      argv[j++]=argv[i];
    }
  }
  if(j < argc) {
    argv[j]=nullptr;
    argc=j;
  }

  QTextStream sOut(stdout);
  LineParser p;
  bool ok=true;
  double vs, vp, nu;
  while(!feof(stdin)) {
    QString l=File::readLine(true);
    if(l=="exit" || l=="quit") break;
    if(!l.isEmpty() && l[0]!='#') {
      p.setString(l);
      switch (mode) {
      case 1:
        vs=p.toDouble(0, ok);
        nu=p.toDouble(1, ok);
        if( !ok) {
          App::log(tr("gppoisson: error reading Vs and Nu\n") );
          return 2;
        }
        sOut << vs*sqrt(2*(nu-1)/(2*nu-1)) << endl;
        break;
      case 2:
        vp=p.toDouble(0, ok);
        nu=p.toDouble(1, ok);
        if( !ok) {
          App::log(tr("gppoisson: error reading Vp and Nu\n") );
          return 2;
        }
        sOut << vp*sqrt(0.5*(2*nu-1)/(nu-1)) << endl;
        break;
      default:
        vp=p.toDouble(0, ok);
        vs=p.toDouble(1, ok);
        vp *= vp;
        vs *= vs;
        if( !ok) {
          App::log(tr("gppoisson: error reading Vp and Vs\n") );
          return 2;
        }
        sOut << (vs-0.5*vp)/(vs-vp) << endl;
        break;
      }
    }
  }
  return 0;
}

ApplicationHelp * help()
{
  ApplicationHelp * h=new ApplicationHelp;
  h->setOptionSummary( "[OPTIONS] [-nu|-vp|-vs]" );
  h->setComments( "Compute Poisson's ratios from Vs and Vp, and vice-versa. It accepts two parameters per line on the stdin. The "
                 "nature of the parameters depends on the option -nu, -vp, or -vs\n\n"
                 "  nu=(vs^2-0.5*vp^2)/(vs^2-vp^2) (velocity)\n"
                 "  nu=(sp^2-0.5*ss^2)/(sp^2-ss^2) (slowness)\n"
                 "  vp=vs*sqrt(2*(nu-1)/(2*nu-1))\n"
                 "  vs=vp*sqrt(0.5*(2*nu-1)/(nu-1))");
  h->addGroup("Gppoisson","gppoisson");
  h->addOption("-nu (default)","param1 is Vp, param2 is Vs, output is Poisson'ratio");
  h->addOption("-vp","param1 is Vs, param2 is Poisson'ratio, output is Vp");
  h->addOption("-vs","param1 is Vp, param2 is Poisson'ratio, output is Vs");
  h->addExample( "echo 500 200 | gppoisson", "Ouput 0.4, Poisson's ratio for Vp=500 m/s and Vs=200 m/s.");
  return h;
}

