/* rd_tledata.c */

#include	"tazel.h"

/****************************************************************************/
// This function reads TLE-DataFile (*fp) and set 1 TLE-DataRecord to *p_tle.
// It returns TRUE if success, or FALSE if not. (EOF)
/****************************************************************************/
extern int rd_tledata(FILE *fp,tle_t *p_tle,int flag_preserve){

dbl		dval;
int		i;

/* Read TLE-DataFile */
	if(fgets(p_tle->name ,BUFSIZ,fp)==NULL)				/* -> 1st Line		*/
		goto RET_FALSE;
	if(fgets(p_tle->line1,BUFSIZ,fp)==NULL)				/* -> 2nd Line		*/
		goto RET_FALSE;
	if( p_tle->name[0]=='1' && p_tle->line1[0]=='2' ){	/* TLE ( 2 Line )	*/
		strcpy(p_tle->line2,p_tle->line1);
		strcpy(p_tle->line1,p_tle->name );
		if(flag_preserve)
			p_tle->name[0]='\0';
		else
			strcpy(p_tle->name ,"(N/A)\n"   );
	}
	else{												/* TLE ( 3 Line )	*/
		if(fgets(p_tle->line2,BUFSIZ,fp)==NULL)			/* -> 3rd Line		*/
			goto RET_FALSE;
	}

	if(tle_cksum(p_tle->line1,p_tle->line2)!=TRUE){
		if(	((p_tle->line1)[68]=='\0' || (p_tle->line1)[68]==' ' || (p_tle->line1)[68]=='\r' || (p_tle->line1)[68]=='\n') && \
			((p_tle->line2)[68]=='\0' || (p_tle->line2)[68]==' ' || (p_tle->line2)[68]=='\r' || (p_tle->line2)[68]=='\n') ){
			fprintf(stderr,"Warning: Empty CheckSum in TLE-DataFile!!\n");
			fprintf(stderr,"%s%s%s",p_tle->name,p_tle->line1,p_tle->line2);
		}
		else{
			fprintf(stderr,"Error: Invalid CheckSum in TLE-DataFile!!\n");
			fprintf(stderr,"%s%s%s",p_tle->name,p_tle->line1,p_tle->line2);
			exit(1);
		}
	}

/* Set TLE-DataRecord(RAW) */
	if(flag_preserve)
		;
	else{
		for( i=strlen(p_tle->name )-1 ; i>=0&&isspace((int)p_tle->name[i] ) ; i-- ){ p_tle->name[i] ='\0'; }
		for( i=strlen(p_tle->line1)-1 ; i>=0&&isspace((int)p_tle->line1[i]) ; i-- ){ p_tle->line1[i]='\0'; }
		for( i=strlen(p_tle->line2)-1 ; i>=0&&isspace((int)p_tle->line2[i]) ; i-- ){ p_tle->line2[i]='\0'; }
		for( i=0 ; i<strlen(p_tle->name) ; i++ ){
			if( isspace((int)p_tle->name[i]) )
				p_tle->name[i]='_';		/* SP/CR/LF/HT/VT/FF or NUL -> '_'	*/
		}
	}

/* Set TLE-DataRecord(1/3) */
	p_tle->catno=atol(substr(p_tle->line1,2,6));

	strcpy(p_tle->idesg,substr(p_tle->line1,9,16));
	p_tle->idesg[8]=0;
	for( i=8-1 ; i>=0&&isspace((int)p_tle->idesg[i]) ; i-- ){ p_tle->idesg[i]='\0'; }

	if( isspace((int)p_tle->idesg[7]) ){		/* SP/CR/LF/HT/VT/FF or NUL			*/
		p_tle->idesg[7]=' ';
	}
	if( isspace((int)p_tle->idesg[6]) ){		/* SP/CR/LF/HT/VT/FF or NUL			*/
		p_tle->idesg[6]=p_tle->idesg[7];
		p_tle->idesg[7]=' ';
	}
	if( isspace((int)p_tle->idesg[5]) ){		/* SP/CR/LF/HT/VT/FF or NUL			*/
		p_tle->idesg[5]=p_tle->idesg[6];
		p_tle->idesg[6]=p_tle->idesg[7];
		p_tle->idesg[7]=' ';
	}

	p_tle->epoch=1000.0*atoi(substr(p_tle->line1,18,19))+atof(substr(p_tle->line1,20,31));
	p_tle->drag1=atof(substr(p_tle->line1,33,42));

	dval=1.0e-5*atof(substr(p_tle->line1,44,49));
	if(p_tle->line1[50]=='+')
		p_tle->drag2=dval*pow(10.0,(p_tle->line1[51]-'0'));
	else
		p_tle->drag2=dval/pow(10.0,(p_tle->line1[51]-'0'));

/* Set TLE-DataRecord(2/3) */
	p_tle->incl=atof(substr(p_tle->line2, 8,15));
	p_tle->raan=atof(substr(p_tle->line2,17,24));
	p_tle->eccn=1.0e-07*atof(substr(p_tle->line2,26,32));
	p_tle->mano=atof(substr(p_tle->line2,43,50));
	p_tle->mmot=atof(substr(p_tle->line2,52,62));

	dval=1.0e-5*atof(substr(p_tle->line1,53,58));
	if(p_tle->line1[59]=='+')
		p_tle->bstar=dval*pow(10.0,(p_tle->line1[60]-'0'));
	else
		p_tle->bstar=dval/pow(10.0,(p_tle->line1[60]-'0'));

	p_tle->argp=atof(substr(p_tle->line2,34,41));

/* Set TLE-DataRecord(3/3) */
	p_tle->setno=atol(substr(p_tle->line1,64,67));
	p_tle->revno=atol(substr(p_tle->line2,63,67));

/* ( Debug ) */
#ifdef DEBUG
	printf("### rd_tledata() ### flag_preserve=%d\n",flag_preserve);
	printf("*name =\"%s\"\n",p_tle->name);
	printf("*line1=\"%s\"\n",p_tle->line1);
	printf("*line2=\"%s\"\n",p_tle->line2);
	printf("*catno=(int)%d\n",p_tle->catno);
	printf("*idesg=\"%s\"\n",p_tle->idesg);
	printf("*epoch=(dbl)%17.12f\n",p_tle->epoch);
	printf("*drag1=(dbl)%17.12f\n",p_tle->drag1);
	printf("*drag2=(dbl)%17.12f\n",p_tle->drag2);
	printf("*bstar=(dbl)%17.12f\n",p_tle->bstar);
	printf("*incl =(dbl)%17.12f\n",p_tle->incl);
	printf("*raan =(dbl)%17.12f\n",p_tle->raan);
	printf("*eccn =(dbl)%17.12f\n",p_tle->eccn);
	printf("*argp =(dbl)%17.12f\n",p_tle->argp);
	printf("*mano =(dbl)%17.12f\n",p_tle->mano);
	printf("*mmot =(dbl)%17.12f\n",p_tle->mmot);
	printf("*setno=(int)%d\n",p_tle->setno);
	printf("*revno=(int)%d\n",p_tle->revno);
#endif

/* Convert EU-UNIT */
	p_tle->drag1*=(M_PI*2.0/pow(24.0*60.0,2.0));
	p_tle->drag2*=(M_PI*2.0/pow(24.0*60.0,3.0));
	p_tle->incl=rad(p_tle->incl);
	p_tle->raan=rad(p_tle->raan);
	p_tle->argp=rad(p_tle->argp);
	p_tle->mano=rad(p_tle->mano);
	p_tle->mmot*=(M_PI*2.0/pow(24.0*60.0,1.0));

/* ( Debug ) */
#ifdef DEBUG
	printf("--- Convert EU-UNIT ---\n");
	printf("*drag1=(dbl)%17.12f\n",p_tle->drag1);
	printf("*drag2=(dbl)%17.12f\n",p_tle->drag2);
	printf("*incl =(dbl)%17.12f\n",p_tle->incl);
	printf("*raan =(dbl)%17.12f\n",p_tle->raan);
	printf("*argp =(dbl)%17.12f\n",p_tle->argp);
	printf("*mano =(dbl)%17.12f\n",p_tle->mano);
	printf("*mmot =(dbl)%17.12f\n",p_tle->mmot);
#endif

/* Return on Success */
	return(TRUE);
/* Return on Failure */
RET_FALSE:
	p_tle->catno=-1;
	return(FALSE);

}

