#ifndef _COMMON_OWNERDRAWLIST_HPP_
#define _COMMON_OWNERDRAWLIST_HPP_
#ifndef _COMMON_CONTROL_HPP_
#include <common/control.hpp>
#endif
#ifndef _COMMON_RUBBERCONTROL_HPP_
#include <common/rubber.hpp>
#endif
#ifndef _COMMON_GLOBALDATA_HPP_
#include <common/gdata.hpp>
#endif
#ifndef _COMMON_STRING_HPP_
#include <common/string.hpp>
#endif
#ifndef _COMMON_RGBCOLOR_HPP_
#include <common/rgbcolor.hpp>
#endif
#ifndef _COMMON_FONT_HPP_
#include <common/font.hpp>
#endif

class Rect;
class GDIPoint;
class DrawItem;
class MeasureItem;
class PureDWORD;
class RGBColor;
class Font;
template <class T>
class Block;

class OwnerDrawList : public Control, public RubberControl
{
public:
  OwnerDrawList(GUIWindow &parentWnd,HWND hControlWnd,UINT controlID);
  OwnerDrawList(GUIWindow &parentWnd,const Rect &initRect,UINT controlID,DWORD style=LBS_NOTIFY|LBS_HASSTRINGS|LBS_USETABSTOPS|LBS_OWNERDRAWFIXED|WS_VSCROLL|WS_HSCROLL|WS_CLIPCHILDREN|WS_CLIPSIBLINGS|WS_DLGFRAME);
	virtual ~OwnerDrawList();
	OwnerDrawList &operator=(const OwnerDrawList &someOwnerDrawList);
  BOOL setTabStops(Block<PureDWORD> &tabStops);
	LONG addString(const String &stringData);
	LONG insertString(const String &stringData,int insertPos=-1);
	LONG insertStringAndMakeCurrent(const String &stringData);
	LONG deleteString(DWORD itemIndex);
	WORD setCurrent(WORD itemIndex);
	LONG getCurrent(void);
	LONG getCount(void);
  LONG setSelection(UINT itemIndex,WORD selectionState);
	LONG getText(String &stringData,DWORD itemIndex=0L);
  LONG getSelItems(GlobalData<DWORD> &selectedItems);
  LONG getSelCount(void);
	LONG getSel(UINT itemIndex);
	LONG getCursorItem(void);
	LONG getItemRect(UINT itemIndex,Rect &someRect);
  LONG findStringExact(const String &itemString,int startIndex=-1)const;
	LONG findString(const String &itemString,int startIndex=-1)const;
  LONG setCaretIndex(int itemIndex,BOOL scrollIntoView)const;
  LONG selItemRange(UINT rangeFirst,UINT rangeLast,BOOL select=TRUE)const;
  LONG itemFromPoint(const GDIPoint &somePoint);
  void setRedraw(WORD isInDraw);
	void resetContent(void);
  LONG textOut(const DrawItem &drawItem,const String &strData,int xLocation=0);
	GUIWindow &getParent(void);
	int dlgWidthUnits(void)const;
  BOOL isOkay(void)const;
protected:
  virtual WORD handleDraw(const DrawItem &drawItem);
	virtual WORD handleMeasureItem(MeasureItem &measureItem);
	virtual LPARAM handleControlColor(PureDevice &pureDevice,Control &wndListBox);
  virtual void drawEntire(const DrawItem &drawItem);
	virtual void handleResize(WORD width,WORD height);
  virtual GUIWindow &controlWindow(void);
private:
	enum {MaxItems=32767};
  CallbackData::ReturnType drawItemHandler(CallbackData &someCallbackData);
	CallbackData::ReturnType measureItemHandler(CallbackData &someCallbackData);
	CallbackData::ReturnType controlColorHandler(CallbackData &someCallbackData);
	CallbackData::ReturnType sizeHandler(CallbackData &someCallbackData);

	Callback<OwnerDrawList> mDrawItemHandler;
	Callback<OwnerDrawList> mMeasureItemHandler;
	Callback<OwnerDrawList> mControlColorHandler;
	Callback<OwnerDrawList> mSizeHandler;
	GUIWindow &mParentWnd;
	GlobalData<int> mTabStopArray;
	int mDlgWidthUnits;
};

inline
OwnerDrawList &OwnerDrawList::operator=(const OwnerDrawList &/*someOwnerDrawList*/)
{  // private implementation
  return *this;
}

inline
void OwnerDrawList::setRedraw(WORD isInDraw)
{
	if(!isOkay())return;
	sendMessage(WM_SETREDRAW,isInDraw,0L);
}

inline
void OwnerDrawList::resetContent(void)
{
  if(!isOkay())return;
	setRedraw(FALSE);
	sendMessage(LB_RESETCONTENT,0,0L);
	setRedraw(TRUE);
}

inline
GUIWindow &OwnerDrawList::getParent(void)
{
  return mParentWnd;
}

inline
int OwnerDrawList::dlgWidthUnits(void)const
{
  return mDlgWidthUnits;
}

inline
BOOL OwnerDrawList::isOkay(void)const
{
  return isValid();
}
#endif
