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

#include "fx_edit.h"

class CFX_Edit_Page;
struct CFX_Edit_LineRect;
class CFX_Edit_LineRectArray;
class CFX_Edit_RectArray;
class CFX_Edit_Refresh;
class CFX_Edit_Select;
class CFX_Edit;
class CFX_Edit_Iterator;
class CFX_Edit_Refresh;
class CFX_Edit_UndoItem;
class CFX_Edit_Undo;
class CFX_Edit_Provider;

#define FX_EDIT_IsFloatZero(f)						(f < 0.0001 && f > -0.0001)
#define FX_EDIT_IsFloatEqual(fa,fb)					FX_EDIT_IsFloatZero(fa - fb)
#define FX_EDIT_IsFloatBigger(fa,fb)				(fa > fb && !FX_EDIT_IsFloatEqual(fa,fb))
#define FX_EDIT_IsFloatSmaller(fa,fb)				(fa < fb && !FX_EDIT_IsFloatEqual(fa,fb))

template<class T> T FX_EDIT_MIN (const T & i, const T & j) { return ((i < j) ? i : j); }
template<class T> T FX_EDIT_MAX (const T & i, const T & j) { return ((i > j) ? i : j); }

#define	FX_EDIT_PI									3.14159265358979f
#define FX_EDIT_ITALIC_ANGEL						10 * FX_EDIT_PI / 180.0f


/* ------------------------- CFX_Edit_Refresh ---------------------------- */

enum REFRESH_PLAN_E
{
	RP_ANALYSE,
	RP_NOANALYSE,
	RP_OPTIONAL
};

enum EDIT_PROPS_E
{
	EP_LINELEADING,
	EP_LINEINDENT,
	EP_ALIGNMENT,
	EP_FONTINDEX,
	EP_FONTSIZE,
	EP_WORDCOLOR,
	EP_SCRIPTTYPE,
	EP_UNDERLINE,
	EP_CROSSOUT,
	EP_CHARSPACE,
	EP_HORZSCALE,
	EP_BOLD,
	EP_ITALIC
};

struct CFX_Edit_LineRect
{
	CFX_Edit_LineRect(const CPVT_WordRange & wrLine,const CPDF_Rect & rcLine) :
		m_wrLine(wrLine), m_rcLine(rcLine)
	{
	}

	FX_BOOL operator != (const CFX_Edit_LineRect & linerect) const
	{
		return FXSYS_memcmp(this, &linerect, sizeof(CFX_Edit_LineRect)) != 0;
	}

	FX_BOOL IsSameHeight(const CFX_Edit_LineRect & linerect) const
	{
		return FX_EDIT_IsFloatZero((m_rcLine.top - m_rcLine.bottom) - (linerect.m_rcLine.top -linerect.m_rcLine.bottom));
	}

	FX_BOOL IsSameTop(const CFX_Edit_LineRect & linerect) const
	{
		return FX_EDIT_IsFloatZero(m_rcLine.top - linerect.m_rcLine.top);
	}

	FX_BOOL IsSameLeft(const CFX_Edit_LineRect & linerect) const
	{
		return FX_EDIT_IsFloatZero(m_rcLine.left - linerect.m_rcLine.left);
	}

	FX_BOOL IsSameRight(const CFX_Edit_LineRect & linerect) const
	{
		return FX_EDIT_IsFloatZero(m_rcLine.right - linerect.m_rcLine.right);
	}

	CPVT_WordRange							m_wrLine;
	CPDF_Rect								m_rcLine;
};

class CFX_Edit_LineRectArray
{
public:
	CFX_Edit_LineRectArray()
	{
	}

	virtual ~CFX_Edit_LineRectArray()
	{
		Empty();
	}

	void Empty()
	{
		for (FX_INT32 i = 0, sz = m_LineRects.GetSize(); i < sz; i++)
			delete m_LineRects.GetAt(i);

		m_LineRects.RemoveAll();
	}

	void RemoveAll()
	{
		m_LineRects.RemoveAll();
	}

	void operator = (CFX_Edit_LineRectArray & rects)
	{
		Empty();
		for (FX_INT32 i = 0, sz = rects.GetSize(); i < sz; i++)
			m_LineRects.Add(rects.GetAt(i));

		rects.RemoveAll();
	}

