#ifndef _JEDIT_H
#define _JEDIT_H

//#include "calendar.h"

// user define messges
#define WM_JEDIT_CHAR				WM_USER + 7890
#define WM_JEDIT_USER_VALIDATE		WM_USER + 7891
#define WM_JEDIT_VALIDATE_ERROR		WM_USER + 7892
#define WM_JEDIT_MESSAGE_FORMAT		WM_USER + 7893
#define WM_JEDIT_DISPLAY_MESSAGE	WM_USER + 7894
#define WM_JEDIT_KILL_FOCUS     	WM_USER + 7895

////////////////////////////
// Following characters are used as template mask characters:

// A - upper case letters
// B - upper case letters or digits
// a - lower case letters
// b - lower case letters or digits
// X - upper or lower case letters
// Y - upper or lower case letters or digits
// 9 - digits
// ? - all characters 
// \\ - make the above mask characters non-mask characters

const char UPPER_LETTER			=	'A';
const char LOWER_LETTER			=	'a';
const char UPPER_LETTER_DIGIT	=	'B';
const char LOWER_LETTER_DIGIT	=	'b';
const char ALL_LETTER			=	'X';
const char ALL_LETTER_DIGIT		=	'Y';
const char ALL_CHARACTER		=	'?';
const char DIGIT				=	'9';
const char TRANS_MASK			=	'\\';

////////////////////////////

// date time format type:
//
// 1 - mm/dd/yyyy  (default)
// 2 - Month dd, yyyy
// 3 - mm/dd/yyyy hh:mm a(p)m  
// 4 - Month dd, yyyy hh:mm a(p)m
// 5 - mm/dd/yy
// 6 - mm/dd/yy hh:mm a(p)m  

const int SHORT_DATE					= 1;
const int LONG_DATE						= 2;
const int SHORT_DATE_TIME				= 3;
const int LONG_DATE_TIME				= 4;
const int SHORT_DATE_WO_CENTURY			= 5;
const int SHORT_DATE_TIME_WO_CENTURY	= 6;


/***********************************************************************
  CLASS:		 CBaseEdit

  BASE CLASS:	 CEdit
  
  Author:        Jan Xiang
  
  Date:          December 24, 1996
  
  Description:   This is the base class for all the other classes in JEdit.
				 It handles all the common tasks for the control.  
 **********************************************************************/
class AFX_EXT_CLASS CBaseEdit : public CEdit
{
    DECLARE_DYNCREATE(CBaseEdit)
public:
	CBaseEdit();  

	// set readonly
	void SetReadOnly(BOOL bReadOnly) { m_bReadOnly = bReadOnly; }
	// return TRUE if the control is modified
	BOOL IsModified() {  return m_bModified; }
	// return TRUE if the control is valid
	BOOL IsValid() { return m_bIsValid; }
	// set modify flag for the control
	void SetModifiedFlag(BOOL bModified) { m_bModified = bModified; }
	// set TRUE to allow the control to be emtpy
    void SetAllowEmpty(BOOL bAllowEmpty)
					{ m_bAllowEmpty = bAllowEmpty; } 
	// set TRUE to allow beep when there is invalid input
    void SetBeep(BOOL bBeep) { m_bBeep = bBeep; } 
	// set control's parent
	void SetParent(CWnd* pParent) { m_pParent = pParent; }
	// handle invalid user input
	void HandleInvalidInput();
	// set TRUE to make the control valid
	void SetDataValid(BOOL bIsValid) { m_bIsValid = bIsValid; }
	// return the error type
	int GetErrorType() { return m_iErrorType; }

	void SetWindowText(LPCTSTR lpszString);

protected:
	CWnd* m_pParent;    
	BOOL m_bBeep;
    BOOL m_bModified;
	BOOL m_bIsValid;
    BOOL m_bAllowEmpty;   
    BOOL m_bAllowCharPass;   
	BOOL m_bReadOnly;

