// 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 FPDFSDK_INCLUDE_PDFWINDOW_PWL_LISTBOX_H_
#define FPDFSDK_INCLUDE_PDFWINDOW_PWL_LISTBOX_H_

#include "../fxedit/fx_edit.h"
#include "PWL_Wnd.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(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 bool					OnKeyDown(FX_WORD nChar, FX_DWORD nFlag);
	virtual bool					OnChar(FX_WORD nChar, FX_DWORD nFlag);
	virtual bool					OnLButtonDown(const CPDF_Point & point, FX_DWORD nFlag);
	virtual bool					OnLButtonUp(const CPDF_Point & point, FX_DWORD nFlag);
	virtual bool					OnMouseMove(const CPDF_Point & point, FX_DWORD nFlag);
	virtual bool					OnMouseWheel(short zDelta, const CPDF_Point & point, FX_DWORD nFlag);
	virtual void					KillFocus();

	virtual void					OnNotify(CPWL_Wnd* pWnd, FX_DWORD msg, intptr_t wParam = 0, intptr_t lParam = 0);
	virtual void					RePosChildWnd();
	virtual CFX_WideString			GetText() const;
	virtual CPDF_Rect				GetFocusRect() const;
	virtual void					SetFontSize(FX_FLOAT fFontSize);
	virtual FX_FLOAT				GetFontSize() const;

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

	void							AddString(const FX_WCHAR* string);
	void							SetTopVisibleIndex(int32_t nItemIndex);
	void							ScrollToListItem(int32_t nItemIndex);
	void							ResetContent();
	void							Reset();
	void							Select(int32_t nItemIndex);
	void							SetCaret(int32_t nItemIndex);
	void							SetHoverSel(bool bHoverSel);

	int32_t						GetCount() const;
	bool							IsMultipleSel() const;
	int32_t						GetCaretIndex() const;
	int32_t						GetCurSel() const;
	bool							IsItemSelected(int32_t nItemIndex) const;
	int32_t						GetTopVisibleIndex() const;
	int32_t						FindNext(int32_t 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;
	bool							m_bMouseDown;
	bool							m_bHoverSel;
	IPWL_Filler_Notify*				m_pFillerNotify;
public:
	void							AttachFFLData(void* pData) {m_pFormFiller = pData;}
private:
	void*							m_pFormFiller;
};

#endif  // FPDFSDK_INCLUDE_PDFWINDOW_PWL_LISTBOX_H_