	void Add(const CPVT_WordRange & wrLine,const CPDF_Rect & rcLine)
	{
		if (CFX_Edit_LineRect * pRect = new CFX_Edit_LineRect(wrLine,rcLine))
			m_LineRects.Add(pRect);
	}

	FX_INT32 GetSize() const
	{
		return m_LineRects.GetSize();
	}

	CFX_Edit_LineRect * GetAt(FX_INT32 nIndex) const
	{
		if (nIndex < 0 || nIndex >= m_LineRects.GetSize())
			return NULL;

		return m_LineRects.GetAt(nIndex);
	}

	CFX_ArrayTemplate<CFX_Edit_LineRect*>		m_LineRects;
};

class CFX_Edit_RectArray
{
public:
	CFX_Edit_RectArray()
	{
	}

	virtual ~CFX_Edit_RectArray()
	{
		this->Empty();
	}

	void Empty()
	{
		for (FX_INT32 i = 0, sz = m_Rects.GetSize(); i < sz; i++)
			delete m_Rects.GetAt(i);

		this->m_Rects.RemoveAll();
	}

	void Add(const CPDF_Rect & rect)
	{
		//check for overlaped area
		for (FX_INT32 i = 0, sz = m_Rects.GetSize(); i < sz; i++)
			if (CPDF_Rect * pRect = m_Rects.GetAt(i))
				if (pRect->Contains(rect))return;

		if (CPDF_Rect * pNewRect = new CPDF_Rect(rect))
			m_Rects.Add(pNewRect);
	}

	FX_INT32 GetSize() const
	{
		return m_Rects.GetSize();
	}

	CPDF_Rect * GetAt(FX_INT32 nIndex) const
	{
		if (nIndex < 0 || nIndex >= m_Rects.GetSize())
			return NULL;

		return m_Rects.GetAt(nIndex);
	}

	CFX_ArrayTemplate<CPDF_Rect*>			m_Rects;
};

class CFX_Edit_Refresh
{
public:
	CFX_Edit_Refresh();
	virtual ~CFX_Edit_Refresh();

	void									BeginRefresh();
	void									Push(const CPVT_WordRange & linerange,const CPDF_Rect & rect);
	void									NoAnalyse();
	void									Analyse(FX_INT32 nAlignment);
	void									AddRefresh(const CPDF_Rect & rect);
	const CFX_Edit_RectArray *				GetRefreshRects() const;
	void									EndRefresh();

private:
	CFX_Edit_LineRectArray					m_NewLineRects;
	CFX_Edit_LineRectArray					m_OldLineRects;
	CFX_Edit_RectArray						m_RefreshRects;
};


/* ------------------------- CFX_Edit_Select ---------------------------- */

class CFX_Edit_Select
{
public:
	CFX_Edit_Select()
	{
	}

	CFX_Edit_Select(const CPVT_WordPlace & begin,const CPVT_WordPlace & end)
	{
		Set(begin,end);
	}

	CFX_Edit_Select(const CPVT_WordRange & range)
	{
		Set(range.BeginPos,range.EndPos);
	}

	CPVT_WordRange ConvertToWordRange() const
	{
		return CPVT_WordRange(this->BeginPos,this->EndPos);
	}

	void Default()
	{
		BeginPos.Default();
		EndPos.Default();
	}

	void Set(const CPVT_WordPlace & begin,const CPVT_WordPlace & end)
	{
		this->BeginPos = begin;
		this->EndPos = end;
	}

	void SetBeginPos(const CPVT_WordPlace & begin)
	{
		this->BeginPos = begin;
	}

	void SetEndPos(const CPVT_WordPlace & end)
	{
		this->EndPos = end;
	}

	FX_BOOL IsExist() const
	{
		return this->BeginPos != this->EndPos;
	}

	FX_BOOL operator != (const CPVT_WordRange & wr) const
	{
		return wr.BeginPos != this->BeginPos || wr.EndPos != this->EndPos;
	}

	CPVT_WordPlace BeginPos,EndPos;
};

/* ------------------------- CFX_Edit_Undo ---------------------------- */

class CFX_Edit_Undo
{
public:
	CFX_Edit_Undo(FX_INT32 nBufsize = 10000);
	virtual ~CFX_Edit_Undo();

	void									Undo();
	void									Redo();

	void									AddItem(IFX_Edit_UndoItem* pItem);

