#ifndef lint
static char vcid[] = "$Id: InitTime.c,v 1.2 2001/03/31 00:10:28 waichler Exp $";
#endif /* lint */

#include <ctype.h>
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "settings.h"
#include "equal.h"
#include "round.h"
/*#include "Calendar.h"*/
#include "DHSVMerror.h"
#include "inittime.h"

#define FAIL -1

/******************************************************************************/
/*				   InitTime()                                 */
/******************************************************************************/
int InitTime(TIMESTRUCT *Time, DATE *Start, DATE *End, DATE *StartRadar, 
	     DATE *StartMM5, int Dt)
{
  const char *Routine = "InitTime";
  int tmpsecond;

  Time->Dt = Dt;		/* timestep in seconds */

  /* Just to be sure, recalculate the Julian and JDay fields of all the dates */
  if (Start != NULL) {
    CopyDate(&(Time->Start), Start);
    Time->Start.JDay = DayOfYear(Time->Start.Year, Time->Start.Month,
				 Time->Start.Day);
    Time->Start.Julian = GregorianToJulianDay(Time->Start.Year,
					      Time->Start.Month,  
					      Time->Start.Day, Time->Start.Hour,
					      Time->Start.Min, Time->Start.Sec);
    CopyDate(&(Time->Current), &(Time->Start));
  }

  if (End != NULL) {
    CopyDate(&(Time->End), End);
    Time->End.JDay = DayOfYear(Time->End.Year, Time->End.Month,
			       Time->End.Day);
    Time->End.Julian = GregorianToJulianDay(Time->End.Year, Time->End.Month, 
					    Time->End.Day, Time->End.Hour,
					    Time->End.Min, Time->End.Sec);
  }
  if (StartRadar != NULL) {
    CopyDate(&(Time->StartRadar), StartRadar);
    Time->StartRadar.JDay = 
      DayOfYear(Time->StartRadar.Year, Time->StartRadar.Month,
		Time->StartRadar.Day);
    Time->StartRadar.Julian = 
      GregorianToJulianDay(Time->StartRadar.Year, Time->StartRadar.Month, 
			   Time->StartRadar.Day, Time->StartRadar.Hour,
			   Time->StartRadar.Min, Time->StartRadar.Sec);
  }
  if (StartMM5 != NULL) {
    CopyDate(&(Time->StartMM5), StartMM5);
    Time->StartMM5.JDay = 
      DayOfYear(Time->StartMM5.Year, Time->StartMM5.Month,
		Time->StartMM5.Day);
    Time->StartMM5.Julian = 
      GregorianToJulianDay(Time->StartMM5.Year, Time->StartMM5.Month, 
			   Time->StartMM5.Day, Time->StartMM5.Hour,
			   Time->StartMM5.Min, Time->StartMM5.Sec);
  }  
  
  if (Start != NULL && End != NULL) {
    if (After(&(Time->Start), &(Time->End)))
      return FALSE;
    Time->Step = 0;
    Time->NDaySteps = SECPDAY/Time->Dt;
    if ((SECPDAY - Time->NDaySteps * Time->Dt) != 0)
      ReportError((char *) Routine, 7);
    /* the 0.5 in the next line is because Julian day is measured from midday,
       and  we want since midnight */
    tmpsecond = Round(((Time->Start.Julian-0.5) -
		       floor(Time->Start.Julian-0.5)) * SECPDAY);
    Time->DayStep = tmpsecond/Time->Dt;
    /* The following line insures that the first timestep of the day would
       coincide with midnight */
    if (tmpsecond - Time->DayStep * Time->Dt != 0)       
      ReportError((char *) Routine, 9);
    Time->NTotalSteps = NumberOfSteps(&(Time->Start), &(Time->End), Time->Dt);
    if (Time->NTotalSteps == FAIL)
      return FALSE;
  }

  return TRUE;
}

/*****************************************************************************
  IncreaseTime()
*****************************************************************************/
void IncreaseTime(TIMESTRUCT *Time)
{
  double Sec;

  (Time->Step)++;
  Time->DayStep = (Time->DayStep + 1) % Time->NDaySteps;
  Time->Current.Julian = Time->Start.Julian + 
    ((double)Time->Step)*(((double)Time->Dt)/SECPDAY);
  JulianDayToGregorian(Time->Current.Julian, &(Time->Current.Year),
		       &(Time->Current.Month), &(Time->Current.Day),
		       &(Time->Current.Hour), &(Time->Current.Min), &Sec);
  Time->Current.Sec = (int) Sec;
  Time->Current.JDay = DayOfYear(Time->Current.Year, Time->Current.Month,
				 Time->Current.Day);
}


