// 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_EDITCTRL_H_
#define _PWL_EDITCTRL_H_

enum PWL_EDIT_ALIGNFORMAT_H
{
	PEAH_LEFT = 0,
	PEAH_MIDDLE,
	PEAH_RIGHT
};

enum PWL_EDIT_ALIGNFORMAT_V
{
	PEAV_TOP = 0,	
	PEAV_CENTER,
	PEAV_BOTTOM
};

class IPWL_Edit_Notify;
class CPWL_EditCtrl;
class CPWL_Caret;
class IFX_Edit;
class CPWL_Edit;

class IPWL_Edit_Notify
{
public:
	//when the position of caret is changed in edit
	virtual void					OnCaretMove(FX_INT32 x1, FX_INT32 y1, FX_INT32 x2, FX_INT32 y2) {}
	virtual void					OnContentChange(const CPDF_Rect& rcContent){}
	//OprType: 0 InsertWord
	//1 InsertReturn
	//2 BackSpace
	//3 Delete
	//4 Clear
	//5 InsertText
	//6 SetText
	virtual void					OnInsertWord(const CPVT_WordPlace& place, const CPVT_WordPlace& oldplace){}
	virtual void					OnInsertReturn(const CPVT_WordPlace& place, const CPVT_WordPlace& oldplace){}
	virtual void					OnBackSpace(const CPVT_WordPlace& place, const CPVT_WordPlace& oldplace){}
	virtual void					OnDelete(const CPVT_WordPlace& place, const CPVT_WordPlace& oldplace){}
	virtual void					OnClear(const CPVT_WordPlace& place, const CPVT_WordPlace& oldplace){}
	virtual void					OnInsertText(const CPVT_WordPlace& place, const CPVT_WordPlace& oldplace){}
	virtual void					OnSetText(const CPVT_WordPlace& place, const CPVT_WordPlace& oldplace){}
	virtual void					OnAddUndo(CPWL_Edit* pEdit) {}
};

class PWL_CLASS CPWL_EditCtrl : public CPWL_Wnd, public IFX_Edit_Notify
{
	friend class CPWL_Edit_Notify;

public:
	CPWL_EditCtrl();
	virtual ~CPWL_EditCtrl();

public:
	virtual void					OnCreate(PWL_CREATEPARAM & cp);
	virtual void					OnCreated();

	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 void					OnNotify(CPWL_Wnd* pWnd, FX_DWORD msg, FX_INTPTR wParam = 0, FX_INTPTR lParam = 0);

	virtual void					CreateChildWnd(const PWL_CREATEPARAM & cp);
	virtual void					RePosChildWnd();	
	virtual void					SetFontSize(FX_FLOAT fFontSize);
	virtual FX_FLOAT				GetFontSize() const;
	
public:
	virtual void					SetText(FX_LPCWSTR csText);

	virtual void					CopyText();
	virtual void					PasteText();
	virtual void 					CutText();

	CPDF_Rect						GetContentRect() const;
	void							GetCaretPos(FX_INT32& x, FX_INT32& y) const;
	FX_BOOL							IsModified() const;

	CFX_WideString					GetText() const;
	void							SetSel(FX_INT32 nStartChar,FX_INT32 nEndChar);
	void							GetSel(FX_INT32 & nStartChar, FX_INT32 & nEndChar ) const;
	void							GetTextRange(const CPDF_Rect& rect, FX_INT32 & nStartChar, FX_INT32 & nEndChar) const;
	CFX_WideString					GetText(FX_INT32 & nStartChar, FX_INT32 & nEndChar) const;
	void							Clear();
	void							SelectAll();

	FX_INT32						GetCaret() const;
	void							SetCaret(FX_INT32 nPos);
	FX_INT32						GetTotalWords() const;

	void							Paint();

	void							EnableRefresh(FX_BOOL bRefresh);	
	CPDF_Point						GetScrollPos() const;
	void							SetScrollPos(const CPDF_Point& point);

	void							SetEditNotify(IPWL_Edit_Notify* pNotify) {m_pEditNotify = pNotify;}	

	void							SetCharSet(FX_BYTE nCharSet){m_nCharSet = nCharSet;}
	FX_INT32						GetCharSet() const;

	void							SetCodePage(FX_INT32 nCodePage){m_nCodePage = nCodePage;}
	FX_INT32						GetCodePage() const {return m_nCodePage;}

	CPDF_Font *						GetCaretFont() const;
	FX_FLOAT						GetCaretFontSize() const;

	FX_BOOL							CanUndo() const;
	FX_BOOL							CanRedo() const;
	void							Redo();
	void							Undo();

	void							SetReadyToInput();
protected:
	virtual void					ShowVScrollBar(FX_BOOL bShow);

	virtual void					InsertWord(FX_WORD word, FX_INT32 nCharset);
	virtual void					InsertReturn();
	virtual void					InsertText(FX_LPCWSTR csText);

	virtual void					SetCursor();
	FX_BOOL							IsWndHorV();

	void							Delete();
	void							Backspace();

protected:
	void							GetCaretInfo(CPDF_Point & ptHead, CPDF_Point & ptFoot) const;
	void							SetCaret(FX_BOOL bVisible, const CPDF_Point & ptHead, const CPDF_Point & ptFoot);
	
	void							SetEditCaret(FX_BOOL bVisible);

protected:
	virtual void					IOnSetScrollInfoX(FX_FLOAT fPlateMin, FX_FLOAT fPlateMax, 
												FX_FLOAT fContentMin, FX_FLOAT fContentMax, 
												FX_FLOAT fSmallStep, FX_FLOAT fBigStep){}
	virtual void					IOnSetScrollInfoY(FX_FLOAT fPlateMin, FX_FLOAT fPlateMax, 
												FX_FLOAT fContentMin, FX_FLOAT fContentMax, 
												FX_FLOAT fSmallStep, FX_FLOAT fBigStep);
	virtual void					IOnSetScrollPosX(FX_FLOAT fx){}
	virtual void					IOnSetScrollPosY(FX_FLOAT fy);
	virtual void					IOnSetCaret(FX_BOOL bVisible,const CPDF_Point & ptHead,const CPDF_Point & ptFoot, const CPVT_WordPlace& place);
	virtual void					IOnCaretChange(const CPVT_SecProps & secProps, const CPVT_WordProps & wordProps);
	virtual void					IOnContentChange(const CPDF_Rect& rcContent);
	virtual void					IOnInvalidateRect(CPDF_Rect * pRect);

private:
	void							CreateEditCaret(const PWL_CREATEPARAM & cp);

protected:
	IFX_Edit*						m_pEdit;
	CPWL_Caret*						m_pEditCaret;
	FX_BOOL							m_bMouseDown;
	IPWL_Edit_Notify*				m_pEditNotify;	

private:
	FX_INT32						m_nCharSet;
	FX_INT32						m_nCodePage;
};

#endif