	FX_BOOL									CanUndo() const;
	FX_BOOL									CanRedo() const;
	FX_BOOL									IsModified() const;
	FX_BOOL									IsWorking() const;

	void									Reset();

	IFX_Edit_UndoItem*						GetItem(FX_INT32 nIndex);
	FX_INT32								GetItemCount(){return m_UndoItemStack.GetSize();}
	FX_INT32								GetCurUndoPos(){return m_nCurUndoPos;}

private:
	void									SetBufSize(FX_INT32 nSize){m_nBufSize = nSize;}
	FX_INT32								GetBufSize(){return m_nBufSize;}

	void									RemoveHeads();
	void									RemoveTails();

private:
	CFX_ArrayTemplate<IFX_Edit_UndoItem*>	m_UndoItemStack;
	
	FX_INT32								m_nCurUndoPos;
	FX_INT32								m_nBufSize;
	FX_BOOL									m_bModified; 
	FX_BOOL									m_bVirgin;
	FX_BOOL									m_bWorking;
};

class CFX_Edit_UndoItem : public IFX_Edit_UndoItem
{
public:
	CFX_Edit_UndoItem() : m_bFirst(TRUE), m_bLast(TRUE) {}
	virtual ~CFX_Edit_UndoItem(){}

	virtual CFX_WideString					GetUndoTitle() {return L"";}
	virtual void							Release(){delete this;}

public:
	void									SetFirst(FX_BOOL bFirst){m_bFirst = bFirst;}
	FX_BOOL									IsFirst(){return m_bFirst;}
	void									SetLast(FX_BOOL bLast){m_bLast = bLast;}
	FX_BOOL									IsLast(){return m_bLast;}

private:
	FX_BOOL									m_bFirst;
	FX_BOOL									m_bLast;
};

class CFX_Edit_GroupUndoItem : public IFX_Edit_UndoItem
{
public:
	CFX_Edit_GroupUndoItem(const CFX_WideString& sTitle);
	virtual ~CFX_Edit_GroupUndoItem();

	void									AddUndoItem(CFX_Edit_UndoItem* pUndoItem);
	void									UpdateItems();

public:
	virtual void							Undo();
	virtual void							Redo();
	virtual CFX_WideString					GetUndoTitle();
	virtual void							Release();

private:
	CFX_WideString							m_sTitle;
	CFX_ArrayTemplate<CFX_Edit_UndoItem*>	m_Items;
};

/* ------------------------- CFX_Edit_UndoItem derived classes ---------------------------- */

class CFXEU_InsertWord : public CFX_Edit_UndoItem
{
public:
	CFXEU_InsertWord(CFX_Edit * pEdit, const CPVT_WordPlace & wpOldPlace, const CPVT_WordPlace & wpNewPlace,
		FX_WORD word, FX_INT32 charset, const CPVT_WordProps * pWordProps);
	virtual ~CFXEU_InsertWord();

	void						Redo();
	void						Undo();

private:
	CFX_Edit*					m_pEdit;

	CPVT_WordPlace				m_wpOld;
	CPVT_WordPlace				m_wpNew;
	FX_WORD						m_Word;
	FX_INT32					m_nCharset;
	CPVT_WordProps				m_WordProps;
};

class CFXEU_InsertReturn : public CFX_Edit_UndoItem
{
public:
	CFXEU_InsertReturn(CFX_Edit * pEdit, const CPVT_WordPlace & wpOldPlace, const CPVT_WordPlace & wpNewPlace,
							 const CPVT_SecProps * pSecProps, const CPVT_WordProps * pWordProps);
	virtual ~CFXEU_InsertReturn();

	void						Redo();
	void						Undo();

private:
	CFX_Edit *					m_pEdit;

	CPVT_WordPlace				m_wpOld;
	CPVT_WordPlace				m_wpNew;
	CPVT_SecProps				m_SecProps;
	CPVT_WordProps				m_WordProps;
};

class CFXEU_Backspace : public CFX_Edit_UndoItem
{
public:
	CFXEU_Backspace(CFX_Edit * pEdit, const CPVT_WordPlace & wpOldPlace, const CPVT_WordPlace & wpNewPlace,
						FX_WORD word, FX_INT32 charset,
						const CPVT_SecProps & SecProps, const CPVT_WordProps & WordProps);
	virtual ~CFXEU_Backspace();

