// C++ code Copyright (C) David R. Evans G4AMJ/NQ0I

#ifndef TIMECLASSH
#define TIMECLASSH

// an internal time class

#include <iostream.h>

#include <defines.h>
#include <DREstring.h>

class timeclass;
extern double dseconds(const timeclass&);

// the lowest permissible value of day == 0 (i.e. day == doy - 1)
class timeclass
{ int _year, _day, _hour, _minute;
  float _second;
  
public:
// note that if we want to instantiate with a day of year, then we
// should use (day_of_year - 1) in the constructor

  timeclass(const int y = 0, const int d = 0, const int h = 0,
            const int m = 0, const double s = 0);

  static int days_in_month[12];

  void _normalise(void);

  inline int year(void) const 
    { return _year; }
  inline int day(void) const 
    { return _day; }
  inline int hour(void) const 
    { return _hour; }
  inline int minute(void) const 
    { return _minute; }
  inline float second(void) const 
    { return _second; }
  inline int doy(void) const 
    { return _day + 1; }

  timeclass& year(const int); 
  timeclass& day(const int); 
  timeclass& hour(const int); 
  timeclass& minute(const int); 
  timeclass& second(const double); 

// doesn't work for 1900; OK for 2000
  inline int leap_year(void) const
    { return ((_year / 4) * 4 == _year); }
  inline int days_in_year(void) const
    { return (leap_year() ? 366 : 365); }

  int month(void) const;
  int day_of_month(void) const;
  
  void operator+=(const timeclass&);
  timeclass operator+(const timeclass&) const;
  
  boolean operator<(const timeclass&) const;
  boolean operator>(const timeclass&) const;
  boolean operator==(const timeclass&) const;
  void operator=(const timeclass& t);
  timeclass operator-(const timeclass& t) const;
  void operator-=(const timeclass&);
  timeclass operator/(const int) const;
  inline double operator/(const timeclass& t) const
    { return dseconds(*this) / dseconds(t); }
  
  inline boolean operator<=(const timeclass& t) const
    { return (!(*this > t)); }
  inline boolean operator>=(const timeclass& t) const
    { return (!(*this < t)); }
  inline boolean operator!=(const timeclass& t) const
    { return (!(*this == t)); }

  friend ostream& operator<<(ostream&, const timeclass&);
  friend istream& operator>>(istream&, timeclass&);

  void write(FILE*);
  void read(FILE*);

};

// sign (timeclass a, timeclass b) [-1 if a<b; 0 if a == b; else +1]
  inline int sign(const timeclass& t1, const timeclass& t2)
    { return ((t1 < t2) ? -1 : (t1 == t2) ? 0 : 1); }

  inline long minutes(const timeclass& t)
    { return ((((long)t.year() * 365 + t.day()) * 24 + t.hour()) * 60 +
              t.minute()); }

  inline long seconds(const timeclass& t)
    { return (((((long)t.year() * 365 + t.day()) * 24 + t.hour()) * 60 +
              t.minute()) * 60 + (long)t.second()); }

// for some strange reason, the MPW compiler vomits at the inline hint
#ifndef macintosh
  inline
#endif
  double dseconds(const timeclass& t)
    { return (((((double)t.year() * 365 + t.day()) * 24 + t.hour()) * 60 +
              t.minute()) * 60 + t.second()); }

#endif
