#ifndef __XVTWIN_H
#define __XVTWIN_H

class TFontId : public wxObject
{
	wxString m_strFace;
	int m_nSize;
	XVT_FONT_STYLE_MASK m_wMask;
	WINDOW m_win;
  DECLARE_DYNAMIC_CLASS(TFontId);

protected:
	void Copy(const TFontId& pFont);
	bool IsEqual(const TFontId& pFont) const;

public:
	void SetWin(WINDOW w) { m_win = w; }
	WINDOW Win() const { return m_win; }

	void SetPointSize(int s) { m_nSize = s; }
	int PointSize() const { return m_nSize; }

	void SetMask(XVT_FONT_STYLE_MASK mask) { m_wMask = mask; }
	XVT_FONT_STYLE_MASK Mask() const { return m_wMask; }
	int Style() const;
  bool Underline() const;
  int Weight() const;
	
	void SetFaceName(const char* f) { m_strFace = f; }
	const char* FaceName() const;
	int Family() const;

	void Copy(const wxFont& rFont);
	const wxFont& Font(wxDC* dc, WINDOW w) const;
	
	TFontId& operator=(const TFontId& f) { Copy(f); return *this; }
	bool operator==(const TFontId& f) const { return IsEqual(f); }
	bool operator!=(const TFontId& f) const { return !IsEqual(f); }

	TFontId() : m_nSize(0), m_wMask(0), m_win(NULL_WIN)  { }
	TFontId(const TFontId& f) : m_win(NULL_WIN) { Copy(f); }
};

class TDC : public wxObject
{
	wxWindow* _owner;

protected:
  wxDC* _dc;
	RCT _clip;
  int _dirty;  // false = 0, true = 1, very_dirty = -1;
  int _deltaf;

	DRAW_CTOOLS _real_dct;
	TFontId _real_font;
  RCT _real_clip;

	bool PenChanged() const;
	bool BrushChanged() const;
	bool FontChanged() const;
  bool ClipChanged() const;

public:
	DRAW_CTOOLS _dct;
	TFontId _font;
  wxPoint _pnt;

	void SetClippingBox(const RCT* pRct);
	bool GetClippingBox(RCT* pRct) const;
	void SetDirty(int d = 1);
  int GetFontDelta() const { return _deltaf; }

  virtual wxDC& GetDC(bool bPaint = false);
	virtual void KillDC();
  TDC(wxWindow* owner);
	virtual ~TDC();
};

class TPrintDC : public TDC
{
  static bool _page_start;

public:
  static void SetPageStart();

  virtual wxDC& GetDC(bool);
	virtual void KillDC();
	TPrintDC(wxWindow* owner);
	virtual ~TPrintDC();
};

WX_DECLARE_HASH_MAP(WINDOW, TDC*, wxIntegerHash, wxIntegerEqual, wxTDCHashMap);

class TDCMapper : public wxTDCHashMap
{
  WINDOW _pLastOwner;
  TDC* _pLastTDC;

public:
	TDC& GetTDC(WINDOW owner);
	wxDC& GetDC(WINDOW owner, bool bPaint = false) { return GetTDC(owner).GetDC(bPaint); }
	void DestroyDC(WINDOW owner);
	void DestroyTDC(WINDOW owner);
  bool HasValidDC(WINDOW owner) const;

	TDCMapper() : _pLastOwner(NULL_WIN), _pLastTDC(NULL) { }
  virtual ~TDCMapper() { DestroyTDC(NULL_WIN); }
};

TDCMapper& GetTDCMapper();

class TwxWindowBase : public wxWindow
{
#ifdef LINUX
private:
	wxString m_strTitle;
  virtual void SetTitle(const wxString& title) { wxWindow::SetTitle(m_strTitle = title); }
  virtual wxString GetTitle() const { return m_strTitle; }
#endif

#ifdef WIN32
  virtual WXLRESULT MSWWindowProc(WXUINT nMsg, WXWPARAM wParam, WXLPARAM lParam);
#endif

public:
  bool CreateBase(wxWindow *parent, wxWindowID id, const wxString &title,
		    		      const wxPoint &pos, const wxSize &size, long style);
                           
  TwxWindowBase() { }
	TwxWindowBase(wxWindow *parent, wxWindowID id, const wxString &title,
	  	          const wxPoint & pos, const wxSize & size, long style);
  DECLARE_DYNAMIC_CLASS(TwxWindowBase)
};

