// 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_NOTE_H_
#define FPDFSDK_INCLUDE_PDFWINDOW_PWL_NOTE_H_

#include "PWL_Button.h"
#include "PWL_Edit.h"
#include "PWL_ListCtrl.h"
#include "PWL_ScrollBar.h"
#include "PWL_Wnd.h"

class CPWL_Label;
class CPWL_Note;
class CPWL_NoteItem;
class CPWL_Note_CloseBox;
class CPWL_Note_Contents;
class CPWL_Note_Edit;
class CPWL_Note_Icon;
class CPWL_Note_LBBox;
class CPWL_Note_Options;
class CPWL_Note_RBBox;
class IPWL_NoteHandler;
class IPWL_NoteItem;
class IPWL_NoteNotify;
class IPopup_Note;

class IPWL_NoteNotify
{
public:
	virtual ~IPWL_NoteNotify() { }
	virtual void						OnNoteMove(const FX_RECT& rtWin) = 0;
	virtual void						OnNoteShow(bool bShow) = 0;
	virtual void						OnNoteActivate(bool bActive) = 0;
	virtual void						OnNoteClose() = 0;
	virtual void						OnItemCreate(IPWL_NoteItem* pItem) = 0;
	virtual void						OnItemDelete(IPWL_NoteItem* pItem) = 0;
	virtual void						OnSetAuthorName(IPWL_NoteItem* pItem) = 0;
	virtual void						OnSetBkColor(IPWL_NoteItem* pItem) = 0;
	virtual void						OnSetContents(IPWL_NoteItem* pItem) = 0;
	virtual void						OnSetDateTime(IPWL_NoteItem* pItem) = 0;
	virtual void						OnSetSubjectName(IPWL_NoteItem* pItem) = 0;
	virtual void						OnPopupMenu(int32_t x, int32_t y) = 0;
	virtual void						OnPopupMenu(IPWL_NoteItem* pItem, int32_t x, int32_t y) = 0;
};

class IPWL_NoteHandler
{
public:
	virtual ~IPWL_NoteHandler() { }
	virtual void						OnNoteColorChanged(const CPWL_Color& color) = 0;
};

class IPWL_NoteItem
{
public:
	virtual ~IPWL_NoteItem() { }
	virtual void						SetPrivateData(void* pData) = 0;
	virtual void						SetBkColor(const CPWL_Color& color) = 0;
	virtual void						SetSubjectName(const CFX_WideString& sName) = 0;
	virtual void						SetAuthorName(const CFX_WideString& sName) = 0;
	virtual void						SetDateTime(FX_SYSTEMTIME time) = 0;
	virtual void						SetContents(const CFX_WideString& sContents) = 0;

	virtual IPWL_NoteItem*				CreateSubItem() = 0;
	virtual int32_t					CountSubItems() const = 0;
	virtual IPWL_NoteItem*				GetSubItems(int32_t index) const = 0;
	virtual void						DeleteSubItem(IPWL_NoteItem* pNoteItem) = 0;
	virtual void						SetFocus() = 0;

	virtual IPWL_NoteItem*				GetParentItem() const = 0;
	virtual void*						GetPrivateData() const = 0;
	virtual CFX_WideString				GetAuthorName() const = 0;
	virtual CPWL_Color					GetBkColor() const = 0;
	virtual CFX_WideString				GetContents() const = 0;
	virtual FX_SYSTEMTIME				GetDateTime() const = 0;
	virtual CFX_WideString				GetSubjectName() const = 0;

	virtual CPWL_Edit*					GetEdit() const = 0;
};

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

	void								SetIconType(int32_t nType);

public:

protected:
	virtual void						DrawThisAppearance(CFX_RenderDevice* pDevice, CPDF_Matrix* pUser2Device);

private:
	int32_t							m_nType;
};

class CPWL_Note_CloseBox : public CPWL_Button
{
public:
	CPWL_Note_CloseBox();
	virtual ~CPWL_Note_CloseBox();

protected:
	virtual void						DrawThisAppearance(CFX_RenderDevice* pDevice, CPDF_Matrix* pUser2Device);
	virtual bool						OnLButtonDown(const CPDF_Point & point, FX_DWORD nFlag);
	virtual bool						OnLButtonUp(const CPDF_Point & point, FX_DWORD nFlag);

private:
	bool								m_bMouseDown;
};

class CPWL_Note_LBBox : public CPWL_Wnd
{
public:
	CPWL_Note_LBBox();
	virtual ~CPWL_Note_LBBox();

protected:
	virtual void						DrawThisAppearance(CFX_RenderDevice* pDevice, CPDF_Matrix* pUser2Device);
};

class CPWL_Note_RBBox : public CPWL_Wnd
{
public:
	CPWL_Note_RBBox();
	virtual ~CPWL_Note_RBBox();

protected:
	virtual void						DrawThisAppearance(CFX_RenderDevice* pDevice, CPDF_Matrix* pUser2Device);
};