	void						Redo();
	void						Undo();

private:
	CFX_Edit *					m_pEdit;

	CPVT_WordPlace				m_wpOld;
	CPVT_WordPlace				m_wpNew;
	FX_WORD						m_Word;
	FX_INT32					m_nCharset;
	CPVT_SecProps				m_SecProps;
	CPVT_WordProps				m_WordProps;
};

class CFXEU_Delete : public CFX_Edit_UndoItem
{
public:
	CFXEU_Delete(CFX_Edit * pEdit, const CPVT_WordPlace & wpOldPlace, const CPVT_WordPlace & wpNewPlace,
						FX_WORD word, FX_INT32 charset,
						const CPVT_SecProps & SecProps, const CPVT_WordProps & WordProps, FX_BOOL bSecEnd);
	virtual ~CFXEU_Delete();

	void						Redo();
	void						Undo();

private:
	CFX_Edit *					m_pEdit;

	CPVT_WordPlace				m_wpOld;
	CPVT_WordPlace				m_wpNew;
	FX_WORD						m_Word;
	FX_INT32					m_nCharset;
	CPVT_SecProps				m_SecProps;
	CPVT_WordProps				m_WordProps;
	FX_BOOL						m_bSecEnd;
};

class CFXEU_Clear : public CFX_Edit_UndoItem
{
public:
	CFXEU_Clear(CFX_Edit * pEdit, const CPVT_WordRange & wrSel, const CFX_WideString & swText);
	virtual ~CFXEU_Clear();

	void						Redo();
	void						Undo();

private:
	CFX_Edit*					m_pEdit;

	CPVT_WordRange				m_wrSel;
	CFX_WideString				m_swText;
};

class CFXEU_ClearRich : public CFX_Edit_UndoItem
{
public:
	CFXEU_ClearRich(CFX_Edit * pEdit, const CPVT_WordPlace & wpOldPlace, const CPVT_WordPlace & wpNewPlace,
						const CPVT_WordRange & wrSel,
					   FX_WORD word, FX_INT32 charset,
					   const CPVT_SecProps & SecProps, const CPVT_WordProps & WordProps);
	virtual ~CFXEU_ClearRich();

	void						Redo();
	void						Undo();

private:
	CFX_Edit *					m_pEdit;

	CPVT_WordPlace				m_wpOld;
	CPVT_WordPlace				m_wpNew;
	CPVT_WordRange				m_wrSel;
	FX_WORD						m_Word;
	FX_INT32					m_nCharset;
	CPVT_SecProps				m_SecProps;
	CPVT_WordProps				m_WordProps;
};

class CFXEU_InsertText : public CFX_Edit_UndoItem
{
public:
	CFXEU_InsertText(CFX_Edit * pEdit, const CPVT_WordPlace & wpOldPlace, const CPVT_WordPlace & wpNewPlace,
						   const CFX_WideString & swText, FX_INT32 charset,
						   const CPVT_SecProps * pSecProps, const CPVT_WordProps * pWordProps);
	virtual ~CFXEU_InsertText();

	void						Redo();
	void						Undo();

private:
	CFX_Edit *					m_pEdit;

	CPVT_WordPlace				m_wpOld;
	CPVT_WordPlace				m_wpNew;
	CFX_WideString				m_swText;
	FX_INT32					m_nCharset;
	CPVT_SecProps				m_SecProps;
	CPVT_WordProps				m_WordProps;
};

class CFXEU_SetSecProps : public CFX_Edit_UndoItem
{
public:
	CFXEU_SetSecProps(CFX_Edit * pEdit, const CPVT_WordPlace & place, EDIT_PROPS_E ep, 
		const CPVT_SecProps & oldsecprops, const CPVT_WordProps & oldwordprops, 
		const CPVT_SecProps & newsecprops, const CPVT_WordProps & newwordprops, const CPVT_WordRange & range);
	virtual ~CFXEU_SetSecProps();

	void						Redo();
	void						Undo();

private:
	CFX_Edit *					m_pEdit;
	CPVT_WordPlace				m_wpPlace;
	CPVT_WordRange				m_wrPlace;
	EDIT_PROPS_E				m_eProps;

	CPVT_SecProps				m_OldSecProps;
	CPVT_SecProps				m_NewSecProps;
	CPVT_WordProps				m_OldWordProps;
	CPVT_WordProps				m_NewWordProps;	
};

