/* 
 * smeg - A satellite modelling and prediction tool
 * Copyright (C) 1999  Tom Rothamel
 * 
 * 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; see the file COPYING.  If not, write to
 * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 * Boston, MA 02111-1307, USA.
 */

#ifndef STS2_H
#define STS2_H

#include <sys/types.h>
#include <regex.h>
#include <math.h>

extern "C" {
#include "sgp.h"
#include "vector.h"
}

#include "parsedate.h"
#include "list.h"

/* Universal (for Earth) Constants */

#define R (6378.135)              /* Earth's Radus, km */
#define SECDAY (1.0/86400.0)      /* One second, as a fraction of a day. */
#define ROTRATE ((2*M_PI/86400.0)*1.002737909350) /* Rate of earth's rotation,
						     radians. */
#define DEGRAD (M_PI/180.0)
#define RADEG (180.0/M_PI)

/* Output Filters (output.cc) */
extern FILE *out; /* Stream for results. */
extern int verbose;  /* Verbose output? */

void open_less();
void close_less();
void open_print();
void close_print();


/* Locatable (locatable.cc) */
struct LLA {
	double lat;
	double lon;
	double alt;
};

class Locatable {
 public:
	char *name;
	double x[3];
	double dx[3];
	double ct;
	
	virtual void calcpos(double) = 0;
	LLA *calclla();
};


/* Site Class (site.cc) */

class Site : public Locatable {
 public:
	double latr;
	double lonr;
	double alt;

	double sinlat;
	double coslat;

	Site(double, double, double);
	void calcpos(double);
};


class Astral : public Locatable {
 public:
	int norad;

	virtual int hasMagnitude() = 0;
	virtual double maxMagnitude() = 0;
	virtual double magnitude(Site *) = 0;
	
	virtual void calcpos(double) = 0;
};

/* Sat Class (sat_class.cc) */
class Sat : public Astral {
 public:
	SAT *s;

	Sat(SAT *);
	void calcpos(double);
	int hasMagnitude();
	double maxMagnitude();
	double magnitude(Site *);
};

/* The Sun */
extern Locatable *theSun;
void CreateSun();
void ShowSun();
int isLit(Locatable *, double);
double SiteSatSun(Locatable *s, Site *si, double t); /* returns radians. */


/* Azrael (locatable.cc) */

struct Azrael {
	double ct;
	double sx[3];
	double six[3];
	double sdx[3];
	double sidx[3];
	double ox[3];
	
	double righta;
	double dec;

	double az;
	double ra;
	double el;
	
	Azrael(Locatable *, Site *, double);
};
	
double Elevation(Locatable *, Site *, double);
void DebugLocation();

/* Pass Prediction (predict.cc) */

struct Pass {
	Sat *s;
	double max;
	double min0;
	double min1;

	int state;
};

/* Option Parsing (mostly opts.cc) */

typedef struct _context {
	Sat *sat;
	LLA *lla;
	Pass *pass;
	Site *site;
	double t;
} CONTEXT;

typedef struct _step {
	int (*op)(CONTEXT *, struct _step *);
	
	struct _step *s1;
	struct _step *s2;

	char con;

	double d;
	int i;
	char *str;
	regex_t reg;
	
	char *name;	
} STEP;

STEP *newSTEP(int(*)(CONTEXT *, STEP *), char con, char *);
STEP *newSTEPident(char *, char con);
int run(CONTEXT *c, STEP *s);

/* set.cc */
void Set(char *, char *);
void ShowLocation();

/* These are also used in options.y */
int op_and(CONTEXT *, STEP *);
int op_or(CONTEXT *, STEP *);
int op_true(CONTEXT *, STEP *);
int op_false(CONTEXT *, STEP *);

void NoradFilter();

/* Sat Class Functions (sat_class.cc) */

void LoadSats(FILE *);
void LoadSatsFromFile(char *);
void SatlistFilter(STEP *);
void SatlistUnfilter();
void ShowSatlist();
void CurrentPosition(STEP *);
void CurrentSatX();
void CurrentLook(STEP *);

/* Prediction functions (predict.cc) */

void FreePassList();
void Predict(double, double);
void ShowPasslist();
void PasslistFilter(STEP *);
void PasslistUnfilter();
void StepPasses(int time, STEP *);

/* Generic Utility (util.cc) */

char *CompassDir(double);
int strfsgptime(char *, int, char *, double);

/* Curses (curses.cc) */

void LiveSatlist();
void LivePasslist();

/* Parse (proc.cc) */
void DefProc(char *, char *);
void CallProc(char *);
void ParseString(char *);

#endif
