// sattool - visual satellite tracking and prediction tool.
// Copyright 2000 Tom Rothamel <tom-idbg@onegeek.org>
//
// This program 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 2 of the License, or
// (at your option) any later version.
//
// This program 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 this program; if not, write to the Free Software
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  

#include "sattool.h"
#include <stdlib.h>

// This is the function used to sort the list of passes by time.
int sortpass(Thing **t1, Thing **t2) {
	Pass *p1;
	Pass *p2;

	p1 = (Pass *) *t1;
	p2 = (Pass *) *t2;

	if (p1->min0 < p2->min0) return -1;
	if (p1->min0 == p2->min0) return 0;
	return 1;
}

// This implements the predict command.
int predict(int argc, char **argv) {
	Options *o;
	List *l;
	List *nl;
	List *nnl;
	Thing *t;
	Sat *s;
	Object *site;
	Pass *p;
		
	int optoff; 	
	int nargs;

	double start;
	double end;
	double minelev = 0;
	double step = 10;	

	int count = 0;
	
	o = ParseGlobalOptions(argc, argv, &optoff);

	if (o->visual) minelev = 10;

	if (getenv("SATMINELEV"))
		minelev = atof(getenv("SATMINELEV"));
	if (getenv("SATPREDICTSTEP"))
		step = atof(getenv("SATPREDICTSTEP"));
	
	nargs = argc - optoff;

	if (nargs == 0) {
		error("predict requires argument.\n");
		return -1;
	}
		
	if (nargs == 1) {
		start = sgp_now();
		end = parse_sgp_date(argv[optoff]);
	}

	if (nargs >= 2) {
		start = parse_sgp_date(argv[optoff]);
		end = parse_sgp_date(argv[optoff+1]);
	}

	if (nargs >= 3) 
		minelev = atof(argv[optoff+2]);

	if (nargs >= 4)
		step = atof(argv[optoff+3]);
	
	if (start == HUGE_VAL) {
		error("predict start time invalid.\n");
		return -1;
	}

	if (end == HUGE_VAL) {
		error("predict end time invalid.\n");
		return -1;
	}

	if (end < start) {
		error("predict end time before start time.\n");
		return -1;
	}

	if (o->debug) {
		fprintf(stderr, "Predicting from %f to %f. (minelev %f, step %f)\n",
			start, end, minelev, step);
	}
		
	l = ReadInput(o);
	site = GetSite();
	if (!site) return -1;

	nl = new List;
	

	// Predict each satellite. 
	while (t = l->next()) {
		s = getSat(t);
		if (!s) continue;                  		

		if (!o->quiet) {
			if (! (count++ % 25)) {
				fprintf(stderr, "\rPredicting %d of %d. (%d found.)",
					count, l->count, nl->count);
			}
		}

		PredictSat(nl, s, site, start, end, minelev, step);
		
	}

	// Sort the passlist.
	if (!o->quiet) {
		fprintf(stderr, "\rDone predicting %d satellites. (%d passes found.)\n",
			count, nl->count);		

		fprintf(stderr, "Sorting pass list... ");
	}

       
	nnl = SortList(nl, sortpass);
	delete nl;
	nl = nnl;

	if (!o->quiet) 
		fprintf(stderr, "Done.\n");


	// If visual mode, find minimum magnitudes.
	if (o->visual) {
		if (!o->quiet)
			fprintf(stderr, "Finding minimum magnitudes... ");
		while (t = nl->next()) {
			p = getPass(t);
			p->visual(step);
		}
		if (!o->quiet)
			fprintf(stderr, "Done.\n");
	}
	
	WriteOutput(o, nl);

	delete l;
	delete nl;
	delete o;
	
	return 0;		
}