class CFXEU_SetWordProps : public CFX_Edit_UndoItem
{
public:
	CFXEU_SetWordProps(CFX_Edit * pEdit, const CPVT_WordPlace & place, EDIT_PROPS_E ep, 
		const CPVT_WordProps & oldprops, const CPVT_WordProps & newprops, const CPVT_WordRange & range);
	virtual ~CFXEU_SetWordProps();

	void						Redo();
	void						Undo();

private:
	CFX_Edit *					m_pEdit;
	CPVT_WordPlace				m_wpPlace;
	CPVT_WordRange				m_wrPlace;
	EDIT_PROPS_E				m_eProps;
	
	CPVT_WordProps				m_OldWordProps;
	CPVT_WordProps				m_NewWordProps;	
};

/* ------------------------- CFX_Edit ---------------------------- */

class CFX_Edit : public IFX_Edit
{
	friend class CFX_Edit_Iterator;
	friend class CFXEU_InsertWord;
	friend class CFXEU_InsertReturn;
	friend class CFXEU_Backspace;
	friend class CFXEU_Delete;
	friend class CFXEU_Clear;
	friend class CFXEU_ClearRich;
	friend class CFXEU_SetSecProps;
	friend class CFXEU_SetWordProps;	
	friend class CFXEU_InsertText;

public:
	CFX_Edit(IPDF_VariableText * pVT);
	virtual ~CFX_Edit();

	void									SetFontMap(IFX_Edit_FontMap * pFontMap);	
	void									SetVTProvider(IPDF_VariableText_Provider* pProvider);
	void									SetNotify(IFX_Edit_Notify * pNotify);
	void									SetOprNotify(IFX_Edit_OprNotify* pOprNotify);
	IFX_Edit_Iterator*						GetIterator();
	IPDF_VariableText *						GetVariableText();
	IFX_Edit_FontMap*						GetFontMap();

	void									Initialize();
	void									SetPlateRect(const CPDF_Rect & rect, FX_BOOL bPaint = TRUE);
	void									SetScrollPos(const CPDF_Point & point);

	void									SetAlignmentH(FX_INT32 nFormat = 0, FX_BOOL bPaint = TRUE);
	void									SetAlignmentV(FX_INT32 nFormat = 0, FX_BOOL bPaint = TRUE);
	void									SetPasswordChar(FX_WORD wSubWord = '*', FX_BOOL bPaint = TRUE);
	void									SetLimitChar(FX_INT32 nLimitChar = 0, FX_BOOL bPaint = TRUE);
	void									SetCharArray(FX_INT32 nCharArray = 0, FX_BOOL bPaint = TRUE);
	void									SetCharSpace(FX_FLOAT fCharSpace = 0.0f, FX_BOOL bPaint = TRUE);
	void									SetHorzScale(FX_INT32 nHorzScale = 100, FX_BOOL bPaint = TRUE);
	void									SetLineLeading(FX_FLOAT fLineLeading, FX_BOOL bPaint = TRUE);
	void									SetMultiLine(FX_BOOL bMultiLine = TRUE, FX_BOOL bPaint = TRUE);
	void									SetAutoReturn(FX_BOOL bAuto = TRUE, FX_BOOL bPaint = TRUE);
	void									SetAutoFontSize(FX_BOOL bAuto = TRUE, FX_BOOL bPaint = TRUE);	
	void									SetAutoScroll(FX_BOOL bAuto = TRUE, FX_BOOL bPaint = TRUE);	
	void									SetFontSize(FX_FLOAT fFontSize, FX_BOOL bPaint = TRUE);
	void									SetTextOverflow(FX_BOOL bAllowed = FALSE, FX_BOOL bPaint = TRUE);

