// 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 <unistd.h>
#define _GNU_SOURCE
#include <getopt.h>
#include <stdlib.h>

struct option long_opts[] = {
	{"infile", 1, 0, 'i'},
	{"outfile", 1, 0, 'o'},
	{"tle", 0, 0, 't'},
	{"quiet", 0, 0, 'q'},
	{"visual", 0, 0, 'v'},
	{"debug", 0, 0, 'd'}
};

void lexer_scan_string(char *);

// This tries to parse the SATSITE environment variable. It returns the
// first object in that list. (Which, for our purposes, we'll assume
// is a Site.) This function should only be called _after_ ReadInput, as
// it reuses the parser.
Object *GetSite() {
	List *l;
	Thing *t;
	Object *o;

	if (!getenv("SATSITE")) {
		error("SATSITE variable not set.\n");
		return NULL;
	}

	lexer_scan_string(getenv("SATSITE"));
	l = new List;

	yyparse((void *) l);

	if (!l->count) {
		error("Couldn't get site from SATSITE variable.\n");
		return NULL;
	}

	
	t = l->next();

	o = getObject(t);

	if (!o) { 
		error("Couldn't get site object from SATSITE variable.\n");
		return NULL;
	}	


	lock(o);
	delete l;
	
	return o;
}

// This uses getopt to create an Options structure. This options structure
// is used in other places in the code. 
Options *ParseGlobalOptions(int argc, char **argv, int *indopt) {
	int opt;
	Options *o;

	o = new Options;
	o->infile = NULL;
	o->outfile = NULL;
	o->tle = 0;
	o->quiet = 0;
	o->visual = 0;
	o->debug = 0;
	
	while ((opt = getopt_long(argc, argv, "i:o:tvqd",
				  long_opts, NULL)) != -1) {
		switch (opt) {
		case 'i':
			o->infile = optarg;
			break;
		case 'o':
			o->outfile = optarg;
			break;
		case 't':
			o->tle = 1;
			break;
		case 'q':
			o->quiet = 1;
			break;
		case 'v':
			o->visual = 1;
			break;			
		case 'd':
			o->debug = 1;
			break;
		}
	}

	if (indopt) {
		*indopt = optind;
	} else {
		if (optind < argc)
			warning("Extra arguments present on command line.\n");
	}

	return o;
}

// This uses the data given in the options structure to read in the
// input list. It uses the file given by the -i option, or stdin if
// it wasn't given. It will try to read the input as a tle file if the
// -t option was given, otherwise it calls the main parser to parse
// the input stream.
List *ReadInput(Options *o) {
	FILE *f;
	List *l;
	
	if (o->infile) {
		f = fopen(o->infile, "r");
		if (!f) {
			error("Couldn't open input file '%s'.\n", o->infile);
			return NULL;
		}
	} else {
		f = stdin;
	}

	if (o->tle) return ReadTLEFile(f);

	yyin = f;
	l = new List;

	yyparse((void *) l);	

	return l;
}

// This attempts to open the output file, based on the -o option given. If
// none was given, this gives standard output as the output file.
FILE *OutputFile(Options *o) {
	FILE *f;

	if (o->outfile) {
		f = fopen(o->outfile, "w");
		if (!f) {
			error("Couldn't open output file '%s'.", o->outfile);
			return NULL;
		}
	} else {
		f = stdout;
	}

	return f;
}

// This writes out the list to the file given by running OutputFile on
// the Options.
void WriteOutput(Options *o, List *l) {
	FILE *f;
	Thing *t;
	
	f = OutputFile(o);
	if (!f) return;

	l->reset();
	while (t = l->next()) {
		t->write(f, 0);
	}
}
