/////////////////////////////////////////////////////////////
// CINEMA 4D SDK                                           //
/////////////////////////////////////////////////////////////
// (c) 1989-2004 MAXON Computer GmbH, all rights reserved  //
/////////////////////////////////////////////////////////////

#ifndef _CUSTOMGUI_DATE_EDIT_H_
#define _CUSTOMGUI_DATE_EDIT_H_

#define DATETIME_GUI      1009383
#define DATETIME_DATA     1009398

#define DATETIME_TIME_CONTROL 'dttc'    // TRUE, if this is a clock
#define DATETIME_DATE_CONTROL 'dtdc'    // TRUE, if this is a calendar
#define DATETIME_COLUMN       'dtco'    // TRUE, if the calendar and the clock should be in one column
#define DATETIME_TIME_NOW     'dttn'    // TRUE, if the clock has a "now" button
#define DATETIME_DATE_TODAY   'dtdt'    // TRUE, if the calendar has a "today" button
#define DATETIME_CLOCK_OPEN   'dtcl'    // TRUE, if the clock is visible
#define DATETIME_CALENDAR_OPEN   'dtca'    // TRUE, if the calendar is open
#define DATETIME_COMPACT_MODE 'dtcm'    // TRUE, if you want a compact mode
#define DATETIME_COMPACT_OPEN 'dtco'    // TRUE, if the compact mode is open
#define DATETIME_NO_DATE_COLLAPSE 'dtda'    // TRUE, if the date open/close arrow should be hidden
#define DATETIME_NO_TIME_COLLAPSE 'dtta'    // TRUE, if the time open/close arrow should be hidden
#define DATETIME_NO_SECONDS 'dtns'    // don't show seconds in the GUI

#include "customgui_base.h"
#include "c4d_basecontainer.h"
#include "c4d_gui.h"
#include "c4d_customdatatype.h"


struct tagDateTime
{
	tagDateTime() { lYear=2000; lMonth=lDay=1; lHour=lMinute=lSecond=0; }

  LONG lYear, lMonth, lDay;
  LONG lHour, lMinute, lSecond;

	Bool operator == (const tagDateTime &b) const;
	Bool operator != (const tagDateTime &b) const;
	Bool operator <= (const tagDateTime &b) const;
	Bool operator < (const tagDateTime &b) const;
	Bool operator >= (const tagDateTime &b) const;
	Bool operator > (const tagDateTime &b) const;
};

LONG CompareDateTime(const tagDateTime &a, const tagDateTime &b);

class DateTimeControl : public BaseCustomGui<DATETIME_GUI>
{
private:
	DateTimeControl();
	~DateTimeControl();

public:
  tagDateTime GetDateTime();
  void SetDateTime(tagDateTime *d, Bool bSetDate = TRUE, Bool bSetTime = TRUE);
};


class DateTimeData : public iCustomDataType<DateTimeData>
{
private:
  DateTimeData();
  ~DateTimeData();

public:
	static DateTimeData* Alloc();
	static void Free(DateTimeData *&pData);

  tagDateTime GetDateTime();
  void SetDateTime(tagDateTime *d, Bool bSetDate = TRUE, Bool bSetTime = TRUE);
};

// generates a modified the julian day. To get the correct Julian day,
// take the integer of this value and subtract .5
LReal GetJulianDay(tagDateTime &t);
tagDateTime FromJulianDay(LReal j);
void DateTimeNow(tagDateTime& t);
// converts local time to GMT depending on the OS time zone settings, tGMT is set to tLocal in case of an error
// returns false if the local date is before Jan 1 of 1970, 2.01 am or after Jan 18, 2038 7 pm
Bool GetGMTime(const tagDateTime &tLocal, tagDateTime &tGMT); // converts local time to GMT depending on the OS time zone settings, tGMT is set to tLocal in case of an error
Bool GetLocalTime(const tagDateTime &tGMT, tagDateTime &tLocal); // converts GMT to local time depending on the OS time zone settings, tLocal is set to tGMT in case of an error
LONG GetDayOfWeek(LONG lYear, LONG lMonth, LONG lDay); // monday = 0
String FormatTime(const char* pszFormat, tagDateTime &t);

// INTERNAL STUFF -- INTERNAL STUFF -- INTERNAL STUFF -- INTERNAL STUFF -- INTERNAL STUFF
// INTERNAL STUFF -- INTERNAL STUFF -- INTERNAL STUFF -- INTERNAL STUFF -- INTERNAL STUFF
// INTERNAL STUFF -- INTERNAL STUFF -- INTERNAL STUFF -- INTERNAL STUFF -- INTERNAL STUFF


#ifndef _DATETIMECONTROL_INTERNAL_DEF_
	class iDateTimeControl : public iBaseCustomGui
	{
		iDateTimeControl(const BaseContainer &settings,CUSTOMGUIPLUGIN *plugin) : iBaseCustomGui(settings,plugin) { }
	};
	class iDateTimeData
	{
	};
#else
	class iDateTimeControl;
	class iDateTimeData;
#endif

struct DateTimechooserLib : public BaseCustomGuiLib
{
	tagDateTime      (iDateTimeControl::*GetDateTimeGUI)();
	void             (iDateTimeControl::*SetDateTimeGUI)(tagDateTime *d, Bool bSetDate, Bool bSetTime);

	tagDateTime      (iDateTimeData::*GetDateTimeData)();
	void             (iDateTimeData::*SetDateTimeData)(tagDateTime *d, Bool bSetDate, Bool bSetTime);

  LReal             (*GetJulianDay)(tagDateTime &t);
  tagDateTime       (*FromJulianDay)(LReal j);
  void              (*DateTimeNow)(tagDateTime& t);
  Bool              (*GetGMTime)(const tagDateTime &tLocal, tagDateTime &tGMT);
  Bool              (*GetLocalTime)(const tagDateTime &tGMT, tagDateTime &tLocal);
  LONG              (*GetDayOfWeek)(LONG lYear, LONG lMonth, LONG lDay);

	DateTimeData*			(*DateTimeData_Alloc)();
	void							(*DateTimeData_Free)(DateTimeData *&pData);
	String						(*FormatTime)(const char* pszFormat, tagDateTime &t);
};

// INTERNAL STUFF -- INTERNAL STUFF -- INTERNAL STUFF -- INTERNAL STUFF -- INTERNAL STUFF
// INTERNAL STUFF -- INTERNAL STUFF -- INTERNAL STUFF -- INTERNAL STUFF -- INTERNAL STUFF
// INTERNAL STUFF -- INTERNAL STUFF -- INTERNAL STUFF -- INTERNAL STUFF -- INTERNAL STUFF


#endif // _CUSTOMGUI_DATE_EDIT_H_
