// 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_LISTBOX_H_
#define _PWL_LISTBOX_H_

class CPDF_ListCtrl;
class CPWL_List_Notify;
class CPWL_ListBox;
class IPWL_Filler_Notify;

class CPWL_List_Notify : public IFX_List_Notify
{
public:
	CPWL_List_Notify(CPWL_ListBox * pList);
	virtual ~CPWL_List_Notify();

	void							IOnSetScrollInfoX(FX_FLOAT fPlateMin, FX_FLOAT fPlateMax, 
												FX_FLOAT fContentMin, FX_FLOAT fContentMax, 
												FX_FLOAT fSmallStep, FX_FLOAT fBigStep){}
	void							IOnSetScrollInfoY(FX_FLOAT fPlateMin, FX_FLOAT fPlateMax, 
												FX_FLOAT fContentMin, FX_FLOAT fContentMax, 
												FX_FLOAT fSmallStep, FX_FLOAT fBigStep);
	void							IOnSetScrollPosX(FX_FLOAT fx){}
	void							IOnSetScrollPosY(FX_FLOAT fy);
	void							IOnSetCaret(FX_BOOL bVisible,const CPDF_Point & ptHead,const CPDF_Point & ptFoot, const CPVT_WordPlace& place);
	void							IOnCaretChange(const CPVT_SecProps & secProps, const CPVT_WordProps & wordProps);
	void							IOnInvalidateRect(CPDF_Rect * pRect);

private:
	CPWL_ListBox*					m_pList;	
};

class PWL_CLASS CPWL_ListBox : public CPWL_Wnd
{
public:
	CPWL_ListBox();
	virtual ~CPWL_ListBox();

	virtual CFX_ByteString			GetClassName() const;
	virtual void					OnCreated();
	virtual void					OnDestroy();
	virtual void					GetThisAppearanceStream(CFX_ByteTextBuf & sAppStream);
	virtual void					DrawThisAppearance(CFX_RenderDevice* pDevice, CPDF_Matrix* pUser2Device);

	virtual FX_BOOL					OnKeyDown(FX_WORD nChar, FX_DWORD nFlag);
	virtual FX_BOOL					OnChar(FX_WORD nChar, FX_DWORD nFlag);
	virtual FX_BOOL					OnLButtonDown(const CPDF_Point & point, FX_DWORD nFlag);
	virtual FX_BOOL					OnLButtonUp(const CPDF_Point & point, FX_DWORD nFlag);
	virtual FX_BOOL					OnMouseMove(const CPDF_Point & point, FX_DWORD nFlag);
	virtual FX_BOOL					OnMouseWheel(short zDelta, const CPDF_Point & point, FX_DWORD nFlag);
	virtual void					KillFocus();

	virtual void					OnNotify(CPWL_Wnd* pWnd, FX_DWORD msg, FX_INTPTR wParam = 0, FX_INTPTR lParam = 0);
	virtual void					RePosChildWnd();
	virtual void					SetText(FX_LPCWSTR csText,FX_BOOL bRefresh = TRUE);
	virtual CFX_WideString			GetText() const;	
	virtual CPDF_Rect				GetFocusRect() const;
	virtual void					SetFontSize(FX_FLOAT fFontSize);
	virtual FX_FLOAT				GetFontSize() const;

	void							OnNotifySelChanged(FX_BOOL bKeyDown, FX_BOOL & bExit , FX_DWORD nFlag);

	void							AddString(FX_LPCWSTR string);	
	void							SetTopVisibleIndex(FX_INT32 nItemIndex);
	void							ScrollToListItem(FX_INT32 nItemIndex);
	void							ResetContent();
	void							Reset();
	void							Select(FX_INT32 nItemIndex);
	void							SetCaret(FX_INT32 nItemIndex);
	void							SetHoverSel(FX_BOOL bHoverSel);
	
	FX_INT32						GetCount() const;
	FX_BOOL							IsMultipleSel() const;
	FX_INT32						GetCaretIndex() const;
	FX_INT32						GetCurSel() const;
	FX_BOOL							IsItemSelected(FX_INT32 nItemIndex) const;
	FX_INT32						GetTopVisibleIndex() const;
	FX_INT32						FindNext(FX_INT32 nIndex,FX_WCHAR nChar) const;
	CPDF_Rect						GetContentRect() const;	
	FX_FLOAT						GetFirstHeight() const;
	CPDF_Rect						GetListRect() const;

	void							SetFillerNotify(IPWL_Filler_Notify* pNotify) {m_pFillerNotify = pNotify;}

protected:
	IFX_List*						m_pList;
	CPWL_List_Notify*				m_pListNotify;
	FX_BOOL							m_bMouseDown;
	FX_BOOL							m_bHoverSel;
	IPWL_Filler_Notify*				m_pFillerNotify;
public:
	void							AttachFFLData(void* pData) {m_pFormFiller = pData;}
private:
	void*							m_pFormFiller;
};

#endif // !defined(AFX_PWL_LISTBOX_H__F8C0DD72_CC3C_4806_86FB_E9D02B04A34B__INCLUDED_)


