/*

  Astrometry

  Copyright © 2010 - 2018 F.Hroch (hroch@physics.muni.cz)

  This file is part of Munipack.

  Munipack 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.

  Munipack 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 Munipack.  If not, see <http://www.gnu.org/licenses/>.

  1. create list to match:
     * projection from catalogue
     * photometry of ref
  2. for every image:
     * photometry
     * match
     * astrometry


   TODO:

     * print default parameters (in help ?)

*/

#include "munipack.h"
#include "vocatconf.h"
#include <wx/wx.h>
#include <wx/tokenzr.h>

bool Munipack::astrometry(MuniProcess *action, MuniCmdLineParser& cmd)
{

  CommonOutputMultiple(action,cmd);

  if( cmd.Found("show-defaults") ) {
    action->Write("MODE = 'DEFAULTS'");
    return true;
  }

  if( cmd.Found("remove") ) {
    action->Write("MODE = 'REMOVE'");
  }

  else {

    wxString a, cone = "cone.fits";
    double x,y;
    long i;
    size_t nseq = 0;
    bool mancal = false;

    if( cmd.Found("m",&a) || cmd.Found("mode",&a) ) {
      a = a.Upper();
      action->Write("MODE = '" + a + "'");
      mancal = a == "MANUAL";
    }

    // PROJ ** must ** precede both REF and CAT
    if( cmd.Found("p",&a) || cmd.Found("projection",&a) )
      action->Write("PROJECTION = '" + a.Upper() + "'");

    if( cmd.Found("fit",&a) )
      action->Write("FIT = '" + a.Upper() + "'");

    if( cmd.Found("xcen",&x) && cmd.Found("ycen",&y) )
      action->Write("CRPIX = %20.15f %20.15f",x,y);

    if( cmd.Found("rcen",&x) && cmd.Found("dcen",&y) )
      action->Write("CRVAL = %20.15f %20.15f",x,y);

    if( cmd.Found("scale",&x) )
      action->Write("SCALE = %25.15e",x);

    if( cmd.Found("angle",&x) )
      action->Write("ANGLE = %20.15f",x);

    if( cmd.Found("reflex") )
      action->Write("REFLEX = T");

    if( cmd.Found("rms",&x) )
      action->Write("RMS = %e",x);

    if( cmd.Found("sig",&x) )
      action->Write("SIG = %e",x);

    if( cmd.Found("sigcat",&x) )
      action->Write("SIGCAT = %e",x);

    if( cmd.Found("fsig",&x) )
      action->Write("FSIG = %e",x);

    if( cmd.Found("units",&a) && ( a == "uas" || a == "mas" || a == "arcsec" ||
				   a == "arcmin" || a == "deg") )
      action->Write("AUNITS = '" + a.Lower() + "'");

    if( cmd.Found("rcen",&x) ||  cmd.Found("dcen",&x) ||
	cmd.Found("scale",&x) || cmd.Found("angle",&x) )
      action->Write("INITPAR = F");

    if( cmd.Found("minmatch",&i) )
      action->Write("MINMATCH = %ld",i);

    if( cmd.Found("maxmatch",&i) )
      action->Write("MAXMATCH = %ld",i);

    if( cmd.Found("luckymatch",&i) )
      action->Write("LUCKYMATCH = %ld",i);

    if( cmd.Found("disable-lucky-match") )
      action->Write("LUCKYMATCH = 0");

    if( cmd.Found("enable-full-match") )
      action->Write("FULLMATCH = T");

    if( cmd.Found("disable-flux-check") )
      action->Write("FLUXCHECK = F");

    if( cmd.Found("disable-rms-check") )
      action->Write("RMSCHECK = F");

    if( cmd.Found("disable-save") )
      action->Write("WCSSAVE = F");

    if( cmd.Found("r",&a) || cmd.Found("ref",&a) ) {
      action->Write("REF = '" + a + "'");
      cone = "";
    }

    if( cmd.Found("R",&a) || cmd.Found("rel",&a) ) {
      action->Write("REL = '" + a + "'");
      cone = "";
    }

    if( cmd.Found("c",&a) || cmd.Found("cat",&a) ) {
      cone = a;
    }

    if( cone != "" && ! mancal) {

      VOCatConf catalogs;
      VOCatResources cat(catalogs.GetCatFits(cone));

      if( cmd.Found("col-ra",&a) )
	action->Write("COL_RA = '" + a + "'");
      else if( cat.IsOk() )
	action->Write("COL_RA = '" + cat.GetLabel("POS_EQ_RA") + "'");

      if( cmd.Found("col-dec",&a) )
	action->Write("COL_DEC = '" + a + "'");
      else if( cat.IsOk() )
	action->Write("COL_DEC = '" + cat.GetLabel("POS_EQ_DEC") + "'");

      if( cmd.Found("col-pm-ra",&a) )
	action->Write("COL_PMRA = '" + a + "'");
      else if( cat.IsOk() )
	action->Write("COL_PMRA = '" + cat.GetLabel("POS_EQ_PMRA") + "'");

      if( cmd.Found("col-pm-dec",&a) )
	action->Write("COL_PMDEC = '" + a + "'");
      else if( cat.IsOk() )
	action->Write("COL_PMDEC = '" + cat.GetLabel("POS_EQ_PMDEC") + "'");

      if( cmd.Found("col-mag",&a) )
	action->Write("COL_MAG = '" + a + "'");
      else if( cat.IsOk() )
	action->Write("COL_MAG = '" + cat.GetSort() + "'");

      action->Write("CAT = '" + cone + "'");
    }

    if( cmd.Found("seq1",&a) ) {
      wxStringTokenizer t(a,",");
      if( nseq == 0 ) {
	nseq = t.CountTokens();
	action->Write("NSEQ = %ld",nseq);
      }
      if( nseq != t.CountTokens() )
	wxLogFatalError("Specified sequences are unequal in length.");

      action->Write("SEQ1 = '" + a + "'");
    }

    if( cmd.Found("seq2",&a) ) {
      wxStringTokenizer t(a,",");
      if( nseq == 0 ) {
	nseq = t.CountTokens();
	action->Write("NSEQ = %ld",nseq);
      }
      if( nseq != t.CountTokens() )
	wxLogFatalError("Specified sequences are unequal in length.");

      action->Write("SEQ2 = '" + a + "'");
    }

  }

  WriteFiles(action,cmd);

  return true;


  // catalogue or image ?
  // if catalogue
  //     ra,dec -> vo (UCAC)
  // photometry
  // astrometry



  // catalogue or image ?
  // if catalogue
  //    ra,dec -> vo (UCAC) -> projection -> table
  // if image
  //    list table

  // for every image
  //    aperture photometry
  //    match to reference table
  //    if catalogue
  //       astrometry
}
