// Copyright 2014 PDFium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
 
// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com

#ifndef _PWL_IconList_H_
#define _PWL_IconList_H_

class IPWL_IconList_Notify;
class CPWL_IconList_Item;
class CPWL_IconList_Content;
class CPWL_IconList;
class CPWL_Label;

class IPWL_IconList_Notify
{
public:
	virtual void						OnNoteListSelChanged(FX_INT32 nItemIndex) = 0;
};

class CPWL_IconList_Item : public CPWL_Wnd
{
public:
	CPWL_IconList_Item();
	virtual ~CPWL_IconList_Item();

	virtual CFX_ByteString				GetClassName() const;
	virtual void						CreateChildWnd(const PWL_CREATEPARAM & cp);
	virtual void						RePosChildWnd();

	void								SetSelect(FX_BOOL bSelected);
	FX_BOOL								IsSelected() const;
	void								SetData(void* pData);
	void								SetIcon(FX_INT32 nIconIndex);
	void								SetText(const CFX_WideString& str);
	void								SetIconFillColor(const CPWL_Color& color);
	CFX_WideString						GetText() const;

protected:
	virtual FX_FLOAT					GetItemHeight(FX_FLOAT fLimitWidth);
	virtual void						DrawThisAppearance(CFX_RenderDevice* pDevice, CPDF_Matrix* pUser2Device);

	virtual void						OnEnabled();
	virtual void						OnDisabled();

private:
	FX_INT32							m_nIconIndex;
	void*								m_pData;
	FX_BOOL								m_bSelected;
	CPWL_Label*							m_pText;
	CPWL_Color							m_crIcon;
};

class CPWL_IconList_Content : public CPWL_ListCtrl
{
public:
	CPWL_IconList_Content(FX_INT32 nListCount);
	virtual ~CPWL_IconList_Content();

	void								SetSelect(FX_INT32 nIndex);
	FX_INT32							GetSelect() const;
	void								SetNotify(IPWL_IconList_Notify* pNotify);
	void								EnableNotify(FX_BOOL bNotify);
	void								SetListData(FX_INT32 nItemIndex, void* pData);
	void								SetListIcon(FX_INT32 nItemIndex, FX_INT32 nIconIndex);
	void								SetListString(FX_INT32 nItemIndex, const CFX_WideString& str);
	void								SetIconFillColor(const CPWL_Color& color);
	CFX_WideString						GetListString(FX_INT32 nItemIndex) const;
	IPWL_IconList_Notify*				GetNotify() const;
	void								ScrollToItem(FX_INT32 nItemIndex);

protected:
	virtual void						CreateChildWnd(const PWL_CREATEPARAM & cp);
	virtual FX_BOOL						OnLButtonDown(const CPDF_Point & point);
	virtual FX_BOOL						OnLButtonUp(const CPDF_Point & point);
	virtual FX_BOOL						OnMouseMove(const CPDF_Point & point);
	virtual FX_BOOL						OnKeyDown(FX_WORD nChar);

private:
	CPWL_IconList_Item*					GetListItem(FX_INT32 nItemIndex) const;
	void								SelectItem(FX_INT32 nItemIndex, FX_BOOL bSelect);
	FX_INT32							FindItemIndex(const CPDF_Point& point);
	
	FX_BOOL								m_nSelectIndex;
	IPWL_IconList_Notify*				m_pNotify;
	FX_BOOL								m_bEnableNotify;
	FX_BOOL								m_bMouseDown;
	FX_INT32							m_nListCount;
};

class PWL_CLASS CPWL_IconList : public CPWL_Wnd
{
public:
	CPWL_IconList(FX_INT32 nListCount);
	virtual ~CPWL_IconList();

	virtual FX_BOOL						OnMouseWheel(short zDelta, const CPDF_Point & point);

	void								SetSelect(FX_INT32 nIndex);
	void								SetTopItem(FX_INT32 nIndex);
	FX_INT32							GetSelect() const;
	void								SetNotify(IPWL_IconList_Notify* pNotify);
	void								EnableNotify(FX_BOOL bNotify);
	void								SetListData(FX_INT32 nItemIndex, void* pData);
	void								SetListIcon(FX_INT32 nItemIndex, FX_INT32 nIconIndex);
	void								SetListString(FX_INT32 nItemIndex, const CFX_WideString& str);
	void								SetIconFillColor(const CPWL_Color& color);
	CFX_WideString						GetListString(FX_INT32 nItemIndex) const;

protected:
	virtual void						OnCreated();
	virtual void						RePosChildWnd();
	virtual void						CreateChildWnd(const PWL_CREATEPARAM & cp);
	
	virtual void						OnNotify(CPWL_Wnd* pWnd, FX_DWORD msg, FX_INTPTR wParam = 0, FX_INTPTR lParam = 0);

private:
	CPWL_IconList_Content*				m_pListContent;
	FX_INT32							m_nListCount;
};
 
#endif //_PWL_IconList_H_


