/*
 * ===========================
 * VDK Visual Development Kit
 * Version 0.4
 * October 1998
 * ===========================
 *
 * Copyright (C) 1998, Mario Motta
 * Developed by Mario Motta <mmotta@guest.net>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
 * 02111-130
 */ 

#ifndef VDKDATE_H
#define VDKDATE_H

#include <math.h>
//#include <iostream.h>

#ifndef CALDATEDEBUG
#define Assert(condition) /* do nothing */
#else
#include <assert.h>
#define Assert(condition) assert(condition)
#endif

/* gregorian calendar adopted on oct 15, 1582 */
#define IGREG (15L+31L*(10L+12L*1582L))
enum { ddmmyyyy,mmddyyyy };
/*
  ===================
  CALENDAR DATE CLASS
  ===================
  */
/*!
  \class calendardate
  \brief provides a date object
 */
class calendardate
{
protected:
  int day,month,year;
  long julian;
  long Julian(void);
  void Caldate(void);
  //friend ostream& operator<<(ostream& os, calendardate& d);
  char* InternalBuffer();
  int mode;
public:
  /*!
    Constructor, uses system date
    \param mode date format
    \arg \b mmddyyyy english format month-day-year
    \arg \b ddmmyyyy european format day-month-year
  */
  calendardate(int mode = mmddyyyy);
  /*!
    Constructor
    \param day
    \param month
    \param year
    \param mode date format
    \arg \b mmddyyyy english format month-day-year
    \arg \b ddmmyyyy european format day-month-year
  */
  calendardate(int day, int month, int year, int mode = mmddyyyy):
    day(day),month(month),year(year),mode(mode) 
    { 
      julian = Julian(); 
    }
  /*!
    Constructor
    \param julian jiulian date
    \param mode date format
    \arg \b mmddyyyy english format month-day-year
    \arg \b ddmmyyyy european format day-month-year
  */
  calendardate(long julian, int mode = mmddyyyy) : 
    julian(julian),mode(mode) 
    { 
      Caldate(); 
    }
  /*!
    Constructor
    \param s date string
    \param mode date format
    \arg \b mmddyyyy english format month-day-year
    \arg \b ddmmyyyy european format day-month-year
    \param sep separator char
  */
  calendardate(char* s, int mode = mmddyyyy, char* sep =".-/");
  /*!
    Destructor
   */
  virtual ~calendardate() {}

  /*! Return date as julian date */
  operator long() { return julian; }
  /*! Returns day index:  0 = sunday, 1 = monday,... 6 = saturday 
   */
  int DayIndex() { return (julian+1) % 7; }
  /*!
    Returns day
   */
  int Day() { return day; }
  /*!
    Returns month
   */
  int Month() { return month; }
  /*!
    Returns year
   */
  int Year() { return year; }
  /*!
    Returns an internal buffer formatted in
    "week-day month day year" format.
    \par Tip
    Do not modify directly this buffer, copy it before use.
   */
  char* CalendarDate();
  /*!
    date operations
    */
  calendardate operator+(long d)
    { return calendardate(julian+d); }
  calendardate operator-(long d)
    { return calendardate(julian-d); }
  long operator-(calendardate& d)
    { return julian - d.julian; }
  calendardate& operator+=(long d)
    { *this = calendardate (julian+d); return *this; }
  calendardate& operator-=(long d)
    { *this = calendardate (julian-d); return *this; }
  /*!
    Returns an internal buffer formatted in
    "dd/mm/yyyy" or "mm/dd/yyyy" format, do not modify directly
    this buffer, copy it before use
    */
  operator char*();
  /*!
    Returns an internal buffer formatted in "yyyymmdd" format, 
    do not modify directly this buffer, copy it before use
    */
  char* AsString();
  /*! validation */
  bool Valid() { return julian >= 0; }
  /*!
    relational operations
    */
  bool operator==(calendardate& d)
    { return julian == d.julian; }
  bool operator<(calendardate& d)
    { return julian < d.julian; }
  bool operator!=(calendardate& d)
    { return julian != d.julian; }
  bool operator>(calendardate& d)
    { return julian > d.julian; }
  bool operator>=(calendardate& d)
    { return julian >= d.julian; }
  bool operator<=(calendardate& d)
    { return julian <= d.julian; }
};
/* !
  leap year 
  */
inline bool Leap(int y)
{ return !(y%4) && ( y%100 || !(y%400)); }
/*!
  MakeDate()
  Makes a date
  \param s a string in ""yyyymmdd" format
*/
calendardate MakeDate(char* s, int mode = mmddyyyy);

#endif