class wxAuiManager;

class TwxWindow : public TwxWindowBase
{
private:
  MENU_ITEM* m_menu;
  wxAuiManager* m_pManager;
  bool m_bInDestroy;

protected:
  virtual void OnChar(wxKeyEvent& e);
  virtual void OnClose(wxCloseEvent& e);
  virtual void OnKeyDown(wxKeyEvent& e);
  virtual void OnKillFocus(wxFocusEvent& e);
  virtual void OnMenu(wxCommandEvent& e);
  virtual void OnMouseCaptureLost(wxMouseCaptureLostEvent& e);
  virtual void OnMouseDouble(wxMouseEvent& e);
  virtual void OnMouseDown(wxMouseEvent& e);
  virtual void OnMouseMove(wxMouseEvent& e);
  virtual void OnMouseUp(wxMouseEvent& e);
  virtual void OnMouseWheel(wxMouseEvent& e);
  virtual void OnScroll(wxScrollEvent& e);
  virtual void OnScrollWin(wxScrollWinEvent& e);
  virtual void OnSetFocus(wxFocusEvent& e);
  virtual void OnSize(wxSizeEvent& e);
  virtual void OnTimer(wxTimerEvent& e);
  virtual void OnButton(wxCommandEvent& e);
  virtual void OnCheckBox(wxCommandEvent& e);
  virtual void OnRadioButton(wxCommandEvent& e);

public:
	void DoXvtEvent(EVENT& e);
	virtual void OnPaint(wxPaintEvent& e);
  virtual bool InDestroy() const { return m_bInDestroy; }

public:
	WIN_TYPE _type;
	EVENT_HANDLER _eh;
	long _app_data;
	wxTimer* _timer;

	void SetMenuTree(const MENU_ITEM* menu);
	MENU_ITEM* GetMenuTree() const { return m_menu; }

  BOOLEAN AddPane(wxWindow* wnd, const char* name, int nDock = 0, int nFlags = 0);

  TwxWindow();
  TwxWindow(wxWindow *parent, wxWindowID id, const wxString& title,
		      const wxPoint& pos = wxDefaultPosition,
          const wxSize& size = wxDefaultSize, long style = 0);
	virtual ~TwxWindow();

  DECLARE_DYNAMIC_CLASS(TwxWindow);
	DECLARE_EVENT_TABLE();
};

class TTaskWin : public wxFrame
{
  MENU_ITEM* m_menu;
	
	wxMenuBar* m_pOldBar;
	wxWindow* m_MenuOwner;

protected:
  virtual void OnClose(wxCloseEvent& e);
  virtual void OnMenu(wxCommandEvent& e);
  virtual void OnSize(wxSizeEvent& e);
  
public:
  virtual void OnPaint(wxPaintEvent& e);
  DECLARE_DYNAMIC_CLASS(TTaskWin);
	DECLARE_EVENT_TABLE();

public:
  void SetMenuTree(const MENU_ITEM* tree);
  const MENU_ITEM* GetMenuTree() const { return m_menu; }
  void PushMenuTree(const MENU_ITEM* tree, wxWindow* owner);
	void PopMenuTree();
  
	TTaskWin() : wxFrame(), m_menu(NULL), m_pOldBar(NULL) { } // Needed by DECLARE_DYNAMIC_CLASS
  TTaskWin(wxWindowID id, const wxString& title,
           const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize,
           long style = wxDEFAULT_FRAME_STYLE);
	virtual ~TTaskWin();
};

#define TIMER_ID 1
const wxString& _GetAppTitle();
wxString _GetResourceName(const char* type, int rid);
const wxIcon& _GetIconResource(int rid);
const wxBitmap& _GetToolResource(int rid, int size);

#define CAST_COLOR(xc, wc) wxColour wc((xc>>16)&0xFF, (xc>>8)&0xFF, xc&0xFF)
#define MAKE_XVT_COLOR(wc) XVT_MAKE_COLOR(wc.Red(), wc.Green(), wc.Blue())
wxRect NormalizeRCT(const RCT* prct);

#ifdef XVTWIN_CPP 
#define extern
#endif

extern wxHashTable _nice_windows;
extern wxFrame*    _task_win;
extern EVENT_HANDLER _task_win_handler;

#endif