	FX_BOOL									IsRichText() const;
	void									SetRichText(FX_BOOL bRichText = TRUE, FX_BOOL bPaint = TRUE);
	FX_BOOL									SetRichFontSize(FX_FLOAT fFontSize);	
	FX_BOOL									SetRichFontIndex(FX_INT32 nFontIndex);
	FX_BOOL									SetRichTextColor(FX_COLORREF dwColor);
	FX_BOOL									SetRichTextScript(FX_INT32 nScriptType);
	FX_BOOL									SetRichTextBold(FX_BOOL bBold = TRUE);	
	FX_BOOL									SetRichTextItalic(FX_BOOL bItalic = TRUE);
	FX_BOOL									SetRichTextUnderline(FX_BOOL bUnderline = TRUE);
	FX_BOOL									SetRichTextCrossout(FX_BOOL bCrossout = TRUE);
	FX_BOOL									SetRichTextCharSpace(FX_FLOAT fCharSpace);
	FX_BOOL									SetRichTextHorzScale(FX_INT32 nHorzScale = 100);
	FX_BOOL									SetRichTextLineLeading(FX_FLOAT fLineLeading);
	FX_BOOL									SetRichTextLineIndent(FX_FLOAT fLineIndent);
	FX_BOOL									SetRichTextAlignment(FX_INT32 nAlignment);

	void									OnMouseDown(const CPDF_Point & point,FX_BOOL bShift,FX_BOOL bCtrl);
	void									OnMouseMove(const CPDF_Point & point,FX_BOOL bShift,FX_BOOL bCtrl);
	void									OnVK_UP(FX_BOOL bShift,FX_BOOL bCtrl);
	void									OnVK_DOWN(FX_BOOL bShift,FX_BOOL bCtrl);
	void									OnVK_LEFT(FX_BOOL bShift,FX_BOOL bCtrl);
	void									OnVK_RIGHT(FX_BOOL bShift,FX_BOOL bCtrl);
	void									OnVK_HOME(FX_BOOL bShift,FX_BOOL bCtrl);
	void									OnVK_END(FX_BOOL bShift,FX_BOOL bCtrl);

	void									SetText(FX_LPCWSTR text,FX_INT32 charset = DEFAULT_CHARSET,
													const CPVT_SecProps * pSecProps = NULL,const CPVT_WordProps * pWordProps = NULL);	
	FX_BOOL									InsertWord(FX_WORD word, FX_INT32 charset = DEFAULT_CHARSET, const CPVT_WordProps * pWordProps = NULL);
	FX_BOOL									InsertReturn(const CPVT_SecProps * pSecProps = NULL,const CPVT_WordProps * pWordProps = NULL);
	FX_BOOL									Backspace();
	FX_BOOL									Delete();		
	FX_BOOL									Clear();
	FX_BOOL									Empty();
	FX_BOOL									InsertText(FX_LPCWSTR text, FX_INT32 charset = DEFAULT_CHARSET,
													const CPVT_SecProps * pSecProps = NULL,const CPVT_WordProps * pWordProps = NULL);
	FX_BOOL									Redo();
	FX_BOOL									Undo();	
	CPVT_WordPlace							DoInsertText(const CPVT_WordPlace& place, FX_LPCWSTR text, FX_INT32 charset, 
												const CPVT_SecProps * pSecProps, const CPVT_WordProps * pWordProps);
	FX_INT32								GetCharSetFromUnicode(FX_WORD word, FX_INT32 nOldCharset);

	FX_INT32								WordPlaceToWordIndex(const CPVT_WordPlace & place) const;
	CPVT_WordPlace							WordIndexToWordPlace(FX_INT32 index) const;	

	CPVT_WordPlace							GetLineBeginPlace(const CPVT_WordPlace & place) const;
	CPVT_WordPlace							GetLineEndPlace(const CPVT_WordPlace & place) const;
	CPVT_WordPlace							GetSectionBeginPlace(const CPVT_WordPlace & place) const;
	CPVT_WordPlace							GetSectionEndPlace(const CPVT_WordPlace & place) const;
	CPVT_WordPlace							SearchWordPlace(const CPDF_Point& point) const;

	FX_INT32								GetCaret() const;
	CPVT_WordPlace							GetCaretWordPlace() const;
	CFX_WideString							GetSelText() const;
	CFX_WideString							GetText() const;
	FX_FLOAT								GetFontSize() const;
	FX_WORD									GetPasswordChar() const;
	CPDF_Point								GetScrollPos() const;
	FX_INT32								GetCharArray() const;
	CPDF_Rect								GetPlateRect() const;
	CPDF_Rect								GetContentRect() const;
	CFX_WideString							GetRangeText(const CPVT_WordRange & range) const;
	FX_INT32								GetHorzScale() const;
	FX_FLOAT								GetCharSpace() const;
	FX_INT32								GetTotalWords() const;
	FX_INT32								GetTotalLines() const;

