//=-- Date.h - This class encapulates Date routines --------------------------=
//
//  This class provides a C++ wrapper around the time.h file.  The functions 
//    provided are mostly date oriented, although some time manipulation is 
//    possible.
//
//=---------------------------------------------------------------------------=
//  This file is copyright (c) 1997-2000 Chris Lattner
//=---------------------------------------------------------------------------=

#ifndef DATE_H
#define DATE_H

#include <time.h>

#include "Object.h"

class Date;
class Serialize;
class String;

class MSAPI Date : public Object {
public :
  Date();               // A constructor for every day of the week. (ha ha)
  Date(const Date &);
  Date(const time_t &);
  Date(const Date *);
  Date(int Day, int Month, int Year);
  Date(String S);
  inline ~Date() { delete TM; }

  int Compare(const Object &Date) const;

  Date &operator=(const Date &);

  Date operator + (const Date &) const;
  Date operator + (const int) const;
  inline Date operator-(const int Days) const { return operator+(-Days); }

  double ElapsedSeconds(Date &StartTime);
  inline double ElapsedMinutes(Date &S) { return ElapsedSeconds(S) / 60; }
  inline double ElapsedHours(Date &S)   { return ElapsedSeconds(S) / 3600; }
  inline double ElapsedDays(Date &S)    { return ElapsedHours(S) / 24; }
  inline double ElapsedWeeks(Date &S)   { return ElapsedDays(S) / 7; }
  inline double ElapsedMonths(Date &S)  { return ElapsedDays(S) / 30; }
  inline double ElapsedYears(Date &S)   { return ElapsedDays(S) / 365; }
  
  inline void SetDay    (const int Day)    { TM->tm_mday = Day; RecalcStruct(); }
  inline void SetMonth  (const int Month)  { TM->tm_mon  = Month-1; RecalcStruct(); }
  inline void SetYear   (const int Year)   { TM->tm_year = Year; RecalcStruct(); }
  inline void SetHour   (const int Hour)   { TM->tm_hour = Hour; }
  inline void SetMinute (const int Minute) { TM->tm_min  = Minute; }
  inline void SetSecond (const int Second) { TM->tm_sec  = Second; }

  // Convert a month name (eg "Apr") into a month number (eg 3).  Returns -1 if unknown.
  static int GetMonthNumber(const String &);

  inline int GetDay()       const { return TM->tm_mday;  }
  inline int GetDayOfWeek() const { return TM->tm_wday;  }
  inline int GetMonth()     const { return TM->tm_mon+1; }
  inline int GetYear()      const { return TM->tm_year;  }
  inline int GetHour()      const { return TM->tm_hour;  }
  inline int GetMinute()    const { return TM->tm_min;   }
  inline int GetSecond()    const { return TM->tm_sec;   }

  int GetDaysInMonth() const;

  // Returns length of dest or zero on error.
  size_t strftime(String &Dest, const char *Format) const;
  ostream &print(ostream &) const;

  Date Tomorrow()  const;
  Date Yesterday() const;

  Serialize &Save(Serialize &) const;
  Serialize &Restore(Serialize &);

private :
  void RecalcStruct();
  struct tm *TM;

  struct tm *CopyTM(struct tm *T) const;
};

inline Serialize& operator<<(Serialize& S, const Date& D) {
  return D.Save(S);
}

inline Serialize& operator>>(Serialize& S, Date& D) {
  return D.Restore(S);
}

#endif