/****************************************************************************/
// This function checks TLE-CheckSum of *line1 & *line2.
// It returns TRUE if they are valid, or FALSE if not.
/****************************************************************************/
extern int tle_cksum(char *line1,char *line2){

static char	cval[256];
static int	flag_1stcall=TRUE;
int		sum1,sum2;
int		i;

/* Initialize Char-ValueTable for TLE-CheckSum */
	if(flag_1stcall==TRUE){
		for(i=0;i<=255;i++)
			cval[i]=0;
		for(i='0';i<='9';i++)
			cval[i]=i-'0';
		cval['-']=1;
		flag_1stcall=FALSE;
	}

/* Calculate CheckSum Value */
	sum1=0;
	sum2=0;
	for(i=0;i<=67;i++){
		sum1+=cval[(int)line1[i]]; sum1%=10;
		sum2+=cval[(int)line2[i]]; sum2%=10;
	}

/* Return Result */
	if( sum1==cval[(int)line1[68]] && sum2==cval[(int)line2[68]] ){
		return(TRUE);
	}
	else{

	// If checksum column is     empty, it will not display error message.
	// If checksum column is not empty, it will     display error message.

		if( line1[68]!='\0' && line1[68]!=' ' && line1[68]!='\r' && line1[68]!='\n' )
			fprintf(stderr,"CkSum(Line#1): TLE_RawData=\'%c\' Expected=\'%c\'\n",cval[(int)line1[68]]+'0',sum1+'0');
		if( line2[68]!='\0' && line2[68]!=' ' && line2[68]!='\r' && line2[68]!='\n' )
			fprintf(stderr,"CkSum(Line#2): TLE_RawData=\'%c\' Expected=\'%c\'\n",cval[(int)line2[68]]+'0',sum2+'0');
		return(FALSE);
	}
}