	BOOL SubclassWindow(HWND hWndCtrl);
    void SetErrorMessage(LPCSTR szEmptyErrorMsg, LPCSTR szMinErrorMsg,
						LPCSTR szMaxErrorMsg, LPCSTR szInvalidErrorMsg);
    void SetErrorMessage(UINT idEmptyErrorMsg, UINT idMinErrorMsg,
						UINT idMaxErrorMsg, UINT idInvalidErrorMsg);
	CString GetStringFromID(UINT nStringID);

    void SetDefaultErrorMessage(LPCSTR szErrorMsg);
	void SetErrorType(int iErrorType);
	BOOL NeedResetFocus(CWnd* pNewWnd);
	void HandleInvalidChar();
	void GetModifiedText(CString& sText, char nChar, int iSelStart, int iSelEnd);
	BOOL ValidateEmpty(CString& sErrorMsg);

	void DisplayErrorMessage();
	void DispMessageBox(LPCSTR szMessage);
	void DispMessageBox(UINT nMessageID);

	virtual BOOL IsEmpty(const CString& sData);

    //{{AFX_MSG(CBaseEdit)
	afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
	afx_msg void OnLButtonDblClk(UINT nFlags, CPoint point);
	afx_msg void OnSetFocus(CWnd* pOldWnd);
	afx_msg void OnPaint();
    afx_msg void OnDestroy();
	afx_msg void OnKillFocus(CWnd* pNewWnd);
	afx_msg void OnChar(UINT nChar, UINT nRepCnt, UINT nFlags);
	afx_msg void OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags);
	afx_msg void OnDropFiles(HDROP hDropInfo);
	//}}AFX_MSG

    DECLARE_MESSAGE_MAP()

private:
	int	m_iErrorType;
	CString m_sEmptyErrorMsg;
	CString m_sMinErrorMsg;
	CString m_sMaxErrorMsg;
	CString m_sInvalidErrorMsg;
	CString m_sDefaultErrorMsg;
};


/***********************************************************************
  CLASS:		 CNumEdit

  BASE CLASS:	 CBaseEdit
  
  Author:        Jan Xiang
  
  Date:          December 24, 1996
  
  Description:   This is the base class for all the float numeric classes in JEdit.
				 It handles all the common tasks for the float numeric control.  
 **********************************************************************/
class AFX_EXT_CLASS CNumEdit : public CBaseEdit
{
    DECLARE_DYNCREATE(CNumEdit)
public:
	// set minimum value
	void SetMinValue(double dMin);
	// set maximum value
	void SetMaxValue(double dMax);
	// set decimal position
    void SetDecimal(int iDecimal);
	// set error message
    void SetErrorMessage(LPCSTR szEmptyErrorMsg="", 
						LPCSTR szMinErrorMsg="",
						LPCSTR szMaxErrorMsg="");
    void SetErrorMessage(UINT idEmptyErrorMsg=0, 
						UINT idMinErrorMsg=0,
						UINT idMaxErrorMsg=0);

	CNumEdit();
	BOOL SubclassWindow(HWND hWndCtrl);
    BOOL ValidateData();
	BOOL ValidateEmpty();
         
protected:
	double m_dVal;
	double m_dMin;
	double m_dMax;
	int m_iDecimal;   
	BOOL m_bSetMinValue;   
	BOOL m_bSetMaxValue;   

	virtual void DisplayValue();
	virtual BOOL CheckRange();
	virtual void UpdateValue();
	virtual BOOL IsEmpty(const CString& sData);

	CString FormatValue(double dVal);

    //{{AFX_MSG(CNumEdit)
	afx_msg void OnChar(UINT nChar, UINT nRepCnt, UINT nFlags);
	afx_msg void OnKillFocus(CWnd* pNewWnd);
    //}}AFX_MSG

    DECLARE_MESSAGE_MAP()
};