	void									SetSel(FX_INT32 nStartChar,FX_INT32 nEndChar);
	void									GetSel(FX_INT32 & nStartChar, FX_INT32 & nEndChar) const;

private:
	void									SelectAll();
	void									SelectNone();
	void									SetSel(const CPVT_WordPlace & begin,const CPVT_WordPlace & end);
	FX_BOOL									IsSelected() const;

	void									RearrangeAll();
	void									RearrangePart(const CPVT_WordRange & range);
	void									Paint();
	void									ScrollToCaret();
	void									SetScrollInfo();
	void									SetScrollPosX(FX_FLOAT fx);
	void									SetScrollPosY(FX_FLOAT fy);
	void									SetScrollLimit();
	void									SetContentChanged();
	void									EnableNotify(FX_BOOL bNotify);

	void									SetText(FX_LPCWSTR text,FX_INT32 charset,
													const CPVT_SecProps * pSecProps,const CPVT_WordProps * pWordProps,FX_BOOL bAddUndo, FX_BOOL bPaint);	
	FX_BOOL									InsertWord(FX_WORD word, FX_INT32 charset, const CPVT_WordProps * pWordProps,FX_BOOL bAddUndo, FX_BOOL bPaint);
	FX_BOOL									InsertReturn(const CPVT_SecProps * pSecProps,const CPVT_WordProps * pWordProps,FX_BOOL bAddUndo, FX_BOOL bPaint);
	FX_BOOL									Backspace(FX_BOOL bAddUndo, FX_BOOL bPaint);
	FX_BOOL									Delete(FX_BOOL bAddUndo, FX_BOOL bPaint);		
	FX_BOOL									Clear(FX_BOOL bAddUndo, FX_BOOL bPaint);
	FX_BOOL									InsertText(FX_LPCWSTR text, FX_INT32 charset,
												const CPVT_SecProps * pSecProps,const CPVT_WordProps * pWordProps,FX_BOOL bAddUndo, FX_BOOL bPaint);
	FX_BOOL									SetRichTextProps(EDIT_PROPS_E eProps,
												const CPVT_SecProps * pSecProps, const CPVT_WordProps * pWordProps);
	FX_BOOL									SetSecProps(EDIT_PROPS_E eProps, const CPVT_WordPlace & place, 
												const CPVT_SecProps * pSecProps, const CPVT_WordProps * pWordProps, const CPVT_WordRange & wr, FX_BOOL bAddUndo);
	FX_BOOL									SetWordProps(EDIT_PROPS_E eProps, const CPVT_WordPlace & place, 
												const CPVT_WordProps * pWordProps, const CPVT_WordRange & wr, FX_BOOL bAddUndo);
	void									PaintSetProps(EDIT_PROPS_E eProps, const CPVT_WordRange & wr);
	void									PaintInsertText(const CPVT_WordPlace & wpOld, const CPVT_WordPlace & wpNew);

	inline CPDF_Point						VTToEdit(const CPDF_Point & point) const;
	inline CPDF_Point						EditToVT(const CPDF_Point & point) const;
	inline CPDF_Rect						VTToEdit(const CPDF_Rect & rect) const;
	inline CPDF_Rect						EditToVT(const CPDF_Rect & rect) const;

	void									EnableRefresh(FX_BOOL bRefresh);
	void									Refresh(REFRESH_PLAN_E ePlan,const CPVT_WordRange * pRange1 = NULL,const CPVT_WordRange * pRange2 = NULL);
	void									RefreshPushLineRects(const CPVT_WordRange & wr);
	void									RefreshPushRandomRects(const CPVT_WordRange & wr);
	void									RefreshWordRange(const CPVT_WordRange& wr);

	void									SetCaret(FX_INT32 nPos);
	void									SetCaret(const CPVT_WordPlace & place);
	void									SetCaretInfo();
	void									SetCaretOrigin();
	void									SetCaretChange();

	CPVT_WordRange							GetWholeWordRange() const;
	CPVT_WordRange							GetVisibleWordRange() const;
	CPVT_WordRange							GetLatinWordsRange(const CPVT_WordPlace & place) const;
	CPVT_WordRange							CombineWordRange(const CPVT_WordRange & wr1, const CPVT_WordRange & wr2);
	CPVT_WordRange							GetSelectWordRange() const;

