#ifndef _COMMON_SDATE_HPP_
#define _COMMON_SDATE_HPP_
#ifndef _COMMON_STRING_HPP_
#include <common/string.hpp>
#endif

typedef struct CompatibleDate
{
	unsigned Day : 8;
	unsigned Month : 8;
	unsigned Year : 16;
}COMPATIBLEDATE;

class SDate : public CompatibleDate
{
public:
	enum Options{TodaysDate};
	SDate(void);
	SDate(long someLongDate);
	SDate(const SDate &someDate);
	SDate(unsigned char month,unsigned char day,unsigned year);
	SDate(const CompatibleDate &someDate);
	SDate(Options dateOptions);
  SDate(const String &someString);
	virtual ~SDate();
	SDate &operator=(const CompatibleDate &someCompatibleDate);
	SDate &operator=(long someLongDate);
  SDate &operator=(const String &someString);
	int operator<(const CompatibleDate &someDate)const;
	int operator>(const CompatibleDate &someDate)const;
	int operator==(const CompatibleDate &someDate)const;
	int operator<=(const CompatibleDate &someDate)const;
	short operator-(const SDate &someDate);
  SDate &operator+=(short dayCount);
	String makeString(void)const;
	String toString(void)const;
	long makeLong(void)const;
	int month(void)const;
	int day(void)const;
	int year(void)const;
	void month(int newMonth);
	void day(int newDay);
	void year(int newYear);
	short monthsBetween360(SDate toDate)const;
	short daysBetween360(SDate toDate)const;
	short daysBetweenActual(SDate toDate)const;
	short daysBetweenActual(SDate fromDate,SDate toDate)const;
	SDate daysAdd360(short dayCount);
	SDate daysAddActual(short actualDays)const;
	SDate daysAddActual(SDate fromDate,short actualDays)const;
	short stringToMonth(char *str)const;
private:
	void initArray(void);
	SDate stringToMonthDay(char *first,char *second);
	SDate stringToMonthYear(char *first,char *second);
	SDate monthYearStringToDate(char *str,short default_day=1);
  short monthsBetween360(SDate fromDate,SDate toDate)const;
	short daysBetween360(SDate fromDate,SDate toDate)const;
	void getTodaysDate(void);
	WORD mDayArray[13];
};

inline
SDate::SDate(const String &someString)
{
  initArray();
	*this=monthYearStringToDate((char*)((String&)someString));
}

inline
SDate &SDate::operator=(const String &someString)
{
	*this=monthYearStringToDate((char*)((String&)someString));
	return *this;
}

inline
short SDate::operator-(const SDate &someDate)
{
	return daysBetweenActual(*this,someDate);
}

inline
SDate &SDate::operator+=(short dayCount)
{
	*this=daysAdd360(dayCount);
  return *this;
}

inline
void SDate::initArray(void)
{
	mDayArray[0]=0;
	mDayArray[1]=31;
	mDayArray[2]=29;
	mDayArray[3]=31;
	mDayArray[4]=30;
	mDayArray[5]=31;
	mDayArray[6]=30;
	mDayArray[7]=31;
	mDayArray[8]=31;
	mDayArray[9]=30;
	mDayArray[10]=31;
	mDayArray[11]=30;
	mDayArray[12]=31;
}

inline
short SDate::daysBetween360(SDate toDate)const
{
  return daysBetween360(*this,toDate);
}

inline
short SDate::monthsBetween360(SDate toDate)const
{
	return monthsBetween360(*this,toDate);
}

inline
short SDate::monthsBetween360(SDate fromDate,SDate toDate)const
{
  return daysBetween360(fromDate,toDate)/30;
}

inline
String SDate::toString(void)const
{
  return makeString();
}
#endif