/***********************************************************************
  CLASS:		 CIntNumEdit

  BASE CLASS:	 CBaseEdit
  
  Author:        Jan Xiang
  
  Date:          December 24, 1996
  
  Description:   This is the base class for all the integer numeric classes in JEdit.
				 It handles all the common tasks for the integer numeric control.  
 **********************************************************************/
class AFX_EXT_CLASS CIntNumEdit : public CBaseEdit
{
    DECLARE_DYNCREATE(CIntNumEdit)
public:
	// set minimum value
	void SetMinValue(long lMin);
	// set maximum value
	void SetMaxValue(long lMax);
	// set error message
    void SetErrorMessage(LPCSTR szEmptyErrorMsg="", 
						LPCSTR szMinErrorMsg="",
						LPCSTR szMaxErrorMsg="");
    void SetErrorMessage(UINT idEmptyErrorMsg=0, 
						UINT idMinErrorMsg=0,
						UINT idMaxErrorMsg=0);

	CIntNumEdit();
	BOOL SubclassWindow(HWND hWndCtrl);
    BOOL ValidateData();
	BOOL ValidateEmpty();
	
protected:
	long m_lVal;
	long m_lMin;
	long m_lMax;
	BOOL m_bSetMinValue;   
	BOOL m_bSetMaxValue;   

	virtual void DisplayValue();
	virtual BOOL CheckRange();
	virtual void UpdateValue();
	virtual BOOL IsEmpty(const CString& sData);
	virtual BOOL ValidateInteger() { return TRUE; }

    //{{AFX_MSG(CIntNumEdit)
	afx_msg void OnChar(UINT nChar, UINT nRepCnt, UINT nFlags);
	afx_msg void OnKillFocus(CWnd* pNewWnd);
    //}}AFX_MSG

    DECLARE_MESSAGE_MAP()
};

/***********************************************************************
  CLASS:		 CIntEdit

  BASE CLASS:	 CIntNumEdit
  
  Author:        Jan Xiang
  
  Date:          December 24, 1996
  
  Description:   This is the class for integer. It only allows users
				 to enter integer into the control, and the control
				 variable behaviour like an integer variable.
 **********************************************************************/
class AFX_EXT_CLASS CIntEdit : public CIntNumEdit
{
public:
	CIntEdit();
	CIntEdit(int value);

    BOOL operator==(CIntEdit& value);
    BOOL operator!=(CIntEdit& value);
    BOOL operator>=(CIntEdit& value);
    BOOL operator>(CIntEdit& value);
    BOOL operator<=(CIntEdit& value);
    BOOL operator<(CIntEdit& value);         
    
    CIntEdit& operator+(CIntEdit& value);
    CIntEdit& operator-(CIntEdit& value);
    CIntEdit& operator*(CIntEdit& value);
    CIntEdit& operator/(CIntEdit& value);
    CIntEdit& operator+(int value);
    CIntEdit& operator-(int value);
    
    CIntEdit& operator+=(const CIntEdit& value);
    CIntEdit& operator-=(const CIntEdit& value);
    CIntEdit& operator*=(const CIntEdit& value);
    CIntEdit& operator/=(const CIntEdit& value);

    CIntEdit& operator=(const CIntEdit& value);
    operator int() const;

	int GetValue() const;
	void SetValue(int value);

protected:
	virtual BOOL ValidateInteger();
};


/***********************************************************************
  CLASS:		 CDoubleEdit

  BASE CLASS:	 CNumEdit
  
  Author:        Jan Xiang
  
  Date:          December 24, 1996
  
  Description:   This is the class for double. It only allows users
				 to enter double into the control, and the control
				 variable behaviour like a double variable.
 **********************************************************************/
class AFX_EXT_CLASS CDoubleEdit : public CNumEdit
{
public:
	CDoubleEdit();
	CDoubleEdit(double value);