class CPWL_Note_Edit : public CPWL_Edit
{
public:
	CPWL_Note_Edit();
	virtual ~CPWL_Note_Edit();

	void								EnableNotify(bool bEnable) {m_bEnableNotify = bEnable;}
	virtual FX_FLOAT					GetItemHeight(FX_FLOAT fLimitWidth);
	FX_FLOAT							GetItemLeftMargin();
	FX_FLOAT							GetItemRightMargin();

	virtual void						SetText(const FX_WCHAR* csText);

protected:
	virtual void						OnNotify(CPWL_Wnd* pWnd, FX_DWORD msg, intptr_t wParam = 0, intptr_t lParam = 0);
	virtual void						RePosChildWnd();
	virtual void						OnSetFocus();
	virtual void						OnKillFocus();

private:
	bool								m_bEnableNotify;
	FX_FLOAT							m_fOldItemHeight;
	bool								m_bSizeChanged;
	FX_FLOAT							m_fOldMin;
	FX_FLOAT							m_fOldMax;
};

class CPWL_Note_Options : public CPWL_Wnd
{
public:
	CPWL_Note_Options();
	virtual ~CPWL_Note_Options();

	CPDF_Rect							GetContentRect() const;
	virtual void						SetTextColor(const CPWL_Color & color);
	void								SetText(const CFX_WideString& sText);

protected:
	virtual void						RePosChildWnd();
	virtual void						CreateChildWnd(const PWL_CREATEPARAM & cp);
	virtual void						DrawThisAppearance(CFX_RenderDevice* pDevice, CPDF_Matrix* pUser2Device);

private:
	CPWL_Label*							m_pText;
};

class CPWL_Note_Contents : public CPWL_ListCtrl
{
public:
	CPWL_Note_Contents();
	virtual ~CPWL_Note_Contents();

	virtual CFX_ByteString				GetClassName() const;
	virtual void						OnNotify(CPWL_Wnd* pWnd, FX_DWORD msg, intptr_t wParam = 0, intptr_t lParam = 0);
	virtual bool						OnLButtonDown(const CPDF_Point& point, FX_DWORD nFlag);

	void								SetEditFocus(bool bLast);
	CPWL_Edit*							GetEdit() const;

public:
	void								SetText(const CFX_WideString& sText);
	CFX_WideString						GetText() const;

	CPWL_NoteItem*						CreateSubItem();
	void								DeleteSubItem(IPWL_NoteItem* pNoteItem);
	int32_t							CountSubItems() const;
	IPWL_NoteItem*						GetSubItems(int32_t index) const;

	virtual IPWL_NoteItem*				GetHitNoteItem(const CPDF_Point& point);
	void								EnableRead(bool bEnabled);
	void								EnableModify(bool bEnabled);

protected:
	virtual void						CreateChildWnd(const PWL_CREATEPARAM & cp);

private:
	CPWL_Note_Edit*						m_pEdit;
};

class PWL_CLASS CPWL_NoteItem : public CPWL_Wnd, public IPWL_NoteItem
{
public:
	CPWL_NoteItem();
	virtual ~CPWL_NoteItem();

public:
	virtual void						SetPrivateData(void* pData);
	virtual void						SetBkColor(const CPWL_Color& color);
	virtual void						SetSubjectName(const CFX_WideString& sName);
	virtual void						SetAuthorName(const CFX_WideString& sName);
	virtual void						SetDateTime(FX_SYSTEMTIME time);
	virtual void						SetContents(const CFX_WideString& sContents);

	virtual IPWL_NoteItem*				CreateSubItem();
	virtual int32_t					CountSubItems() const;
	virtual IPWL_NoteItem*				GetSubItems(int32_t index) const;
	virtual void						DeleteSubItem(IPWL_NoteItem* pNoteItem);
	virtual void						SetFocus(){SetNoteFocus(false);}

	virtual IPWL_NoteItem*				GetParentItem() const;
	virtual void*						GetPrivateData() const;
	virtual CFX_WideString				GetAuthorName() const;
	virtual CPWL_Color					GetBkColor() const;
	virtual CFX_WideString				GetContents() const;
	virtual FX_SYSTEMTIME				GetDateTime() const;
	virtual CFX_WideString				GetSubjectName() const;
	virtual bool						IsTopItem() const { return false;}
	virtual CPWL_Edit*					GetEdit() const;

public:
	virtual bool						OnLButtonDown(const CPDF_Point& point, FX_DWORD nFlag);
	virtual bool						OnRButtonUp(const CPDF_Point & point, FX_DWORD nFlag);
	virtual CFX_ByteString				GetClassName() const;
	virtual IPWL_NoteItem*				GetHitNoteItem(const CPDF_Point& point);
	virtual IPWL_NoteItem*				GetFocusedNoteItem() const;

