/**---------------------------------------------------------------------------
 ** 
 ** time.c -- Additionnal time handling functions
 ** 
 ** Author          : Pierre Jaccard
 ** Created On      : 1999/07/15 15:47:36
 ** Last Modified By: Pierre Jaccard
 ** Last Modified On: 1999/09/20 17:24:54
 ** Update Count    : 4
 ** Directory       : /pcdata1/jaccard/codas3c/gfi/src/libs/misc/
 ** Version         : 0.0
 ** Status          : Unknown
 ** ---------------------------------------------------------------------- ** 
 ** DESCRIPTION: 
 ** 
 **    These are time handling function that come in addition to those defined 
 **    in the original CODAS files.
 ** 
 ** ---------------------------------------------------------------------- ** 
 ** REVISIONS: 
 ** ---------------------------------------------------------------------- ** 
 ** CHANGES: 
 **------------------------------------------------------------------------**/

#include "time.h"

/* ------------------------------------------------------------------
   Set all fields of a YMDHMS time structure to bad values.
   
   RETURNS: 0
   ------------------------------------------------------------------ */
#if PROTOTYPE_ALLOWED
int ymdhms_to_bad(/* Pointer to time structure */
                  YMDHMS_TIME_TYPE *time)
#else
	int ymdhms_to_bad(time) 
	YMDHMS_TIME_TYPE *time
#endif
{

	time->year   = BADUSHORT;
	time->month  = BADUSHORT;
	time->day    = BADUSHORT;
	time->hour   = BADUSHORT;
	time->minute = BADUSHORT;
	time->second = BADUSHORT;

	return(0);

}

/* ------------------------------------------------------------------
	 Set YMDHMS to minimal value. Currently, this 1979/01/01 00:00:00

   RETURNS: 0
	 ------------------------------------------------------------------ */
#if PROTOTYPE_ALLOWED
int ymdhms_to_min(/* Pointer to time structure */
                  YMDHMS_TIME_TYPE *t)
#else
int ymdhms_to_min()
#endif
{

	t->year   = 1970;
	t->month  = 1;
	t->day    = 1;
	t->hour   = 0;
	t->minute = 0;
	t->second = 0;

	return(0);

}

/* ------------------------------------------------------------------
	 Set YMDHMS to maximal value. Currently, this 2070/01/01 00:00:00

   RETURNS: 0
	 ------------------------------------------------------------------ */
#if PROTOTYPE_ALLOWED
int ymdhms_to_max(/* Pointer to time structure */
                  YMDHMS_TIME_TYPE *t)
#else
int ymdhms_to_max()
#endif
{

	t->year   = 2070;
	t->month  = 1;
	t->day    = 1;
	t->hour   = 0;
	t->minute = 0;
	t->second = 0;

	return(0);

}

/* ------------------------------------------------------------------
   Convert an YMDHMS time to a string.

   RETURNS: 1 if invalid time or 0 if success.
   ------------------------------------------------------------------ */

#if PROTOTYPE_ALLOWED
int ymdhms_to_str(/* Pointer to destination string */
                  char *str, 
                  /* Pointer to time structure */
                  YMDHMS_TIME_TYPE *t, 
                  /* Uses decimal seconds if true */
                  int hs)
#else
int ymdhms_to_str(str, t, hs)
char *str;
YMDHMS_TIME_TYPE *t;
int hs;
#endif
{
	char strsec[10];
	
	/* Check for valide time */
	if(invalid_time(t)){
		sprintf(str, "9999/99/99  99:99:99");
		if(hs)
			strcat(str, ".99");
		return(1);
	}

	/* write date, hours and minutes */
	sprintf(str, "%04hu/%02hu/%02hu  %02hu:%02hu:", t->year, t->month,
            t->day, t->hour, t->minute);

	/* Check for YMDHMH times */
	if (t->second & 0x8000)      /* YMDHMH-type */
		sprintf(strsec, "%05.2f", ((double) (t->second ^ 0x8000) / 100.0));
	else if(hs)
		sprintf(strsec, "%05.2f", (double) (t->second));
	else
		sprintf(strsec, "%02hu", t->second);

	/* Append second value */
	strcat(str, strsec);

	return(0);
}     

	
/* ------------------------------------------------------------------
	 Converts a time given in decimal day into a string in YMDHMS format.
	 Seconds are printed in floating point format.

   RETURNS: 0
	 ------------------------------------------------------------------ */
#if PROTOTYPE_ALLOWED
int yd_to_ymdhms_str(/* Pointer to destinatin string */
                     char *str, 
                     /* Decimal day */
                     double yd, 
                     /* Year base used to get decimal day */
                     int year_base)