    BOOL operator==(CDoubleEdit& value);
    BOOL operator!=(CDoubleEdit& value);
    BOOL operator>=(CDoubleEdit& value);
    BOOL operator>(CDoubleEdit& value);
    BOOL operator<=(CDoubleEdit& value);
    BOOL operator<(CDoubleEdit& value);         
    
    CDoubleEdit& operator+(CDoubleEdit& value);
    CDoubleEdit& operator-(CDoubleEdit& value);
    CDoubleEdit& operator*(CDoubleEdit& value);
    CDoubleEdit& operator/(CDoubleEdit& value);
    
    CDoubleEdit& operator+=(const CDoubleEdit& value);
    CDoubleEdit& operator-=(const CDoubleEdit& value);
    CDoubleEdit& operator*=(const CDoubleEdit& value);
    CDoubleEdit& operator/=(const CDoubleEdit& value);

    CDoubleEdit& operator=(const CDoubleEdit& value);
    operator double() const;

	double GetValue() const;
	void SetValue(double value);
};


/***********************************************************************
  CLASS:		 CShortEdit

  BASE CLASS:	 CIntNumEdit
  
  Author:        Jan Xiang
  
  Date:          December 24, 1996
  
  Description:   This is the class for short. It only allows users
				 to enter short into the control, and the control
				 variable behaviour like a short variable.
 **********************************************************************/
class AFX_EXT_CLASS CShortEdit : public CIntNumEdit
{
public:
	CShortEdit();
	CShortEdit(short value);

    BOOL operator==(CShortEdit& value);
    BOOL operator!=(CShortEdit& value);
    BOOL operator>=(CShortEdit& value);
    BOOL operator>(CShortEdit& value);
    BOOL operator<=(CShortEdit& value);
    BOOL operator<(CShortEdit& value);         
    
    CShortEdit& operator+(CShortEdit& value);
    CShortEdit& operator-(CShortEdit& value);
    CShortEdit& operator*(CShortEdit& value);
    CShortEdit& operator/(CShortEdit& value);
    CShortEdit& operator+(short value);
    CShortEdit& operator-(short value);
    
    CShortEdit& operator+=(const CShortEdit& value);
    CShortEdit& operator-=(const CShortEdit& value);
    CShortEdit& operator*=(const CShortEdit& value);
    CShortEdit& operator/=(const CShortEdit& value);

    CShortEdit& operator=(const CShortEdit& value);
    operator short() const;

	short GetValue() const;
	void SetValue(short value);

protected:
	virtual BOOL ValidateShort();
};


/***********************************************************************
  CLASS:		 CLongEdit

  BASE CLASS:	 CIntNumEdit
  
  Author:        Jan Xiang
  
  Date:          December 24, 1996
  
  Description:   This is the class for long. It only allows users
				 to enter long into the control, and the control
				 variable behaviour like a long variable.
 **********************************************************************/
class AFX_EXT_CLASS CLongEdit : public CIntNumEdit
{
public:
	CLongEdit();
	CLongEdit(long value);

    BOOL operator==(CLongEdit& value);
    BOOL operator!=(CLongEdit& value);
    BOOL operator>=(CLongEdit& value);
    BOOL operator>(CLongEdit& value);
    BOOL operator<=(CLongEdit& value);
    BOOL operator<(CLongEdit& value);         
    
    CLongEdit& operator+(CLongEdit& value);
    CLongEdit& operator-(CLongEdit& value);
    CLongEdit& operator*(CLongEdit& value);
    CLongEdit& operator/(CLongEdit& value);
	CLongEdit& operator+(long value);
    CLongEdit& operator-(long value);
    
    CLongEdit& operator+=(const CLongEdit& value);
    CLongEdit& operator-=(const CLongEdit& value);
    CLongEdit& operator*=(const CLongEdit& value);
    CLongEdit& operator/=(const CLongEdit& value);

    CLongEdit& operator=(const CLongEdit& value);
    operator long() const;

	long GetValue() const;
	void SetValue(long value);

protected:
	virtual BOOL ValidateLong();
};


