// 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_EDIT_H_
#define _PWL_EDIT_H_

class IPWL_Filler_Notify;
class CPWL_Edit;
class IPWL_SpellCheck;

class IPWL_Filler_Notify
{
public:
	virtual void					QueryWherePopup(void* pPrivateData, FX_FLOAT fPopupMin,FX_FLOAT fPopupMax, 
										FX_INT32 & nRet, FX_FLOAT & fPopupRet) = 0; //nRet: (0:bottom 1:top)
	virtual void					OnBeforeKeyStroke(FX_BOOL bEditOrList, void* pPrivateData, FX_INT32 nKeyCode,
										CFX_WideString & strChange, const CFX_WideString& strChangeEx, 
										int nSelStart, int nSelEnd,
										FX_BOOL bKeyDown, FX_BOOL & bRC, FX_BOOL & bExit, FX_DWORD nFlag) = 0;
	virtual void					OnAfterKeyStroke(FX_BOOL bEditOrList, void* pPrivateData, FX_BOOL & bExit, FX_DWORD nFlag) = 0;
};

class PWL_CLASS CPWL_Edit : public CPWL_EditCtrl, public IFX_Edit_OprNotify
{
public:
	CPWL_Edit();
	virtual ~CPWL_Edit();

public:
	virtual CFX_ByteString			GetClassName() const;
	virtual void					OnDestroy();
	virtual void					OnCreated();
	virtual void					RePosChildWnd();
	virtual CPDF_Rect				GetClientRect() const;

	virtual void					GetThisAppearanceStream(CFX_ByteTextBuf & sAppStream);
	virtual void					DrawThisAppearance(CFX_RenderDevice* pDevice, CPDF_Matrix* pUser2Device);

	virtual FX_BOOL					OnLButtonDown(const CPDF_Point & point, FX_DWORD nFlag);
	virtual FX_BOOL					OnLButtonDblClk(const CPDF_Point & point, FX_DWORD nFlag);
	virtual FX_BOOL					OnRButtonUp(const CPDF_Point & point, FX_DWORD nFlag);
	virtual FX_BOOL					OnMouseWheel(short zDelta, const CPDF_Point & point, FX_DWORD nFlag);

	virtual FX_BOOL					OnKeyDown(FX_WORD nChar, FX_DWORD nFlag);
	virtual FX_BOOL					OnChar(FX_WORD nChar, FX_DWORD nFlag);

	virtual CPDF_Rect				GetFocusRect() const;

public:		
	void							SetAlignFormatH(PWL_EDIT_ALIGNFORMAT_H nFormat = PEAH_LEFT, FX_BOOL bPaint = TRUE);	//0:left 1:right 2:middle 
	void							SetAlignFormatV(PWL_EDIT_ALIGNFORMAT_V nFormat = PEAV_TOP, FX_BOOL bPaint = TRUE);	//0:top 1:bottom 2:center

	void							SetCharArray(FX_INT32 nCharArray);
	void							SetLimitChar(FX_INT32 nLimitChar);

	void							SetHorzScale(FX_INT32 nHorzScale, FX_BOOL bPaint = TRUE);
	void							SetCharSpace(FX_FLOAT fCharSpace, FX_BOOL bPaint = TRUE);

	void							SetLineLeading(FX_FLOAT fLineLeading, FX_BOOL bPaint = TRUE);

	void							EnableSpellCheck(FX_BOOL bEnabled);

	FX_BOOL							CanSelectAll() const;
	FX_BOOL							CanClear() const;
	FX_BOOL							CanCopy() const;
	FX_BOOL							CanCut() const;
	FX_BOOL							CanPaste() const;

	virtual void					CopyText();
	virtual void					PasteText();
	virtual void 					CutText();

	virtual void					SetText(FX_LPCWSTR csText);
	void							ReplaceSel(FX_LPCWSTR csText);

	CFX_ByteString					GetTextAppearanceStream(const CPDF_Point & ptOffset) const;
	CFX_ByteString					GetCaretAppearanceStream(const CPDF_Point & ptOffset) const;	
	CFX_ByteString					GetSelectAppearanceStream(const CPDF_Point & ptOffset) const;

	FX_BOOL							IsTextFull() const;	

	static FX_FLOAT					GetCharArrayAutoFontSize(CPDF_Font* pFont, const CPDF_Rect& rcPlate, FX_INT32 nCharArray);

	void							SetFillerNotify(IPWL_Filler_Notify* pNotify) {m_pFillerNotify = pNotify;}

	void							GeneratePageObjects(CPDF_PageObjects* pPageObjects, 
										const CPDF_Point& ptOffset, CFX_ArrayTemplate<CPDF_TextObject*>& ObjArray);
	void							GeneratePageObjects(CPDF_PageObjects* pPageObjects, 
										const CPDF_Point& ptOffset);

protected:
	virtual void					OnSetFocus();
	virtual void					OnKillFocus();

protected:
	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					OnSetText(const CPVT_WordPlace& place, const CPVT_WordPlace& oldplace);
	virtual void					OnInsertText(const CPVT_WordPlace& place, const CPVT_WordPlace& oldplace);
	virtual void					OnAddUndo(IFX_Edit_UndoItem* pUndoItem);

private:	
	CPVT_WordRange					GetSelectWordRange() const;
	virtual void					ShowVScrollBar(FX_BOOL bShow);
	FX_BOOL							IsVScrollBarVisible() const;
	void							SetParamByFlag();

	FX_FLOAT						GetCharArrayAutoFontSize(FX_INT32 nCharArray);
	CPDF_Point						GetWordRightBottomPoint(const CPVT_WordPlace& wpWord);

	CPVT_WordRange					CombineWordRange(const CPVT_WordRange& wr1, const CPVT_WordRange& wr2);
	CPVT_WordRange					GetLatinWordsRange(const CPDF_Point & point) const;
	CPVT_WordRange					GetLatinWordsRange(const CPVT_WordPlace & place) const;
	CPVT_WordRange					GetArabicWordsRange(const CPVT_WordPlace & place) const;
	CPVT_WordRange					GetSameWordsRange(const CPVT_WordPlace & place, FX_BOOL bLatin, FX_BOOL bArabic) const;

	void							AjustArabicWords(const CPVT_WordRange& wr);
public:
	FX_BOOL							IsProceedtoOnChar(FX_WORD nKeyCode, FX_DWORD nFlag);
private:
	IPWL_Filler_Notify*				m_pFillerNotify;
	IPWL_SpellCheck*				m_pSpellCheck;
	FX_BOOL							m_bFocus;
	CPDF_Rect						m_rcOldWindow;
public:
	void							AttachFFLData(void* pData) {m_pFormFiller = pData;}
private:
	void*							m_pFormFiller;
};

#endif 

