/***************************************************************************
**
**  This file is part of gpcoord.
**
**  gpcoord 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.
**
**  gpcoord 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: 2009-06-19
**  Copyright: 2009-2019
**    Marc Wathelet
**    Marc Wathelet (LGIT, Grenoble, France)
**
***************************************************************************/

#include <QGpCoreTools.h>

#include "gpcoordVersion.h"
#include "gpcoordInstallPath.h"
#include "CoordReader.h"

PACKAGE_INFO("gpcoord", GPCOORD)

ApplicationHelp * help();

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

  // Options
  CoordReader reader;
  if(reader.setOptions(argc, argv) &&
     (!reader.hasInput() || reader.read(argc, argv)) &&
     reader.terminate()) {
    return 0;
  } else {
    return 2;
  }
}

ApplicationHelp * help()
{
  TRACE;
  ApplicationHelp * h=new ApplicationHelp;
  h->setOptionSummary( "[OPTIONS] [FILES]" );
  h->setComments( "Operation on coordinates X Y[ Z [NAME]] given through FILES or stdin. If Z is omitted, Z=0." );
  h->addGroup("gpcoord", "gpcoord");
  h->addOption("-distance","Input must be X1 Y1 [Z1] X2 Y2 [Z2]. Output is in meters.");
  h->addOption("-distance-lookup FILE","Input must be NAME1 NAME2 [REF_DIST]. Output is in meters. If REF_DIST is provided the "
                                       "computed distance is compared to REF_DIST (output: name1 name2 calc ref diff_abs diff_rel(%)). "
                                       "See option '-lookup' for FILE format.");
  h->addOption("-distance-geo","Input must be LONG1 LAT1 [Z1] LONG2 LAT2 [Z2]. Output is in meters.");
  h->addOption("-all-distances FILE","Input must be X1 Y1 [Z1]. Output is in meters. "
                                     "See option '-lookup' for FILE format.");
  h->addOption("-azimuth","Input must be X1 Y1 [Z1] X2 Y2 [Z2]. Output is in degrees from north (Y axis).");
  h->addOption("-azimuth-geo","Input must be LONG1 LAT1 [Z1] LONG2 LAT2 [Z2]. Output is in degrees from north.");
  h->addOption("-from-geo","Input must be LONG LAT [Z [NAME]] in degrees (Z in meters). Output in rectangular coordinates X Y Z (m). "
                           "Option -reference must be supplied.");
  h->addOption("-to-geo","Input must be X Y [Z [NAME]] in meters. Output geographical coordinates LONG LAT Z in degrees. "
                         "Option -reference must be supplied.");
  h->addOption("-to-utm [ZONE]","Input must be LONG LAT [Z [NAME]] in degrees. If ZONE is omitted, the UTM is automatically computed. "
               "Output Universal Transverse Mercator coordinates UTM_ZONE UTM_LONG UTM_LAT Z in meters.");
  h->addOption("-from-utm [ZONE]","Input must be [UTM_ZONE] UTM_LONG UTM_LAT [Z [NAME]] in degrees. If UTM_ZONE is not available, "
                                  "it must be specified in the argument. Output geographical coordinates LONG LAT Z in degrees.");
  h->addOption("-utm-declination", "Input must be LONG LAT [Z [NAME]] in degrees. It returns the angle between UTM north and "
                                   "geographical north for input location with the same conventions as magnetic declination. "
                                   "(Magnetic-UTM) is the magnetic north in UTM coordinates.");
  h->addOption("-mag-declination YY MM DD", "Calculate magnetic declination at input location. "
                                            "Input  must be LONG LAT [Z [NAME]] in degrees. wget is used to access "
                                            "https://www.ngdc.noaa.gov/geomag-web/#declination");
  h->addOption("-from-dms","Input must be LONG LAT [Z [NAME]] in degrees, minutes, seconds (format: D.MMSSss..., Z in meters). "
                           "Output is LONG LAT Z in degrees.");
  h->addOption("-to-dms","Input must be LONG LAT [Z [NAME]] in degrees. Output geographical coordinates LONG LAT Z in degrees, "
                         "minutes, seconds (D.MMSSss..., Z in meters).");
  h->addOption("-from-dm","Input must be LONG LAT [Z [NAME]] in degrees, minutes (format: D.MMmm..., Z in meters). "
                           "Output is LONG LAT Z in degrees.");
  h->addOption("-to-dm","Input must be LONG LAT [Z [NAME]] in degrees. Output geographical coordinates LONG LAT Z in degrees, "
                         "minutes (D.MMmm..., Z in meters).");
  h->addOption("-to-kml FILE","Input must be LONG LAT [Z [NAME]] in degrees. Output to KML FILE.");
  h->addOption("-from-kml FILE","Output is LONG LAT Z NAME in degrees.");
  h->addOption("-reference LONG LAT","Set geographical coordinates at origin of rectangular coordinates (0,0).");
  h->addOption("-translate TX TY","Input must be X Y [Z [NAME]]. Translates by vection (TX,TY).");
  h->addOption("-rotate ANGLE","Input must be X Y [Z [NAME]]. Rotates around origin (0,0) counterclockwize with ANGLE in degrees.");
  h->addOption("-average","Input must be X Y [Z] from a fixed station. Output X Y [Z]. Coordinates can be lat/long or "
                          "cartesian.");
  h->addOption("-lookup FILE","Return the coordinates of points referenced by their names. "
                              "Input must be NAME. Output X Y [Z] NAME. FILE must contains "
                              "points with format X Y Z NAME");
  h->addOption("-localize X Y","Input must be DISTANCE AZIMUTH from reference point X Y. Output are X Y of points shifted from "
                               "reference point by DISTANCE and AZIMUTH. X Y are the rectangular coordinates of the reference point");
  h->addOption("-trig-dist FILE","Triangulate from known distances to at least two reference points. "
                                 "Input must be NAME DISTANCE. Output X Y DX DY. FILE must contains the "
                                 "reference points with format X Y [Z] NAME");
  h->addOption("-trig-az FILE","Triangulate from known azimuth to at least three reference points. "
                               "Input must be NAME AZIMUTH. Output X Y DX DY. FILE must contains the "
                               "reference points with format X Y [Z] NAME");
  h->addOption("-from-distances","Input must be NAME1 NAME2 DISTANCE. Output are X Y of named points (see -origin and -north).");
  h->addOption("-circle RADIUS N [I0]","Generate a set of N coordinates distributed on a circle of RADIUS, plus a center at 0 0. "
               "Coordinates are named starting at index I0 (0 by default).");
  h->addOption("-array-limits", "Computes Kmin and Kmax for the input coordinates X Y [Z NAME].");
  h->addOption("-no-progress","Hides progress information through terminal");
  h->addGroup("from distance", "fromdistance");
  h->addOption("-stddev VALUE","The estimated standard deviation of distance measurements (default=1cm).");
  h->addOption("-origin NAME","Sets point named NAME as the origin of the relative coordinates, solves translation ambiguity (see -from-distances).");
  h->addOption("-north NAME","Defines the north axis (or Y) as the segment from origin to point NAME, solves rotation ambiguity (see -from-distances).");
  h->addOption("-eastward NAME","Sets that point NAME is located eastward compared to origin, solves flip ambiguity (see -from-distances).");
  h->addOption("-prior-positions FILE","Sets prior coordinates of points. All solutions that fall outside the prior precision are discarded.");
  h->addOption("-prior-precision VALUE","Sets precision of prior localizations (see -prior-positions, default=5m).");
  h->addOption("-posterior-precision VALUE","Sets precision of posterior localizations (default=0.05m).");
  h->addOption("-cluster-count N", "Aggregate robust quads using N random combinations (default=500).");
  h->addOption("-out MODE","Sets output mode: none, mean, raw, ellipse, clusters (default=mean). Several modes can be combined.");
  return h;
}