/***********************************************************************
  CLASS:		 CFloatEdit

  BASE CLASS:	 CNumEdit
  
  Author:        Jan Xiang
  
  Date:          December 24, 1996
  
  Description:   This is the class for float. It only allows users
				 to enter float into the control, and the control
				 variable behaviour like a float variable.
 **********************************************************************/
class AFX_EXT_CLASS CFloatEdit : public CNumEdit
{
public:
	CFloatEdit();
	CFloatEdit(float value);
	CFloatEdit(double value);

    BOOL operator==(CFloatEdit& value);
    BOOL operator!=(CFloatEdit& value);
    BOOL operator>=(CFloatEdit& value);
    BOOL operator>(CFloatEdit& value);
    BOOL operator<=(CFloatEdit& value);
    BOOL operator<(CFloatEdit& value);         
    
    CFloatEdit& operator+(CFloatEdit& value);
    CFloatEdit& operator-(CFloatEdit& value);
    CFloatEdit& operator*(CFloatEdit& value);
    CFloatEdit& operator/(CFloatEdit& value);
    
    CFloatEdit& operator+=(const CFloatEdit& value);
    CFloatEdit& operator-=(const CFloatEdit& value);
    CFloatEdit& operator*=(const CFloatEdit& value);
    CFloatEdit& operator/=(const CFloatEdit& value);

    CFloatEdit& operator=(const CFloatEdit& value);
    CFloatEdit& operator=(float value);
    CFloatEdit& operator=(double value);
    operator float() const;

	float GetValue() const;
	void SetValue(float value);
};


/***********************************************************************
  CLASS:		 CCurrencyEdit

  BASE CLASS:	 CNumEdit
  
  Author:        Jan Xiang
  
  Date:          December 24, 1996
  
  Description:   This is the class for currency. It behaviors like CDoubleEdit
				 but has '$' sign and some special format.
 **********************************************************************/
class AFX_EXT_CLASS CCurrencyEdit : public CNumEdit
{
public:
	CCurrencyEdit();
	CCurrencyEdit(double value);

    BOOL operator==(CCurrencyEdit& value);
    BOOL operator!=(CCurrencyEdit& value);
    BOOL operator>=(CCurrencyEdit& value);
    BOOL operator>(CCurrencyEdit& value);
    BOOL operator<=(CCurrencyEdit& value);
    BOOL operator<(CCurrencyEdit& value);         
  
    CCurrencyEdit& operator+(CCurrencyEdit& value);
    CCurrencyEdit& operator-(CCurrencyEdit& value);
    CCurrencyEdit& operator*(CCurrencyEdit& value);
    CCurrencyEdit& operator/(CCurrencyEdit& value);
    
    CCurrencyEdit& operator+=(const CCurrencyEdit& value);
    CCurrencyEdit& operator-=(const CCurrencyEdit& value);
    CCurrencyEdit& operator*=(const CCurrencyEdit& value);
    CCurrencyEdit& operator/=(const CCurrencyEdit& value);

    CCurrencyEdit& operator=(const CCurrencyEdit& value);
    operator double() const;

	double GetValue() const;
	void SetValue(double value);

protected:
	virtual void DisplayValue();
	virtual BOOL CheckRange();
	virtual void UpdateValue();

    //{{AFX_MSG(CCurrencyEdit)
	afx_msg void OnChar(UINT nChar, UINT nRepCnt, UINT nFlags);
	afx_msg void OnKillFocus(CWnd* pNewWnd);
    //}}AFX_MSG

    DECLARE_MESSAGE_MAP()
    
private:
	void AddSymbols(CString& sData);
	void GetRidOfSymbols(CString& sData);    
};