#else
int yd_to_ymdhms_str(str, yd, year_base)
char *str;
double yd;
int year_base;
#endif
{
	
	YMDHMS_TIME_TYPE t;

  if(yd < ADJ_BADFLOAT)
    yd_to_ymdhms_time(yd, year_base, &t);
  else
    ymdhms_to_bad(&t);
	ymdhms_to_str(str, &t, 1);

	return(0);
}

/* ------------------------------------------------------------------
	 Write a time range into a string. Seconds are not decimal.

   RETURNS: 0
	 ------------------------------------------------------------------ */
#if PROTOTYPE_ALLOWED
int time_range_to_str(/* Pointer to destination string */
                      char *str, 
                      /* Satrt time */
                      YMDHMS_TIME_TYPE *t1, 
                      /* Stop time */
                      YMDHMS_TIME_TYPE *t2)
#else
int time_range_to_str(str, t1, t2)
char *str;
YMDHMS_TIME_TYPE *t1;
YMDHMS_TIME_TYPE *t2;
#endif
{
	
	char s[40];

	ymdhms_to_str(str, t1, 0);
	strcat(str, "  to  ");
	ymdhms_to_str(s, t2, 0);
	strcat(str, s);

	return(0);
}


/* ------------------------------------------------------------------
	 This function fills an YMDHMS time structure with the content found in a
	 string. Required fields are 
 
	    YYY/MM/DD

	 if hour, minute and seconds are not present, they are set to zero. It also
	 test the validity of the obtained time. If seconds are decimal, they are
   saved in hundredths of second.

	 RETURN: non zero on error
	 ------------------------------------------------------------------ */
#if PROTOTYPE_ALLOWED
int str_to_ymdhms(/* Pointer to time structure */
                  YMDHMS_TIME_TYPE *time, 
                  /* Pointer to input string */
                  char *str)
#else
int str_to_ymdhms(time, str)
YMDHMS_TIME_TYPE *time;
char *str;
#endif
{

	int n;
	USHORT sec, hun;

	/* Get date information */
	n = sscanf(str, "%4hu/%2hu/%2hu %2hu:%2hu:%2hu.%2hu", 
						&(time->year), &(time->month), &(time->day),
						&(time->hour), &(time->minute), &sec, &hun);

	if(n < 3)
		return(-1);
	else if((n >= 3) && (n < 6))
		time->hour = time->minute = time->second = 0;
	else if(n == 6)
		time->second = sec;
	else if(n == 7)
		time->second = set_hs(((double) sec) + ((double) hun)/100.0);
	else
		return(-1);
	
	return(invalid_time(time));

}

/* ------------------------------------------------------------------
	 Check if a given time is within a specified time range.

   RETURNS: true if inside time range
	 ------------------------------------------------------------------ */
#if PROTOTYPE_ALLOWED
int time_inside_range(/* Start time */
                      YMDHMS_TIME_TYPE *t1, 
                      /* Stop time */
                      YMDHMS_TIME_TYPE *t2,
											/* This time */
                      YMDHMS_TIME_TYPE *t)
#else
int time_inside_range()
#endif
{

	LONG dh1, dh2;

	dh1 = HTIMDIF(t1, t);
	dh2 = HTIMDIF(t, t2);

	return((dh1 >= 0) && (dh2 >= 0));

}

/* ------------------------------------------------------------------
	 This function is similar to `get_ymdhms_time', but it reads the times in
	 the standard CODAS format, i.e. with '/' and ':' separators. Seconds are
   set to hundredths of seconds.

	 RETURNS: EOF if end of file, 0 if successfull, otherwise on error
	 ------------------------------------------------------------------ */
#if PROTOTYPE_ALLOWED
int fget_ymdhmh_time(/* File descriptor to read from */
                     FILE *fp, 
                     /* Place for time data */
                     YMDHMS_TIME_TYPE *t)
#else
int fget_ymdhmh_time()
#endif
{
  
  double dsec;

	/* Get time from file */
	if(fscanf(fp, " %4hu/%2hu/%2hu %2hu:%2hu:%lf", 
             &(t->year), &(t->month), &(t->day),
            &(t->hour), &(t->minute), &(dsec)) < 6){
		if(feof(fp)) return(EOF);
		error_found(READ_ERROR, "Reading YMDHMS time\n");
		return(READ_ERROR);
	}
	
	/* Process seconds */
  t->second = set_hs(dsec);

	return(0);

}