	virtual void						ResetSubjectName(int32_t nItemIndex);
	void								EnableRead(bool bEnabled);
	void								EnableModify(bool bEnabled);

protected:
	virtual void						RePosChildWnd();
	virtual void						CreateChildWnd(const PWL_CREATEPARAM & cp);

	virtual void						OnNotify(CPWL_Wnd* pWnd, FX_DWORD msg, intptr_t wParam = 0, intptr_t lParam = 0);

public:
	virtual FX_FLOAT					GetItemHeight(FX_FLOAT fLimitWidth);
	virtual FX_FLOAT					GetItemLeftMargin();
	virtual FX_FLOAT					GetItemRightMargin();
	CPWL_NoteItem*						CreateNoteItem();
	CPWL_NoteItem*						GetParentNoteItem() const;

	void								SetNoteFocus(bool bLast);
	void								OnContentsValidate();

	void								OnCreateNoteItem();

protected:
	void								PopupNoteItemMenu(const CPDF_Point& point);

	virtual const CPWL_Note*			GetNote() const;
	virtual IPWL_NoteNotify*			GetNoteNotify() const;

protected:
	CPWL_Label*							m_pSubject;
	CPWL_Label*							m_pDateTime;
	CPWL_Note_Contents*					m_pContents;

private:
	void*								m_pPrivateData;
	FX_SYSTEMTIME						m_dtNote;
	CFX_WideString						m_sAuthor;

	FX_FLOAT							m_fOldItemHeight;
	bool								m_bSizeChanged;
	bool								m_bAllowModify;
};

class PWL_CLASS CPWL_Note : public CPWL_NoteItem
{
public:
	CPWL_Note(IPopup_Note* pPopupNote, IPWL_NoteNotify* pNoteNotify, IPWL_NoteHandler* pNoteHandler);
	virtual ~CPWL_Note();

public:
	virtual void						SetSubjectName(const CFX_WideString& sName);
	virtual void						SetAuthorName(const CFX_WideString& sName);
	virtual CFX_WideString				GetAuthorName() const;
	virtual void						SetBkColor(const CPWL_Color& color);
	virtual void						ResetSubjectName(int32_t nItemIndex){}
	virtual bool						IsTopItem() const {return true;}
	virtual const CPWL_Note*			GetNote() const;
	virtual IPWL_NoteNotify*			GetNoteNotify() const;

public:
	IPWL_NoteItem*						Reply();
	void								EnableNotify(bool bEnabled);
	void								SetIconType(int32_t nType);
	void								SetOptionsText(const CFX_WideString& sText);
	void								EnableRead(bool bEnabled);
	void								EnableModify(bool bEnabled);

	CFX_WideString						GetReplyString() const;
	void								SetReplyString(const CFX_WideString& string);

	//0-normal / 1-caption / 2-leftbottom corner / 3-rightbottom corner / 4-close / 5-options
	int32_t							NoteHitTest(const CPDF_Point& point) const;
	CPDF_Rect							GetCaptionRect() const {return m_rcCaption;}
	IPopup_Note*						GetPopupNote() const {return m_pPopupNote;}

public:
	virtual bool						OnLButtonDown(const CPDF_Point & point, FX_DWORD nFlag);
	virtual bool						OnRButtonUp(const CPDF_Point & point, FX_DWORD nFlag);
	virtual bool						OnMouseWheel(short zDelta, const CPDF_Point & point, FX_DWORD nFlag);

protected:
	virtual void						RePosChildWnd();
	virtual void						CreateChildWnd(const PWL_CREATEPARAM & cp);

	virtual void						OnNotify(CPWL_Wnd* pWnd, FX_DWORD msg, intptr_t wParam = 0, intptr_t lParam = 0);

	bool								ResetScrollBar();
	void								RePosNoteChildren();
	bool								ScrollBarShouldVisible();

private:
	CPWL_Label*							m_pAuthor;
	CPWL_Note_Icon*						m_pIcon;
	CPWL_Note_CloseBox*					m_pCloseBox;
	CPWL_Note_LBBox*					m_pLBBox;
	CPWL_Note_RBBox*					m_pRBBox;
	CPWL_ScrollBar*						m_pContentsBar;
	CPWL_Note_Options*					m_pOptions;
	IPWL_NoteNotify*					m_pNoteNotify;
	bool								m_bResizing;
	PWL_SCROLL_INFO						m_OldScrollInfo;
	CPDF_Rect							m_rcCaption;
	bool								m_bEnalbleNotify;
	IPopup_Note*						m_pPopupNote;
	CFX_WideString						m_sReplyString;
};

#endif  // FPDFSDK_INCLUDE_PDFWINDOW_PWL_NOTE_H_