/***********************************************************************
  CLASS:		 CTemplateEdit

  BASE CLASS:	 CBaseEdit
  
  Author:        Jan Xiang
  
  Date:          December 24, 1996
  
  Description:   This is the base class for CStringEdit and CDateTimeEdit. 
				 It allows users to set template and validate the control
				 according to the template. The user can set up to ten
				 templates for one control. The template can be checked
				 character by character or checked after user finished
				 entering in the control.
 **********************************************************************/
class AFX_EXT_CLASS CTemplateEdit : public CBaseEdit
{
    DECLARE_DYNCREATE(CTemplateEdit)
public:
	// set TRUE to allow check the control character by character
    void SetActiveTemplate(BOOL bActiveTemplate)
					{ m_bActiveTemplate = bActiveTemplate; }
                          
	// set the ten templates
	void SetTemplate(LPCSTR sTemplate1, LPCSTR sTemplate2="",
			LPCSTR sTemplate3="", LPCSTR sTemplate4="",
			LPCSTR sTemplate5="", LPCSTR sTemplate6="",
			LPCSTR sTemplate7="", LPCSTR sTemplate8="",
			LPCSTR sTemplate9="", LPCSTR sTemplate10="");
	// set error message
    void SetErrorMessage(LPCSTR szEmptyErrorMsg="", 
						LPCSTR szInvalidErrorMsg="");
    void SetErrorMessage(UINT szEmptyErrorMsg=0, 
						UINT szInvalidErrorMsg=0);

	BOOL SubclassWindow(HWND hWndCtrl);
    BOOL ValidateData();       
	BOOL ValidateEmpty();

protected:                  
	CString m_sData;  
    CString m_sTemplate1;  // 10 template
    CString m_sTemplate2;
    CString m_sTemplate3;
    CString m_sTemplate4;
    CString m_sTemplate5;

    CString m_sTemplate6;
    CString m_sTemplate7;
    CString m_sTemplate8;
    CString m_sTemplate9;
    CString m_sTemplate10;
    BOOL m_bActiveTemplate;  // flag to indicate if do active template check or not

	CTemplateEdit();

	BOOL IsMask(const CString& sTemplate, int iPos);
    BOOL MatchOK(const CString& sTemplate, int iTemplatePos, int nChar);
    BOOL GetMaskTemplate(const CString& sTemplate, CString& sOut);
    int ActiveTemplateCheck(const CString& sTemplate, UINT nChar, int& iPos);
    BOOL IsStringEmpty(const CString& sTemplate, CString& sWindowText);
    int TemplateLenWoSlash(const CString& sTemplate);
    void GetRidOfPrevSlash(int iPos, CString& sOut);
    BOOL DeleteOneChar(const CString& sTemplate, CString& sWindowText, int iSelStart);
    BOOL DeleteInTemplate(const CString& sTemplate, CString& sText, int iSelStart, int iSelEnd);
    int CountSlashToLength(LPCSTR sText, int iDelLen);
    void DelMaskInTemplate(const CString& sTemplate, CString& sText, int iDelLen);
    void FindMatchedTemplate(CStringList& matchedTemplateList, const CString& sWindowText);
    BOOL IsTextMatchTemplate(const CString& sText, const CString& sTemplate, BOOL bAllowSpace);
	BOOL GetMatchedTemplate(CStringList& matchedTemplateList, CString& sTemplate);
	int CopyTemplToText(CString& sWindowText, const CString& sTemplate, int iSvSelStart, int& iSelStart);
                           
    void UpdateData();
	void DisplayValue();
	void TrimLeft(CString& sStr);
	void TrimRight(CString& sStr);
    virtual BOOL CheckData(CString& sErrorMsg, const CString& sData);

    //{{AFX_MSG(CTemplateEdit)
	afx_msg void OnChar(UINT nChar, UINT nRepCnt, UINT nFlags);
	afx_msg void OnKillFocus(CWnd* pNewWnd);
    afx_msg void OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags);
    //}}AFX_MSG

    DECLARE_MESSAGE_MAP()
};


