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

                       CSA Library, Free Evaluation Version 2.0.5 
                                       Release: January 22th 1997 

       Header file of the csDATE class.
       Also defines date formats.

       NOTE: The julian-date functions require floating point.
             The other member functions of the class can be used without
             forcing the floating point liberies to be linked int.

                                           Copyright(c) 1994-1997 
                                                          ComBits 
                                                  The Netherlands 
***********************************************************************/

#ifndef __CSDATE_H
#define __CSDATE_H


#include "time.h"
#include "cstypes.h"
#include "cswarnof.h"
#include "csjulian.h"

enum f_date  {  MDY2,
                MY2D,
                Y2MD,
                Y2DM,
                DMY2,
                DY2M,
                MDY4,
                MY4D,
                Y4MD,
                Y4DM,
                DMY4,
                DY4M   };




inline int leap_year(int J) {return ((J%400==0) || ((J%4==0) && (J%100!=0))); }
inline int days_in_year(int j) { return 365+leap_year(j); }
int  days_in_month(int mo,int year);
int  days_in_month(int mo);
int  date_validate(csCHAR *s,int format);
void date_SN(csCHAR *s,int *x,int *y,int *z);
void parm_ord(int ,int,int,int, int &,int & ,int &);
void default_date_format(int );     // Sets the default format for the csDATE.


/*
  The frequently used frase 'semi-jul' refers to a represenation of a
  date according to the formula: YEAR*512+MONTH*32+DAY.

  With YEAR in the 4 digit format,
  MONTH in the range [1..12] and
  DAY in the range [1..31].


*/


class csDATE
{

private:

  unsigned form :4;           // Date Format.
  unsigned mo   :4;           // Month
  unsigned y4   :1;           // TRUE if 4 digits for the year, FALSE otherwise.
  unsigned da   :5;           // Day
  S16      ye;                // Year

protected:

   int year4(int ye);


public:

  S32 sem_jul(void);
  S32 sem_jul(csCHAR *s);
  S32 sem_jul(uchar *s)       { return sem_jul((csCHAR *)s); }
  S32 sem_jul(int Y,int M,int D);
 void sem_jul(S32 l);



  void format(int dat_f);  // Set the date format.
   int format(void)        { return form; }
                           // Returns the date format.
   int day(void)           { return da; }
                           // Returns the day of the month [1..31]
   int day(csCHAR *);      // Returns also the name of the day,
                           // [monday,tuesday,...sunday]
  void day(int d)          { da=d; }
                           // Sets the day.
   int week_day(void);     // Returns the day of the week.
                           // Monday=1, Tuesday=2, etc..
   int month(void)         { return mo; }
                           // Returns the month [1..12]
   int month(csCHAR *);    // Returns also the name of the calendar month,
                           // [January,February...December]
  void month(int m)        { mo=m; }
                           // Sets the month. (January==1)
   int year(void)          { return ( (y4) ? ye: ye%100); }
                           // Returns the year in 2 or 4 digits, depending
                           // on the format.
  void year(int y)         {  ye=y; }
                           // Sets the year.
                           // No century data is added or checked!
   int year4(void)         { return ye; }
                           // Returns the year with a 4 digit format.
   int long_year(void)     { return y4; }
                           // Returns TRUE if 4 positions are used
                           // to represent the year. FALSE otherwise.
   int leap_year(void)     {  return ::leap_year(ye); }
                           // Returns TRUE if the date is a leap-year.
                           // FALSE otherwise.
  void julian(long j);     // Set date according to julian date.
  long julian(void)        {  return cal_julian(mo,da,year4()); }
                           // Returns Julian date.
   int valid(void);        // Returns TRUE if the date is a valid
                           // calendar date, FALSE otherwise.
   void now(void);         // Make date equal to the system clock.
   int  read_comp_time(csCHAR *s);
   int  read_time_t(time_t t);


////////////////////// Constructor   /////////////////////////////
   csDATE::csDATE(void);
   csDATE::csDATE(csCHAR *s);

////////////////////// Type casting  /////////////////////////////

   operator csCHAR*();


////////////////////// Operator overloading /////////////////////


   int operator==(csDATE &da)    { return sem_jul()==da.sem_jul(); }
   int operator!=(csDATE &da)    { return sem_jul()!=da.sem_jul(); }
   int operator<( csDATE &da )   { return sem_jul()<da.sem_jul();  }
   int operator<=(csDATE &da )   { return sem_jul()<=da.sem_jul(); }
   int operator>( csDATE &da )   { return sem_jul()>da.sem_jul();  }
   int operator>=(csDATE &da )   { return sem_jul()>=da.sem_jul(); }
   int operator==(csCHAR *s)   { return sem_jul()==sem_jul(s); }
   int operator!=(csCHAR *s)   { return sem_jul()!=sem_jul(s); }
   int operator<( csCHAR *s )  { return sem_jul()<sem_jul(s);  }
   int operator<=(csCHAR *s )  { return sem_jul()<=sem_jul(s); }
   int operator>( csCHAR *s )  { return sem_jul()>sem_jul(s);  }
   int operator>=(csCHAR *s )  { return sem_jul()>=sem_jul(s); }
   int operator==(uchar *s)    { return sem_jul()==sem_jul(s); }
   int operator!=(uchar *s)    { return sem_jul()!=sem_jul(s); }
   int operator<( uchar *s )   { return sem_jul()<sem_jul(s);  }
   int operator<=(uchar *s )   { return sem_jul()<=sem_jul(s); }
   int operator>( uchar *s )   { return sem_jul()>sem_jul(s);  }
   int operator>=(uchar *s )   { return sem_jul()>=sem_jul(s); }

   csDATE&  operator+=(long days);
   csDATE&  operator-=(long days)  { return operator+=(-days); }
   csDATE&  operator=(csDATE &);
    long  operator-(csDATE &);
   csDATE&  operator=(csCHAR *);


};


#endif
