#if defined(_WIN32)
#ifndef _COMMON_SYSTEMTIME_HPP_
#define _COMMON_SYSTEMTIME_HPP_
#include <stdio.h>
#ifndef _COMMON_WINDOWS_HPP_
#include <common/windows.hpp>
#endif
#ifndef _COMMON_STRING_HPP_
#include <common/string.hpp>
#endif
#ifndef _COMMON_FILETIME_HPP_
#include <common/filetime.hpp>
#endif

class SystemTime : private SYSTEMTIME
{
public:
	enum Month{None,January,February,March,April,May,June,July,August,September,October,
						 November,December};
	enum Day{Sunday,Monday,Tuesday,Wednesday,Thursday,Friday,Saturday};
	SystemTime(void);
	SystemTime(const SystemTime &someSystemTime);
	SystemTime(WORD year,WORD month,WORD day,WORD hour=0,WORD minute=0,WORD second=0);
  SystemTime(const FileTime &someFileTime);
	SystemTime(const SYSTEMTIME &someSYSTEMTIME);
	virtual ~SystemTime();
	SystemTime &operator=(const SystemTime &someSystemTime);
	SystemTime &operator=(const SYSTEMTIME &someSYSTEMTIME);
	SystemTime &operator=(const FileTime &someFileTime);
	bool operator>(const SystemTime &someSystemTime)const;
  bool operator<(const SystemTime &someSystemTime)const;
	bool operator==(const SystemTime &someSystemTime)const;
	bool operator>=(const SystemTime &someSystemTime)const;
	WORD year(void)const;
	void year(WORD year);
	Month month(void)const;
	void month(Month month);
	Day dayOfWeek(void)const;
	void dayOfWeek(Day dayOfWeek);
	WORD day(void)const;
	void day(WORD day);
	WORD hour(void)const;
	void hour(WORD hour);
	WORD minute(void)const;
	void minute(WORD minute);
	WORD second(void)const;
	void second(WORD second);
	WORD milliseconds(void)const;
	void milliseconds(WORD milliseconds);
  void daysAdd360(short dayCount);
	void refresh(void);
	void systemTime(void);
	void localTime(void);
	SYSTEMTIME &getSYSTEMTIME(void);
	String toString(void)const;
  String toStringShort(void)const;
  void makeTime(WORD year,WORD month,WORD day,WORD hour,WORD minute,WORD second);
private:
  enum{LongestDaysInMonth=31};
	void getMonth(String &monthString)const;
	void getDay(String &dayString,bool shortName=false)const;
};

inline
SystemTime::SystemTime(void)
{
	refresh();
}

inline
SystemTime::SystemTime(const SystemTime &someSystemTime)
{
	*this=someSystemTime;
}

inline
SystemTime::SystemTime(const SYSTEMTIME &someSYSTEMTIME)
{
  *this=someSYSTEMTIME;
}

inline
SystemTime &SystemTime::operator=(const SYSTEMTIME &someSYSTEMTIME)
{
  ::memcpy(&getSYSTEMTIME(),&someSYSTEMTIME,sizeof(SYSTEMTIME));
	return *this;
}

inline
SystemTime::SystemTime(WORD year,WORD month,WORD day,WORD hour,WORD minute,WORD second)
{
  makeTime(year,month,day,hour,minute,second);
}

inline
SystemTime::SystemTime(const FileTime &someFileTime)
{
	*this=someFileTime;
}

inline
SystemTime::~SystemTime()
{
}

inline
SystemTime &SystemTime::operator=(const SystemTime &someSystemTime)
{
	year(someSystemTime.year());
	month(someSystemTime.month());
	dayOfWeek(someSystemTime.dayOfWeek());
	day(someSystemTime.day());
	hour(someSystemTime.hour());
	minute(someSystemTime.minute());
	second(someSystemTime.second());
	milliseconds(someSystemTime.milliseconds());
	return *this;
}

inline
SystemTime &SystemTime::operator=(const FileTime &someFileTime)
{
	::FileTimeToSystemTime(&((FILETIME&)someFileTime),&((SYSTEMTIME&)*this));
	return *this;
}

inline
bool SystemTime::operator==(const SystemTime &someSystemTime)const
{
	return (year()==someSystemTime.year()&&
					month()==someSystemTime.month()&&
					dayOfWeek()==someSystemTime.dayOfWeek()&&
					day()==someSystemTime.day()&&
					hour()==someSystemTime.hour()&&
					minute()==someSystemTime.minute()&&
					second()==someSystemTime.second()&&
					milliseconds()==someSystemTime.milliseconds());
}

inline
bool SystemTime::operator>=(const SystemTime &someSystemTime)const
{
  if(*this>someSystemTime)return true;
	return *this==someSystemTime;
}

inline
WORD SystemTime::year(void)const
{
	return SYSTEMTIME::wYear;
}

inline
void SystemTime::year(WORD year)
{
	SYSTEMTIME::wYear=year;
}

inline
SystemTime::Month SystemTime::month(void)const
{
	return (Month)SYSTEMTIME::wMonth;
}

inline
void SystemTime::month(Month month)
{
	SYSTEMTIME::wMonth=(WORD)month;
}

inline
SystemTime::Day SystemTime::dayOfWeek(void)const
{
	return (Day)SYSTEMTIME::wDayOfWeek;
}

inline
void SystemTime::dayOfWeek(Day dayOfWeek)
{
	SYSTEMTIME::wDayOfWeek=(WORD)dayOfWeek;
}

inline
WORD SystemTime::day(void)const
{
	return SYSTEMTIME::wDay;
}

inline
void SystemTime::day(WORD day)
{
  SYSTEMTIME::wDay=day;
}

inline
WORD SystemTime::hour(void)const
{
	return SYSTEMTIME::wHour;
}

inline
void SystemTime::hour(WORD hour)
{
  SYSTEMTIME::wHour=hour;
}

inline
WORD SystemTime::minute(void)const
{
	return SYSTEMTIME::wMinute;
}

inline
void SystemTime::minute(WORD minute)
{
	SYSTEMTIME::wMinute=minute;
}

inline
WORD SystemTime::second(void)const
{
	return SYSTEMTIME::wSecond;
}

inline
void SystemTime::second(WORD second)
{
  SYSTEMTIME::wSecond=second;
}

inline
WORD SystemTime::milliseconds(void)const
{
	return SYSTEMTIME::wMilliseconds;
}

inline
void SystemTime::milliseconds(WORD milliseconds)
{
	SYSTEMTIME::wMilliseconds=milliseconds;
}

inline
void SystemTime::refresh(void)
{
  localTime();
}

inline
void SystemTime::systemTime(void)
{
  ::GetSystemTime(&((SYSTEMTIME&)*this));
}

inline
void SystemTime::localTime(void)
{
  ::GetLocalTime(&((SYSTEMTIME&)*this));
}

inline
SYSTEMTIME &SystemTime::getSYSTEMTIME(void)
{
  return *this;
}
#endif
#endif
