/////////////////////////////////////////////////////////////////////////////
// Name:        wxMaskedTextCtrl.h
// Purpose:     wxMaskedTextCtrl: masked edit control class
// Author:      Thomas Härtel
// Modified by:
// Created:     2002-11-14
// RCS-ID:      $Id: wxMaskedTextCtrl.h,v $
// Copyright:   (c) Thomas Härtel
// Licence:     wxWindows licence
/////////////////////////////////////////////////////////////////////////////
#pragma once
#include <api/api.h>
#include <wx/list.h>
#include <wx/datetime.h>
#include <wx/textctrl.h>

const wxChar chNULL = wxT('\0') ;
const wxChar chDECIMALNULL = wxT('0') ;
const wxChar chCR = wxT('\r') ;
const wxChar chLF = wxT('\n') ;
const wxChar chSPACE = wxT('_') ;
const wxChar chPERIOD = wxT('.') ;
const wxChar chCOMMA = wxT(',') ;
const wxChar chCOLON = wxT(':') ;
const wxChar chSLASH = wxT('/') ;

/////////////////////////////////////////////////////////////////////////////
// wxMaskData object

const wxChar chMaskPlaceholderDECIMALSEPARATOR = wxT('.');
const wxChar chMaskPlaceholderTHOUSANDSSEPARATOR = wxT(',');
const wxChar chMaskPlaceholderTIMESEPARATOR = wxT(':');
const wxChar chMaskPlaceholderDATESEPARATOR = wxT('/');
const wxChar chMaskPlaceholderDIGIT = wxT('#');
const wxChar chMaskPlaceholderALPHANUMERIC = wxT('A');
const wxChar chMaskPlaceholderALPHABETIC = wxT('?');
const wxChar chMaskPlaceholderALPHABETICUPPER = wxT('>');
const wxChar chMaskPlaceholderALPHABETICLOWER = wxT('<');
const wxChar chMaskPlaceholderCHARACTER = wxT('&');
const wxChar chMaskPlaceholderLITERALESCAPE = wxT('\\');
const wxChar chMaskPlaceholderDATEDAY = wxT('d');
const wxChar chMaskPlaceholderDATEMONTH = wxT('m');
const wxChar chMaskPlaceholderDATEYEAR = wxT('y');
const wxChar chMaskPlaceholderTIMEHOUR = wxT('h');
const wxChar chMaskPlaceholderTIMEMINUTE = wxT('n');
const wxChar chMaskPlaceholderTIMESECOND = wxT('s');

enum enumMaskDataType
{
	MaskDataTypeDECIMALSEPARATOR=0,  // Decimal separator. 
	MaskDataTypeTHOUSANDSSEPARATOR,  // Thousands separator. 
	MaskDataTypeTIMESEPARATOR     ,  // Time separator. 
	MaskDataTypeDATESEPARATOR     ,  // Date separator. 
	MaskDataTypeDIGIT             ,  // # digit placeholder (0-9). 
	MaskDataTypeALPHANUMERIC      ,  // A alphanumeric character placeholder (0-9 and a-Z). 
	MaskDataTypeALPHABETIC        ,  // ? Alphabetic placeholder (a-Z). 
	MaskDataTypeALPHAETICUPPER    ,  // > Alphabetic placeholder, but forced to Uppercase characters (A-Z). 
	MaskDataTypeALPHAETICLOWER    ,  // < Alphabetic placeholder, but forced to Lowercase characters (a-z). 
	MaskDataTypeCHARACTER         ,  // # character placeholder (ANSI characters 32-126 and 128-255). 
	MaskDataTypeLITERALESCAPE     ,  // All other symbols are displayed as themselves. 
	MaskDataTypeLITERAL           ,  // All other symbols are displayed as themselves. 
	MASKDATATYPECOUNT
};

enum enumMaskDataSubType
{
	MaskDataSubTypeNONE = 0,
	MaskDataSubTypeDATEDAY,
	MaskDataSubTypeDATEMONTH,
	MaskDataSubTypeDATEYEAR,
	MaskDataSubTypeTIMEHOUR,
	MaskDataSubTypeTIMEMINUTE,
	MaskDataSubTypeTIMESECOND,
	MASKDATASUBTYPECOUNT
};

