/* main.c - TAZEL Main Program File */

#include	"tazel.h"
#include	"sgp-c-lib.mod/sgp.h"

/************************************************************************************************/
// This is a TAZEL main() function.
/************************************************************************************************/
int main(int argc,char *argv[]){

FILE	*fp;							/* File Pointer to TLE-Data File						*/

tle_t	tle,tle2;						/* TLE-Data Record						( Curr & Next )	*/
sat_t	sat;							/* Satellite-Data Record								*/
obs_t	obs;							/* Observer -Data Record (Lon,Lat,Alt,Theta)			*/

char	buf_datetime[BUFSIZ];			/* Date & Time               String Buffer				*/
char	buf_satcname[BUFSIZ];			/* Satellite Concise Name    String Buffer				*/
char	buf_tleepoch[BUFSIZ];			/* TLE-Epoch ( Date & Time ) String Buffer				*/

struct tm	tm_epoc,tm_epoc2;			/* TLE-Epoch Date & Time [UTC]			( Curr & Next )	*/
struct tm	tm_init;					/* Initial   Date & Time [UTC]							*/
struct tm	tm_curr;					/* Current   Date & Time [UTC]							*/

time_t	t_abs,t_abs2;					/* TIME Since 1970-01-01 00:00:00 [sec]	( Curr & Next )	*/
time_t	t_off;							/* LTZ - UTC                      [sec]					*/
dbl		msec,msec2;						/* TIME less than 1.0 [msec]			( Curr & Next )	*/

char	*p_gname,*p_fname;				/* ARGs: Gound Location Name / TLE-Data File Name		*/
char	*p_date,*p_time,*p_looptick;	/* ARGs: YYYY-MM-DD / hh:mm:ss / LoopTick				*/

int		flag_tledump=FALSE;				/* Flag for TLE-Data Dump (T/F)							*/
int		flag_exemode='P';				/* Flag for Exec Mode ('P'arallel/'S'erial)				*/
int		flag_gapline=0;					/* Flag Counter for Gap Line Number between TLE-Data	*/

int		tc,disp,loop,mult,tick;			/* Counter / LoopTick Elements ( e.g. 240*15m )			*/
int		i;

/*----------------------------------------------------------------------------------------------*/
dbl		jul_date;						/* SGP-C-LIB: Julian Date Of Time						*/
struct tle_ascii	c_tle;				/* SGP-C-LIB: TLE-Data (ASCII)							*/
struct vector		c_pos,c_vel;		/* SGP-C-LIB: SAT Pos & SAT Vel							*/
/*----------------------------------------------------------------------------------------------*/

/* Set Option & Parameter */
	set_optparam(argv          /* => */ ,&flag_tledump,&flag_exemode,&flag_gapline,&p_gname,&p_fname,&p_date,&p_time,&p_looptick);
	set_looptick(p_looptick    /* => */ ,&loop,&mult,&tick);
	set_datetime(p_date,p_time /* => */ ,&tm_init,&msec);

/* Set Ground Location Lon/Lat/Alt */
	set_obspos(p_gname         /* => */ ,&obs);

/* Set LTZ_Date&Time-UTC_Date&Time [sec] */
	t_abs=time(NULL);
	t_off=t_abs-mktime(gmtime(&t_abs));

/* Open TLE-Data File */
	if(strcmp(p_fname,"-")==0)
		fp=stdin;
	else{
		if( (fp=fopen(p_fname,"r"))==NULL ){
			fprintf(stderr,"Error: Cannot Open TLE-Data File [%s]\n",p_fname);
			exit(1);
		}
	}

/* Prepare for Main Loop */
	tle .catno=-1;						/* Empty; It's identical to re_tledata()==FALSE			*/
	tle2.catno=-1;						/* Empty; It's identical to re_tledata()==FALSE			*/
	if(rd_tledata(fp,&tle2,00)==FALSE)	/* Read TLE2 for *Next* Loop ( Prefetch )				*/
		exit(0);

/* Display Format (1/2) */
	disp_format(stdout,flag_tledump);

/* Compute & Display Result */
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
	tc=0;								/* Propagation Tick Counter								*/
	while(TRUE){						/* Main Loop ( for All TLE-DataRecord )					*/
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/

	/* >Read TLE-Data File & Set TLE-Data Record */
		if( tle=tle2 , tle.catno<0 )	/* Assign & Check ( EOF? )								*/
			break;
		rd_tledata(fp,&tle2,00);		/* Read TLE2 for *Next*  Loop ( Prefetch )				*/

	/* >Set "SatName(%d)" */
		strcpy(buf_satcname,tle.name);
		if(strlen(buf_satcname)<=LEN_SATCNAME){
			for( i=strlen(buf_satcname) ; i<LEN_SATCNAME ; i++ )
				buf_satcname[i]=' ';
			buf_satcname[LEN_SATCNAME+0]=' ';
			buf_satcname[LEN_SATCNAME+1]='\0';
		}
		else{
			buf_satcname[LEN_SATCNAME+0]='*';
			buf_satcname[LEN_SATCNAME+1]='\0';
		}

	/* >Set TLE-Epoch */
		tleepoch2str(tle.epoch,buf_tleepoch);
		tm_epoc =tleepoch2tm(tle );
		if(flag_exemode=='S'){
			tm_epoc2=tleepoch2tm(tle2);
			msec2 = fmod( fmod(tle2.epoch,1.0)*24*60*60 , 1.0 );
		}

	/* >Set Initial Date&Time */
		if(strcmp(p_date,"e")==0){
			tm_init.tm_year	=tm_epoc.tm_year;
			tm_init.tm_mon	=tm_epoc.tm_mon	;
			tm_init.tm_mday	=tm_epoc.tm_mday;
		}
		if(strcmp(p_time,"e")==0){
			tm_init.tm_hour	=tm_epoc.tm_hour;
			tm_init.tm_min	=tm_epoc.tm_min	;
			tm_init.tm_sec	=tm_epoc.tm_sec	;
			msec = fmod( fmod(tle.epoch,1.0)*24*60*60 , 1.0 );
		}
		if( flag_exemode=='S' && tc!=0 )
			;							/* Don't Init TC & TM_CURR for New TLE-Data !!			*/
		else{
			tc=0; tm_curr=tm_init;		/*       Init TC & TM_CURR for New TLE-Data !!			*/
		}

	/********************************************************************************************/
		t_abs2 = ( tle2.catno<0 ? 0 : mktime(&tm_epoc2)+t_off );
		for( disp=0 ; tc<loop ; tc++ ){	// Sub Loop ( for All LoopTick )
	/********************************************************************************************/

		/* >>Set Current Date&Time */
			t_abs=mktime(&tm_curr)+t_off;
#ifdef MinGW
			strftime(buf_datetime,BUFSIZ,  "%Y-%m-%d %H:%M:%S",&tm_curr);
#else
			strftime(buf_datetime,BUFSIZ,"%04Y-%m-%d %H:%M:%S",&tm_curr);
#endif

		/* >>Jump to Next TLE ( flag_exemode=='S' ) */
			if( flag_exemode=='S' && tle2.catno>=0 && t_abs+msec>=t_abs2+msec2 )
				break;

		/* >>Predict Orbit & Set SAT-DataRecord */
			do_predict(t_abs,msec,&tle,&sat,&obs);

	/*------------------------------------------------------------------------------------------*/
		/* >>Predict Orbit & Set SAT-DataRecord ( SGP-C-LIB Version ) */
			jul_date=Julian_Date_of_Epoch(unix2tleepoch(t_abs,msec));
			strcpy(&(c_tle.l[0][0]),tle.name);
			strcpy(&(c_tle.l[1][0]),tle.line1);
			strcpy(&(c_tle.l[2][0]),tle.line2);
			sgp(AUTO_SGP4SDP4,jul_date,c_tle,&c_pos,&c_vel);
	/*------------------------------------------------------------------------------------------*/

		/* >>Display Result */
			disp_result(t_abs,t_off,msec,tle,sat,buf_datetime,buf_satcname,buf_tleepoch,flag_tledump);
			disp++;

		/* >>Adjust Data&Time [UTC] */
			switch(tick){
				case 'Y':
				case 'y': tm_curr.tm_year+=mult; break;
				case 'M': tm_curr.tm_mon +=mult; break;
					;;;;
				case 'D':
				case 'd': tm_curr.tm_mday+=mult; break;
				case 'H':
				case 'h': tm_curr.tm_hour+=mult; break;
				case 'm': tm_curr.tm_min +=mult; break;
					;;;;
				case 'S':
				case 's': tm_curr.tm_sec +=mult; break;
			}

		}
	/********************************************************************************************/

	/* >Check Exit Condition ( flag_exemode=='S' ) */
		if( flag_exemode=='S' && tc>=loop )
			break;						/* Don't Proceed to Next TLE-Data						*/

	/* >Print Gap Line(s) ( if not Last TLE-Data && Printed ) */
		if( tle2.catno>=0 && disp!=0 ){
			for( i=0 ; i<flag_gapline ; i++ )
				printf("\n");
		}

	}
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/

/* Display Format (2/2) */
	disp_format(stdout,flag_tledump);

/* Normal Exit */
	exit(0);

}