	void									EnableUndo(FX_BOOL bUndo);
	void									EnableOprNotify(FX_BOOL bNotify);

	FX_BOOL									IsTextFull() const;
	FX_BOOL									IsTextOverflow() const;
	FX_BOOL									CanUndo() const;
	FX_BOOL									CanRedo() const;
	FX_BOOL									IsModified() const;

	void									BeginGroupUndo(const CFX_WideString& sTitle);
	void									EndGroupUndo();
	void									AddEditUndoItem(CFX_Edit_UndoItem* pEditUndoItem);
	void									AddUndoItem(IFX_Edit_UndoItem* pUndoItem);

	void									SetPageInfo(const CPVT_WordPlace& place);
	CPVT_WordPlace							SearchPageEndPlace(const CPVT_WordPlace& wpPageBegin, const CPDF_Point& point) const;
	FX_FLOAT								GetLineTop(const CPVT_WordPlace& place) const;
	FX_FLOAT								GetLineBottom(const CPVT_WordPlace& place) const;

private:	
	IPDF_VariableText*						m_pVT;
	IFX_Edit_Notify*						m_pNotify;
	IFX_Edit_OprNotify*						m_pOprNotify;
	CFX_Edit_Provider*						m_pVTProvide;

	CPVT_WordPlace							m_wpCaret;
	CPVT_WordPlace							m_wpOldCaret;
	CFX_Edit_Select							m_SelState;

	CPDF_Point								m_ptScrollPos;
	CPDF_Point								m_ptRefreshScrollPos;
	FX_BOOL									m_bEnableScroll;	
	IFX_Edit_Iterator *						m_pIterator;	
	CFX_Edit_Refresh						m_Refresh;
	CPDF_Point								m_ptCaret;
	CFX_Edit_Undo							m_Undo;
	FX_INT32								m_nAlignment;
	FX_BOOL									m_bNotifyFlag;
	FX_BOOL									m_bEnableOverflow;
	FX_BOOL									m_bEnableRefresh;
	CPDF_Rect								m_rcOldContent;
	FX_BOOL									m_bEnableUndo;
	FX_BOOL									m_bNotify;
	FX_BOOL									m_bOprNotify;
	CFX_Edit_GroupUndoItem*					m_pGroupUndoItem;
};

/* ------------------------- CFX_Edit_Iterator ---------------------------- */

class CFX_Edit_Iterator : public IFX_Edit_Iterator
{
public:
	CFX_Edit_Iterator(CFX_Edit * pEdit,IPDF_VariableText_Iterator * pVTIterator);
	virtual ~CFX_Edit_Iterator();

	FX_BOOL									NextWord();
	FX_BOOL									NextLine();
	FX_BOOL									NextSection();
	FX_BOOL									PrevWord();
	FX_BOOL									PrevLine();
	FX_BOOL									PrevSection();

	FX_BOOL									GetWord(CPVT_Word & word) const;
	FX_BOOL									GetLine(CPVT_Line & line) const;
	FX_BOOL									GetSection(CPVT_Section & section) const;
	void									SetAt(FX_INT32 nWordIndex);
	void									SetAt(const CPVT_WordPlace & place);
	const CPVT_WordPlace &					GetAt() const;
	IFX_Edit*								GetEdit() const;

private:
	CFX_Edit *								m_pEdit;
	IPDF_VariableText_Iterator*				m_pVTIterator;
};

class CFX_Edit_Provider : public IPDF_VariableText_Provider
{
public:
	CFX_Edit_Provider(IFX_Edit_FontMap* pFontMap);
	virtual ~CFX_Edit_Provider();

	IFX_Edit_FontMap*			GetFontMap();

	FX_INT32					GetCharWidth(FX_INT32 nFontIndex, FX_WORD word, FX_INT32 nWordStyle);
	FX_INT32					GetTypeAscent(FX_INT32 nFontIndex);
	FX_INT32					GetTypeDescent(FX_INT32 nFontIndex);
	FX_INT32					GetWordFontIndex(FX_WORD word, FX_INT32 charset, FX_INT32 nFontIndex);
	FX_INT32					GetDefaultFontIndex();
	FX_BOOL						IsLatinWord(FX_WORD word);

private:
	IFX_Edit_FontMap*			m_pFontMap;
};

#endif //_FXET_EDIT_H_

