/***************************************************************

   time_IO.c

      Functions for time IO.

      Header: use_db.h
      Library: use_db_x.lib

*/

#include "dbinc.h"   /* YMDHMS_TIME_TYPE, invalid_time() */
#include "ioserv.h"   /* report_msg() yr4digit() */
#include "use_db.h"


/***************************************************************
   get_time_range

      This is a function to read a time range from a file.
      The range is given as:

         yy/mm/dd hh:min:sec to yy/mm/dd hh:min:sec

      for example:

         82/01/01 12:00:00 to 82/01/31 06:00:00

      It returns 1 if successful, 0 if something other than
      a time range is found, EOF if end of file.  If
      something other than a time range is found, the file
      pointer is reset so that whatever was found is still
      available.
*/

#if PROTOTYPE_ALLOWED
int get_time_range(FILE *fp, YMDHMS_TIME_TYPE *t1, YMDHMS_TIME_TYPE *t2)
#else
int get_time_range(fp, t1, t2)
FILE *fp;
YMDHMS_TIME_TYPE *t1, *t2;
#endif
{
   int ns1, ns2;
   long offset;
   double hs;
   char buf[5];

   offset = ftell(fp);
   getword_nc(fp, buf, 5);
   if (strcmp(buf, "all") == 0)
   {
      t1->year = 1970;
      t1->month = t1->day = t1->hour = t1->minute = t1->second = 1;
      *t2 = *t1;
      t2->year = 2070;
      return(1);
   }
   else
   {
      if (fseek(fp, offset, SEEK_SET) == -1)  return(EOF);
   }

   ns1 = fscanf(fp, " %hd/%hd/%hd %hd:%hd:%lf", &(t1->year), &(t1->month),
            &(t1->day), &(t1->hour), &(t1->minute), &hs);
   if (ns1 != 6)
   {
      if (ns1==EOF) return(EOF);         /** normal end of file **/
      if (fseek(fp, offset, SEEK_SET) == -1)  return(EOF);
      return(0);
   }
   t1->second = set_hs(hs);   /* set as YMDHMH if needed - JR+ 95/10 */

   ns2 = fscanf(fp, " to %hd/%hd/%hd %hd:%hd:%lf", &(t2->year), &(t2->month),
            &(t2->day), &(t2->hour), &(t2->minute), &hs);

   if (ns2 != 6)
   {
      report_msg("\n%%%% ERROR: Reading time range\n\n");
      return(EOF);
   }
   t2->second = set_hs(hs);
   t1->year = (SHORT) yr4digit( (int)t1->year );
   t2->year = (SHORT) yr4digit( (int)t2->year );
   if (invalid_time(t1) || invalid_time(t2))    /* check whether pointer is right */
   {
      report_msg("\n%%%% ERROR: Invalid time in range\n\n");
      return(EOF);
   }
   return (1);
}                       /* get_time_range */

/* The following writes time in the format that get_time_range reads it.
*/

#if PROTOTYPE_ALLOWED
void write_ymdhms_time(FILE *fp, YMDHMS_TIME_TYPE *t)
#else
void write_ymdhms_time(fp, t)
FILE *fp;
YMDHMS_TIME_TYPE *t;
#endif
{
   int sec, hun, hs;

   fprintf(fp, "%04hd/%02hd/%02hd  %02hd:%02hd:", t->year, t->month,
            t->day, t->hour, t->minute);
   if (t->second & 0x8000)      /* YMDHMH-type */
   {
      hs = (t->second ^ 0x8000);
      sec = hs/100;
      hun = hs - sec*100;
      fprintf(fp, "%02d.%02d", sec, hun);
   }
   else
   {
      fprintf(fp, "%02d", t->second);
   }

   return;
}                       /* write_ymdhms_time */


#if PROTOTYPE_ALLOWED
void print_time_range(FILE *fp, YMDHMS_TIME_TYPE *start, YMDHMS_TIME_TYPE *end)
#else
void print_time_range(fp, start, end)
FILE *fp;
YMDHMS_TIME_TYPE *start, *end;
#endif
{
   fprintf(fp, "\n Time range: ");
   write_ymdhms_time(fp, start);
   fprintf(fp, " to ");
   write_ymdhms_time(fp, end);
   if (fp == stdout) fprintf(fp, "\n");
}                       /* print_time_range() */

#if PROTOTYPE_ALLOWED
int check_year_base(int *year_base)
#else
int check_year_base(year_base)
int *year_base;
#endif
{
   YMDHMS_TIME_TYPE ymd_time;

   if (*year_base > 0) return(0);         /* good year_base */
   if (db == NULL) return(1);             /* db not open -- can't retrieve */
   UPCKTIM(&ymd_time, &(db->block_dir_hdr.time1));
   *year_base = ymd_time.year;
   return(0);
}

/***************************************************************
   get_time

      This is a function to read a time from a file.
      The two possible formats are:

         yy/mm/dd hh:min:sec
         yearbase dday

      It returns 0 if successful, 1 if something other than
      a time range is found, EOF if end of file.  If
      a time is found, EOF if end of file.  If
      something other than a time is found, the file
      pointer is reset so that whatever was found is still
      available.

      EF 2000/09/18
      (Return: in contrast to get_time_range, here I am using
      the convention that 0 is ordinary success (no errors).

*/

int get_time(FILE *fp, YMDHMS_TIME_TYPE *t1)
{
   int ns1, ns2;
   long offset;
   double hs, dday;
   char buf1[80], buf2[80];
   int yearbase;


   offset = ftell(fp);
   getword_nc(fp, buf1, 80);
   getword_nc(fp, buf2, 80);

   ns1 = sscanf(buf1, " %hd/%hd/%hd", &(t1->year), &(t1->month),
            &(t1->day));
   if (ns1 != 3)
   {
      if (ns1==EOF) return(EOF);         /** normal end of file **/
      if (ns1 != 1)
      {
         if (fseek(fp, offset, SEEK_SET) == -1)  return(EOF);
         return(1);
      }
      yearbase = t1->year;
      ns2 = sscanf(buf2, "%lf", &dday);
      if (ns2 != 1)
      {
         report_msg("\n%%%% ERROR: Reading time\n");
         return(EOF);
      }
      yd_to_ymdhms_time(dday, yearbase, t1);
      return(0);  /* success */
   }
   /* ns1 = 3, so it is ymd hms */
   ns2 = sscanf(buf2, "%hd:%hd:%lf", &(t1->hour), &(t1->minute), &hs);
   if (ns2 != 3)
   {
      report_msg("\n%%%% ERROR: Reading time\n\n");
      return(EOF);
   }
   t1->second = set_hs(hs);
   t1->year = (SHORT) yr4digit( (int)t1->year );
   if (invalid_time(t1))    /* check whether pointer is right */
   {
      report_msg("\n%%%% ERROR: Invalid time\n\n");
      return(EOF);
   }
   return (0);
}                       /* get_time*/

