#ifndef __DATE_H
#define __DATE_H

#ifndef __OBJECT_H
#include <object.h>
#endif

// @C
// Classe TDate : TObject
// @END

#define TODAY  -1
#define ANSI   -1

class TDate : TObject
{
  // @DPRIV
  long    _val; // Valore data in formato packed

  // @DES Operatori esterni < > <= >= == !=
  // @FPUB
  friend bool operator <(const TDate& a, const TDate& b);
  friend bool operator >(const TDate& a, const TDate& b);
  friend bool operator <=(const TDate& a, const TDate& b);
  friend bool operator >=(const TDate& a, const TDate& b);
  friend bool operator ==(const TDate& a, const TDate& b);
  friend bool operator !=(const TDate& a, const TDate& b);

public:
  // @FPUB
  char* string(int yeardgts = 4, char sep = '-') const ;
  // @DES Ritorna la data in formato di stringa (anche in formato ANSI)
  // @FPUB
  int     day() const ; // Ritorna il giorno
  int     month() const ; // Ritorna il mese
  int     year() const ; // Ritorna l'anno
  void    addmonth(int nmonth = 1); // Aggiunge dei mesi
  void    addyear(int nyear = 1); // Aggiunge degli anni
  bool    ok() const; // Vero se la data e' corretta
  static  bool isdate(const char*); // Vero se la stringa passata e' una data corretta

  static int last_day(int month, int year);
  bool    is_end_month();
  void    set_end_month();        // setta il giorno del mese all'ultimo possibile
  // implementando la filastrocchina
  
  void    set_day(int n);
  void    set_month(int n); 
  void    set_year(int n); 
  
  // @DES Ridefiniti gli operatori: += -= ++ -- >> e <<
  // @FPUB
  TDate& operator +=(const long nday)  { _val += nday; return *this; }
  TDate& operator -=(const long   nday)  { _val -= nday; return *this; }
  TDate& operator ++()  { _val++; return *this; }
  TDate& operator --()  { _val--; return *this; }

  void print_on(ostream& out) const ;
  void read_from(istream& in) ;

  operator long() const { return _val; }
  
  operator long*() { return &_val;}
  
  operator const char*() const ;
  TDate& operator =(const char* s);
  TDate& operator =(long val) { _val = val; return *this;}
  TDate& operator =(const TDate& d) { _val = d._val; return *this;}

  TDate(const TDate& d);
  TDate(long l);
  TDate(const char* s);
  TDate(int day = 0, int month = 0, int year = 0);
};

// @FPUB
TDate& operator +(const TDate& a, long nday) ;
TDate& operator +(const long nday, const TDate& b) ;
TDate& operator -(const TDate& a, long nday) ;
inline bool operator <(const TDate& a, const TDate& b) { return a._val < b._val;}
inline bool operator >(const TDate& a, const TDate& b) { return a._val > b._val;}
inline bool operator <=(const TDate& a, const TDate& b) { return a._val <= b._val;}
inline bool operator >=(const TDate& a, const TDate& b) { return a._val >= b._val;}
inline bool operator ==(const TDate& a, const TDate& b) { return a._val == b._val;}
inline bool operator !=(const TDate& a, const TDate& b) { return a._val != b._val;}
void swap(TDate& a, TDate& b) ; // Scambia la data a con la data b
const TDate& fnc_min(const TDate& a, const TDate& b) ; // Ritorna la data piu' piccola tra a e b
const TDate& fnc_max(const TDate& a, const TDate& b) ; // Ritorna la data piu' grande tra a e b
// @END

const char* itom(byte month);     // Ritorna il nome del mese (1-12)
const char* itow(byte dayofweek); // Ritorna il nome del giorno (1-7)

// @DPUB
extern const TDate nodate, botime, eotime;
// @END

#endif // __DATE_H



