/*
  This file is part of the Astrometry.net suite.
  Copyright 2009 Dustin Lang.

  The Astrometry.net suite 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, version 2.

  The Astrometry.net suite 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 the Astrometry.net suite ; if not, write to the Free Software
  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
*/

#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include <string.h>

#include "uniformize-catalog.h"
#include "fitstable.h"
#include "boilerplate.h"
#include "errors.h"
#include "log.h"
#include "fitsioutils.h"

const char* OPTIONS = "hvH:s:n:N:d:R:D:S:fm:";

void printHelp(char* progname) {
	boilerplate_help_header(stdout);
	printf("\nUsage: %s [options] <input-FITS-catalog> <output-FITS-catalog>\n"
		   "    [-R <ra-column-name>]: name of RA in FITS table (default RA)\n"
		   "    [-D <dec-column-name>]: name of DEC in FITS table (default DEC)\n"
		   "    [-S <sort-column-name>]: column on which to sort\n"
		   "    [-f]: sort in descending order (eg, for FLUX); default ascending (eg, for MAG)\n"
		   "    [-H <big healpix>]; default is all-sky\n"
           "    [-s <big healpix Nside>]; default is 1\n"
		   "    [-m <margin>]: add a margin of <margin> healpixels; default 0\n"
		   "    [-n <sweeps>]    (ie, number of stars per fine healpix grid cell); default 10\n"
		   "    [-N <nside>]:   fine healpixelization grid; default 100.\n"
		   "    [-d <dedup-radius>]: deduplication radius in arcseconds; default no deduplication\n"
		   "    [-v]: +verbose\n"
		   "\n", progname);
}

extern char *optarg;
extern int optind, opterr, optopt;

int main(int argc, char *argv[]) {
    int argchar;
	char* progname = argv[0];
	char* infn = NULL;
	char* outfn = NULL;
	char* racol = NULL;
	char* deccol = NULL;
	char* sortcol = NULL;
	anbool sortasc = TRUE;
	int loglvl = LOG_MSG;
	int bighp = -1;
	int bignside = 1;
	int sweeps = 10;
	int Nside = 100;
	double dedup = 0.0;
	int margin = 0;
	double mincut = -HUGE_VAL;
	
	fitstable_t* intable;
	fitstable_t* outtable;

	char** myargs;
	int nmyargs;

    while ((argchar = getopt (argc, argv, OPTIONS)) != -1)
        switch (argchar) {
		case 'R':
			racol = optarg;
			break;
		case 'D':
			deccol = optarg;
			break;
		case 'S':
			sortcol = optarg;
			break;
		case 'f':
			sortasc = FALSE;
			break;
		case 'H':
			bighp = atoi(optarg);
			break;
		case 's':
			bignside = atoi(optarg);
			break;
		case 'n':
			sweeps = atoi(optarg);
			break;
		case 'N':
			Nside = atoi(optarg);
			break;
		case 'd':
			dedup = atof(optarg);
			break;
		case 'm':
			margin = atoi(optarg);
			break;
		case 'v':
			loglvl++;
			break;
        case '?':
            fprintf(stderr, "Unknown option `-%c'.\n", optopt);
        case 'h':
			printHelp(progname);
            return 0;
        default:
            return -1;
        }

	nmyargs = argc - optind;
	myargs = argv + optind;

	if (nmyargs != 2) {
		printHelp(progname);
		exit(-1);
	}
	log_init(loglvl);
	fits_use_error_system();

	infn = myargs[0];
	outfn = myargs[1];

	logmsg("Reading catalog from %s, writing to %s\n", infn, outfn);

	logmsg("Reading %s...\n", infn);
	intable = fitstable_open(infn);
    if (!intable) {
        ERROR("Couldn't read catalog %s", infn);
        exit(-1);
    }
	logmsg("Got %i stars\n", fitstable_nrows(intable));

	outtable = fitstable_open_for_writing(outfn);
	if (!outtable) {
		ERROR("Failed to open output table %s", outfn);
		exit(-1);
	}
	/*
	 if (fitstable_write_primary_header(outtable)) {
	 ERROR("Failed to write primary header");
	 exit(-1);
	 }
	 */
	if (uniformize_catalog(intable, outtable, racol, deccol,
						   sortcol, sortasc, mincut,
						   bighp, bignside, margin,
						   Nside, dedup, sweeps,
						   argv, argc)) {
		exit(-1);
	}

	if (fitstable_fix_primary_header(outtable) ||
		fitstable_close(outtable)) {
		ERROR("Failed to close output table");
		exit(-1);
	}

	fitstable_close(intable);
    return 0;
}