/***********************************************************************
  CLASS:		 CStringEdit

  BASE CLASS:	 CTemplateEdit
  
  Author:        Jan Xiang
  
  Date:          December 24, 1996
  
  Description:   This is an all-purpose string control class. The control variable
				 behaviors like a CString for programmer's convenience. The control
				 can be set up in such a way so that users can only enter certain
				 characters into the control or enter them in some special ways 
				 depending on the templates.
 **********************************************************************/
class AFX_EXT_CLASS CStringEdit : public CTemplateEdit
{
  public:
    CStringEdit();  // standard constructor
	CStringEdit(LPCSTR sData);
	CStringEdit(const CStringEdit& sData);

    operator CString() const;            
    CStringEdit& operator=(LPCSTR sData);  
    CStringEdit& operator+=(LPCSTR sData);  
    CStringEdit& operator+(CStringEdit& sData);
    CStringEdit& operator=(const CStringEdit& sData);
    CStringEdit& operator+=(const CStringEdit& sData);

    BOOL operator==(CStringEdit& sData);
    BOOL operator!=(CStringEdit& sData);
    BOOL operator>=(CStringEdit& sData);
    BOOL operator>(CStringEdit& sData);
    BOOL operator<=(CStringEdit& sData);
    BOOL operator<(CStringEdit& sData);

    //CString functions         
    BOOL IsEmpty();
    void MakeUpper();
    void MakeLower();
    int GetLength() const;
    char GetAt(int index) const;
    char operator[](int index) const;
    void SetAt(int index, char ch);
    int CompareNoCase(LPCSTR pszText) const;
    CString Mid(int first, int count) const;
    CString Mid(int first) const;
    CString Left(int count) const;
    CString Right(int count) const;
    void MakeReverse();
    CString SpanIncluding(LPCSTR pszString);
    CString SpanExcluding(LPCSTR pszString);
    int Find(char ch);
    int Find(LPCSTR pszString);
    int FindOneOf(LPCSTR pszString);
    int ReverseFind(char ch);
    BOOL LoadString(UINT nID);
    void AnsiToOem();
    void OemToAnsi();
    LPSTR GetBuffer(int bufSize);
    LPSTR GetBufferSetLength(int newLength);
    void ReleaseBuffer(int newLength=-1);
	void TrimLeft();
	void TrimRight();
};

/***********************************************************************
  CLASS:		 CDateTimeEdit

  BASE CLASS:	 CTemplateEdit
  
  Author:        Jan Xiang
  
  Date:          December 24, 1996
  
  Description:   This is the class to edit date/time. The date/time can be
				 displayed in different formats. The control validates users
				 input and make sure the date/time is good and in valid range.
 **********************************************************************/
class AFX_EXT_CLASS CDateTimeEdit : public CTemplateEdit
{
    DECLARE_DYNCREATE(CDateTimeEdit)
public:
    CDateTimeEdit();
	CDateTimeEdit(LPCSTR sData);
	CDateTimeEdit(const CTime& time);
    CDateTimeEdit(const CDateTimeEdit& sData);

	// set minimum date/time
	void SetMinDate(LPCSTR szData);
	void SetMinDate(const CTime& time);
	// set maximum date/time
	void SetMaxDate(LPCSTR szData);
	void SetMaxDate(const CTime& time);

	// set date format
    void SetFormat(int iFormat);
    int GetFormat() const { return m_iFormat; }
	// set error message
    void SetErrorMessage(LPCSTR szEmptyErrorMsg="", 
						LPCSTR szMinErrorMsg="",
						LPCSTR szMaxErrorMsg="",
						LPCSTR szInvalidErrorMsg="");
    void SetErrorMessage(UINT idEmptyErrorMsg=0, 
						UINT idMinErrorMsg=0,
						UINT idMaxErrorMsg=0,
						UINT idInvalidErrorMsg=0);

	BOOL SubclassWindow(HWND hWndCtrl);

