/*Δοκιμαστικό πρόγραμμα για την astrolib */

#include "astrolib.h"
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>

#define	TRUE	1
#define	FALSE	0


double file_read(FILE*);

int main(int argc, char* argv[])
{
	double year,month,day;
	double hour,minute,second;
	double TZ, Longitude,Latitude,LST,GST;
	double Pressure,Temperature,Height;
	double JD,JD1,DT;
	double *star_ra,*star_dec;
	double sun_long,sun_lat,sun_size,sun_dist;
	double moon_long,moon_lat,moon_size,moon_dist;
	int n_objects,i;
	char flags;

	double Moon[6];
	char daysofweek[7][9]={"Sunday","Monday","Tuesday","Wensday","Thursday","Friday","Saturday"};
	FILE* input;
	
	/*Ανοίγει το input.dat, εκτός αν ο χρήστης υποδείξει */
	/*άλλο αρχείο ως όρισμα στο εκτελέσιμο */
	if(argc==1)
		input=fopen("input.dat","rt");
	else
		input=fopen(argv[1],"rt");
	if(!input)
		return 1;
	flags=FLAGS_RESET;

	/*Ανάγνωση από το αρχείο δεδομένων, χρόνος, μήνας...ώρα κλπ*/
	year=file_read(input),month=file_read(input),day=file_read(input);
	hour=file_read(input),minute=file_read(input),second=file_read(input);
	TZ=file_read(input);
	Longitude=(PI/180.000)*file_read(input);
	Latitude=(PI/180.000)*file_read(input);
	Pressure=file_read(input);
	Temperature=file_read(input);
	Height=file_read(input);
	DT=file_read(input);
	if((int)file_read(input)==TRUE)
		flags+=PRECESSION;
	if((int)file_read(input)==TRUE)
		flags+=NUTATION;
	if((int)file_read(input)==TRUE)
		flags+=ABERRATION;
	if((int)file_read(input)==TRUE)
		flags+=REFRACTION;
	if((int)file_read(input)==TRUE)
		flags+=GEOPARALAX;
	if((int)file_read(input)==TRUE)
		flags+=LIGHTTRAVEL;
	if((int)file_read(input)==TRUE)
		flags+=TDTDIFFERENCE;
	if(!(flags&TDTDIFFERENCE))
		DT=0.000;
	JD1=file_read(input);
	n_objects=(int)file_read(input);
	star_ra=(double*)malloc(sizeof(double)*n_objects);
	star_dec=(double*)malloc(sizeof(double)*n_objects);
	for(i=0;i<n_objects;i++)
	{
		fscanf(input,"%lf %lf",&star_ra[i],&star_dec[i]);
		star_ra[i]=star_ra[i]*PI/12.000;
		star_dec[i]=star_dec[i]*PI/180.000;
	}


	/*Υπολόγισε την JD */
	JD=YYMMDD2JD(year,month,DDDecHour2DecDay(day,HHMMSS2DecHour(LT2UTC(TZ,hour),minute,second)));
	
	/*Υπολογισμός Φεγγαριού*/
	calculateMoon(JD+DT/86400,Moon);
	if(flags&LIGHTTRAVEL)
		calculateMoon(JD_from_light_travel_delay(JD+DT/86400 ,Moon[2]),Moon);
	moon_long=Moon[0];
	moon_lat=Moon[1];
	moon_size=Moon[3];
	moon_dist=Moon[2];

	/*Υπολογισμός Ήλιου*/
	sun_long=sun_longitude(JD+DT/86400);
	if(flags&LIGHTTRAVEL)
		sun_long=sun_longitude( JD_from_light_travel_delay(JD+DT/86400 ,sun_distance(sun_long)) );
	sun_size=sun_angular_size(sun_long);
	sun_dist=sun_distance(sun_long);
	sun_lat=0.000;
	
	/*Εμφάνισε την φάση της Σελήνης*/
	printf("Moon is %lf days old, Phase=%lf%% \n",(Moon[4]<0.000?29.5306:0.000)+Moon[4]*29.5306*0.500/PI,Moon[5]*100.000);

	printf("The Julian Day is: ");	
	printf("%lf \n",JD);

	printf("Day of the Week is ");
	printf("%s\n\n",daysofweek[FindDayOfTheWeek(JD)]);

	GST=UTC2GST(JD);
	LST=GST2LST(Longitude,GST);
	hour=DecHour2HHMMSS(LST,&minute,&second);
	printf("GST=%lf, Local Sidereal Time is %lfh %lfm %lfs\n\n",GST,hour,minute,second);
	
	
	/*Μετασχηματισμοί συντεταγμένων*/

	/*Mετασχημός: Κλόνιση και Αποπλάνιση*/
	Transform_lamdabeta2radec_nutationANDaberration(flags,JD,1,&sun_long,&sun_lat,&sun_long,&sun_lat);
	Transform_lamdabeta2radec_nutationANDaberration(flags,JD,1,&moon_long,&moon_lat,&moon_long,&moon_lat);
	Transform_radec_nutationANDaberration(flags,JD,n_objects,star_ra,star_dec,star_ra,star_dec);

	/*Μετασχηματισμός Μετάπτωσης*/
	if(flags&PRECESSION)
	{
		PrecessionTransform(2447891.500,JD,1,&sun_long,&sun_lat,&sun_long,&sun_lat);
		PrecessionTransform(2447891.500,JD,1,&moon_long,&moon_lat,&moon_long,&moon_lat);
		PrecessionTransform(JD1,JD,n_objects,star_ra,star_dec,star_ra,star_dec);
	}
	
	/*Γεωκεντρική παράλαξη για ήλιο και φεγγάρι*/
	if(flags&GEOPARALAX)
	{
		GeocentricParalax(LST*PI/12.000,Latitude,Height,sun_dist,1,&sun_long,&sun_lat,&sun_long,&sun_lat);
		GeocentricParalax(LST*PI/12.000,Latitude,Height,moon_dist,1,&moon_long,&moon_lat,&moon_long,&moon_lat);
	}

	/*Εμφάνισε στοιχεία για τον Ήλιο και τη Σελήνη*/
	printf("Sun,  converted coordinates: ra=%lf hours, dec=%lf degs\n",sun_long*12.000/PI,sun_lat*180.000/PI);
	printf("Moon, converted coordinates: ra=%lf hours, dec=%lf degs\n",moon_long*12.000/PI,moon_lat*180.000/PI);

	/*Αλλαγή συστήματος συντεγαμένων Ουράνιες->Αλταζιμουθιακές*/
	radec2azalt(LST*PI/12.000,Latitude,1,&sun_long,&sun_lat,&sun_long,&sun_lat);
	radec2azalt(LST*PI/12.000,Latitude,1,&moon_long,&moon_lat,&moon_long,&moon_lat);

	/*Επίδραση διάθλασης αν απαιτείται*/
	if(flags&REFRACTION)
	{
		sun_lat=sun_lat-refraction(Pressure,Temperature,sun_lat);
		moon_lat=moon_lat-refraction(Pressure,Temperature,moon_lat);
	}

	/*Εμφάνισε στοιχεία για τον Ήλιο και τη Σελήνη*/
	printf("Sun,  observed at: Az=%lf degs, Alt=%lf degs\n",sun_long*180.000/PI,sun_lat*180.000/PI);
	printf("Moon, observed at: Az=%lf degs, Alt=%lf degs\n",moon_long*180.000/PI,moon_lat*180.000/PI);

	printf("Sun / Moon observed Angular Size: Sun=%lf arcmins, Moon=%lf arcmins\n\n",sun_size*10800.0/PI,moon_size*10800.0/PI);
	
	/*Εμφάνισε ουράνιες συντεταγμένες για τα αστέρια*/
	for(i=0;i<n_objects;i++)
	{
		printf("Object %3d: ra=%lfdegs, dec=%lfdegs\n",i,star_ra[i]*12.000/PI,star_dec[i]*180.000/PI);
	}

	/*Μετασχημάτησε τις ουράνιες των αστεριών σε αλταζιμουθιακές*/
	radec2azalt(LST*PI/12.000,Latitude,n_objects,star_ra,star_dec,star_ra,star_dec);

	/*Διάθλαση στα αστέρια*/
	if(flags&REFRACTION)
	{
		for(i=0;i<n_objects;i++)
			star_dec[i]=star_dec[i]-refraction(Pressure,Temperature,star_dec[i]);
	}

	/*Εμφάνισε τα αστέρια με τις αλταζιμουθιακές*/
	for(i=0;i<n_objects;i++)
		printf("Object %d, observed at: Az=%lf degs, Alt=%lf degs\n",i,star_ra[i]*180.000/PI,star_dec[i]*180.000/PI);

	
	/*Πάμε τον χρόνο πίσω για επιβεβαίωση*/
	printf("\nGoing reversely...\n");

	GST=LST2GST(Longitude,LST);
	printf("GST=%lf, UTC=%lf ",GST,GST2UTC(0.500+(double)((int)(JD-0.5)),GST));
	JD2YYMMDD(JD, &year, &month, &day);
	
	day=DecDay2DDDecHour(day, &hour);
	hour=UTC2LT(TZ,hour);
	hour=DecHour2HHMMSS(hour, &minute, &second);

	if(hour>=24.000)
	{
		hour-=24.000;
		day+=1.000;
	}
	if(hour<0.000)
	{
		hour+=24.000;
		day-=1.000;
	}

	printf("y=%lf m=%lf d=%lf\n",year,month,day);
	printf("h=%lf m=%lf s=%lf\n\n",hour,minute,second);

	fclose(input);
	free(star_ra);
	free(star_dec);
	return 0;
}



/*Συνάρτηση που διαβάζει έναν πραγματικό αριθμό από το */
/*αρχείο δεδομένων εκτός αν η γραμμή ανάγνωσης ξεκινάει*/
/*από #, οπότε είναι σχολιασμός */
double file_read(FILE* input)
{
	char *tmp_chr;
	char *tmp_str;
	int tmp_int;
	tmp_chr=(char*) malloc(81*sizeof(char));	
	tmp_str=tmp_chr;
	do{
		tmp_int=0;
		while(tmp_int!='\n'&&tmp_int!='\r'&&!feof(input))
		{
			tmp_int=getc(input);
			*tmp_chr++=(char)tmp_int;
		}
		if(tmp_int=='\r')
			getc(input);
		if(tmp_int=='\n'||tmp_int=='\r'||feof(input))
			*--tmp_chr='\0';
		tmp_chr=tmp_str;
		
		if(*tmp_str!='#')
		{
			return atof(tmp_str);
		}
	}while(TRUE);
	free(tmp_chr);
}