#ifndef _COMMON_CALLBACKDATA_HPP_
#define _COMMON_CALLBACKDATA_HPP_
#ifndef _COMMON_WINDOWS_HPP_
#include <common/windows.hpp>
#endif
#ifndef _COMMON_WINDOWSX_HPP_
#include <common/windowsx.hpp>
#endif
#ifndef _COMMON_RECTANGLE_HPP_
#include <common/rect.hpp>
#endif

class PureDevice;

class PaintInformation : public PAINTSTRUCT
{
public:
	PaintInformation(const PureDevice &somePureDevice);
	~PaintInformation();
	operator PureDevice&(void)const;
	Rect paintRect(void)const;
private:
	PureDevice *mlpPaintDevice;
};

inline
Rect PaintInformation::paintRect(void)const
{
  return Rect(PAINTSTRUCT::rcPaint.left,PAINTSTRUCT::rcPaint.top,PAINTSTRUCT::rcPaint.right,PAINTSTRUCT::rcPaint.bottom);
}

class CallbackData
{
public:
  typedef LONG ReturnType;
  CallbackData(void);
  CallbackData(const CallbackData &someCallbackData);
	CallbackData(WPARAM wParam,LPARAM lParam,HWND hWndFrom=0);
	virtual ~CallbackData();
	CallbackData &operator=(const CallbackData &someCallbackData);
	WORD operator==(const CallbackData &someCallbackData)const;
  HWND hwndFrom(void)const;
	void hwndFrom(HWND hwndFrom);
	WPARAM wParam(void)const;
	void wParam(WPARAM wParam);
	LPARAM lParam(void)const;
	void lParam(LPARAM lParam);
	WORD loWord(void)const;
	WORD hiWord(void)const;
	WPARAM wmCommandID(void)const;       // specialized WM_COMMAND interpreter
	HWND wmCommandWindow(void)const;     // ""
	WORD wmCommandCommand(void)const;    // ""
	WPARAM menuSelectID(void)const;      // specialized WM_MENUSELECT interpreter
	WPARAM menuSelectFlags(void)const;   // ""
	HMENU menuSelectMenu(void)const;     // ""
	HMENU menuSelectIDPopup(void)const;  // ""
	UINT controlID(void)const;           // specialized control handling
	HWND controlWindow(void)const;       // ""
	WORD controlNotification(void)const; // ""
private:
  WPARAM mwParam;
	LPARAM mlParam;
  HWND mhWndFrom;
};

inline
CallbackData::CallbackData(void)
: mwParam(0), mlParam(0), mhWndFrom(0)
{
}

inline
CallbackData::CallbackData(WPARAM wParam,LPARAM lParam,HWND hWndFrom)
: mwParam(wParam), mlParam(lParam), mhWndFrom(hWndFrom)
{
}

inline
CallbackData::CallbackData(const CallbackData &someCallbackData)
{
  *this=someCallbackData;
}

inline
CallbackData::~CallbackData()
{
}

inline
CallbackData &CallbackData::operator=(const CallbackData &someCallbackData)
{
  wParam(someCallbackData.wParam());
	lParam(someCallbackData.lParam());
	hwndFrom(someCallbackData.hwndFrom());  
	return *this;
}

inline
WORD CallbackData::operator==(const CallbackData &someCallbackData)const
{
	return (wParam()==someCallbackData.wParam()&&
					lParam()==someCallbackData.lParam()&&
					hwndFrom()==someCallbackData.hwndFrom());
}

inline
WPARAM CallbackData::wmCommandID(void)const
{
	return (WPARAM)(GET_WM_COMMAND_ID(mwParam,mlParam));
}

inline
HWND CallbackData::wmCommandWindow(void)const
{
	return GET_WM_COMMAND_HWND(mwParam,mlParam);
}

inline
WORD CallbackData::wmCommandCommand(void)const
{
	return GET_WM_COMMAND_CMD(mwParam,mlParam);
}

inline
WPARAM CallbackData::menuSelectID(void)const
{
#ifdef __FLAT__
  return LOWORD(mwParam);
#else
  return mwParam;
#endif
}

inline
WPARAM CallbackData::menuSelectFlags(void)const
{
#ifdef __FLAT__
  return HIWORD(mwParam);
#else
  return LOWORD(mlParam);
#endif
}

inline
HMENU CallbackData::menuSelectMenu(void)const
{
#ifdef __FLAT__
  return (HMENU)mlParam;
#else
  return (HMENU)HIWORD(mlParam);
#endif
}

inline
HMENU CallbackData::menuSelectIDPopup(void)const
{
  if(!(menuSelectFlags()&MF_POPUP))return (HMENU)0;
#ifdef __FLAT__
  return ::GetSubMenu(menuSelectMenu(),menuSelectID());
#else
  return (HMENU)menuSelectID();
#endif
}

inline
UINT CallbackData::controlID(void)const
{
#ifdef __FLAT__
	return LOWORD(mwParam);
#else
	return mwParam;
#endif
}

inline
HWND CallbackData::controlWindow(void)const
{
#ifdef __FLAT__
	return (HWND)mlParam;
#else
  return (HWND)LOWORD(mlParam);  
#endif  
}

inline
WORD CallbackData::controlNotification(void)const
{
#ifdef __FLAT__
  return HIWORD(mwParam);
#else
  return HIWORD(mlParam);
#endif
}

inline
HWND CallbackData::hwndFrom(void)const
{
  return mhWndFrom;
}

inline
void CallbackData::hwndFrom(HWND hwndFrom)
{
  mhWndFrom=hwndFrom;
}

inline
WPARAM CallbackData::wParam(void)const
{
	return mwParam;
}

inline
void CallbackData::wParam(WPARAM wParam)
{
  mwParam=wParam;
}

inline
LPARAM CallbackData::lParam(void)const
{
	return mlParam;
}

inline
void CallbackData::lParam(LPARAM lParam)
{
  mlParam=lParam;
}

inline
WORD CallbackData::loWord(void)const
{
  return LOWORD(mlParam);
}

inline
WORD CallbackData::hiWord(void)const
{
  return HIWORD(mlParam);
}
#endif