class EXTAPI wxMaskData : public wxObject
{
	DECLARE_DYNAMIC_CLASS(wxMaskData)
	
public:
	wxMaskData();
	virtual ~wxMaskData();

// Attributes
public:
	enumMaskDataType m_eType;
	enumMaskDataSubType m_eSubType;
	wxChar m_chValue;
	
// Operations
public:
	void operator=(const wxMaskData& src);
	bool IsInputData();
	bool IsValidInput(wxChar chNewChar);
	wxChar PreProcessChar(wxChar chNewChar);
};

class EXTAPI wxMaskedTextCtrl : public wxTextCtrl
{
DECLARE_DYNAMIC_CLASS(wxMaskedTextCtrl)

// Member functions ---------------------------------------------------------
public:
	wxMaskedTextCtrl();
	wxMaskedTextCtrl(wxWindow *parent, wxWindowID id, const wxString& mask, const wxString &value, const wxPoint &pos, const wxSize &size, int style);
	virtual ~wxMaskedTextCtrl();

	wxString GetMask();
	void SetMask(wxString& mask);
	wxChar GetPromptSymbol();
	void SetPromptSymbol(wxChar chNewPromptSymbol);
	wxChar GetDecimalSeperator();
	void SetDecimalSeperator(wxChar chNewDecimalSeperator);
	wxChar GetThousandsSeperator();
	void SetThousandsSeperator(wxChar chNewThousandsSeperator);
	wxChar GetTimeSeperator();
	void SetTimeSeperator(wxChar chNewTimeSeperator);
	wxChar GetDateSeperator();
	void SetDateSeperator(wxChar chNewDateSeperator);
	bool GetInsertMode();
	void SetInsertMode(bool bInsertMode);
	bool GetAutoTab();
	void SetAutoTab(bool bAutoTab);
	bool GetBackwardLocationRight();
	void SetBackwardLocationRight(bool bRight=TRUE);
	wxDateTime GetMinDateTime(void);
	void SetMinDateTime(wxDateTime& minDateTime);
	wxDateTime GetMaxDateTime(void);
	void SetMaxDateTime(wxDateTime& maxDateTime);
	void SetDateTimeRange(wxDateTime& minDateTime, wxDateTime& maxDateTime);

	void Clear();
	void SetValue(const wxString& value);
	wxDateTime GetDateTimeValue();
	void SetDateTimeValue(wxDateTime& value);
	
// Internal Member functions ------------------------------------------------
protected:
	// Event Handler
	void OnKeyDown(wxKeyEvent& event);
	void OnChar(wxKeyEvent& event);
	void OnSetFocus(wxFocusEvent& event);
	void OnKillFocus(wxFocusEvent& event);
	void OnLeftButtonDown(wxMouseEvent& event);
	void OnCut(wxUpdateUIEvent& event);
	void OnCopy(wxUpdateUIEvent& event);
	void OnPaste(wxUpdateUIEvent& event);
	DECLARE_EVENT_TABLE();
	
	wxString ShowMask();
	wxString GetInputData();
	wxString GetInputData(wxString& value);
	bool SetInputData(const wxString& value, int nBeginPos=0, bool bAllowPrompt=TRUE);	
	void EmptyData(bool bOnlyInput=FALSE);
	bool IsInputEmpty() const;
	bool IsEmpty() const;
	virtual void ValidationError();
	bool Validate();
	bool IsValid(void);
	int RPtoLP(int nRealPos);
	int LPtoRP(int nLogicalPos);

	void DeleteContents();
	bool IsInputData(int nPosition);
	int DeleteRange(int nSelectionStart, int nSelectionEnd);
	int InsertAt(int nSelectionStart, wxChar chNewChar);
	int SetAt(int nSelectionStart, wxChar chNewChar);
	int GetNextInputLocation(int nSelectionStart);
	int GetPreviousInputLocation(int nSelectionStart);
	int GetEmptyInputLocation(int nSelectionStart);

	void UpdateControl(int nSelectionStart=0);  // UpdateInsertionPoint is automatic. 
	void UpdateInsertionPointForward(int nSelectionStart);
	void UpdateInsertionPointBackward(int nSelectionStart);

// Data members -------------------------------------------------------------
	wxList m_listData;

	bool m_bInsertMode;
	wxChar m_chPromptSymbol;
	wxChar m_chIntlDecimal;
	wxChar m_chIntlThousands;
	wxChar m_chIntlTime;
	wxChar m_chIntlDate;
	bool m_bAutoTab;	
	bool m_bBackwardLocationRight;
	bool m_bNeedValidation;
	bool m_bValidation;

	wxDateTime m_dtDateTime;
	wxDateTime m_dtMinDateTime;
	wxDateTime m_dtMaxDateTime;
};