    operator CString() const;            
    operator CTime();            
    CDateTimeEdit& operator=(LPCSTR sData);  
    CDateTimeEdit& operator=(const CTime& sData);  
    CDateTimeEdit& operator=(const CDateTimeEdit& sData);  

    BOOL operator==(const CDateTimeEdit& sData);
    BOOL operator!=(const CDateTimeEdit& sData);
    BOOL operator>=(const CDateTimeEdit& sData);
    BOOL operator<=(const CDateTimeEdit& sData);
    BOOL operator>(const CDateTimeEdit& sData);
    BOOL operator<(const CDateTimeEdit& sData);         

    BOOL operator==(const CTime& time);
    BOOL operator!=(const CTime& time);
    BOOL operator>=(const CTime& time);
    BOOL operator<=(const CTime& time);
    BOOL operator>(const CTime& time);
    BOOL operator<(const CTime& time);         

    BOOL operator==(LPCSTR szData);
    BOOL operator!=(LPCSTR szData);
    BOOL operator>=(LPCSTR szData);
    BOOL operator<=(LPCSTR szData);
    BOOL operator>(LPCSTR szData);
    BOOL operator<(LPCSTR szData);         

    BOOL operator==(const CString& sData);
    BOOL operator!=(const CString& sData);
    BOOL operator>=(const CString& sData);
    BOOL operator<=(const CString& sData);
    BOOL operator>(const CString& sData);
    BOOL operator<(const CString& sData);         

protected:
	virtual BOOL CheckData(CString& sErrorMsg, const CString& sData);

    //{{AFX_MSG(CDateTimeEdit)
	afx_msg void OnLButtonDblClk(UINT nFlags, CPoint point); 
    //}}AFX_MSG

    DECLARE_MESSAGE_MAP()

private:
	int m_iFormat;
	BOOL m_bShowInvalidFlag;
	CString m_sMinDate;
	CString m_sMaxDate;
                                                       
	void CheckFormat();                                                       
	BOOL ValidateDate(int iYear, int iMonth, int iDay);
	BOOL ValidateTime(int iHour, int iMinute);
	BOOL IsLeapYear(int iYear);
	int MaxDaysInMonth(int iMonth, int iYear);
	BOOL GetDateTime (const CString& sData, int& iYear, int& iMonth, int& iDay, int& iHour, int& iMinute); 
	BOOL GetTime(const CString& sData, int& iHour, int& iMinute);
	int MonthStoN(LPCSTR szMonth);
	CString MonthNtoS(int iMonth);
	CString ExtractLeft(CString& sData, char cutChar);
	BOOL IsNum(LPCSTR szData);
	BOOL IsLetter(LPCSTR szData);
	void AssignTemplateToFormat();
	int GetFormatByData(LPCSTR szData);
	void TransferDataByFormat(int iOldFormat, int iNewFormat);

	void AssignCTime(const CTime& time);
	void AssignString(LPCSTR szData);
	void AssignDateTimeEdit(const CDateTimeEdit& sData);
};

///////////////////////////////////
///////////////////////////////////
// Global functions
///////////////////////////////////
///////////////////////////////////

// TRUE if any one of the JEdit controls in a dialog is modified
BOOL AFX_EXT_API IsJEditModified();
// set the modified flag
void AFX_EXT_API SetJEditModified(BOOL bJEditModified);
// set TRUE to validate control when the control losing focus
void AFX_EXT_API SetJEditValidateKillFocus(BOOL bgJEditValidateType); 
// set TRUE to allow displaying error message when error occurs
void AFX_EXT_API SetJEditKillFocusShowErrMsg(BOOL bJEditKillFocusShowErrMsg);
// TRUE if a validation OK
BOOL AFX_EXT_API IsJEditValidateOK();

// DDX_CONTROL for JEdit controls
void AFX_EXT_API DDX_JEditControl(CDataExchange* pDX, int nIDC, CBaseEdit& rControl);
  
#endif // _JEDIT_H
