// 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

#include "../../include/fxedit/fxet_stub.h"
#include "../../include/fxedit/fxet_edit.h"

#define FX_EDIT_UNDO_MAXITEM				10000

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

CFX_Edit_Iterator::CFX_Edit_Iterator(CFX_Edit * pEdit,IPDF_VariableText_Iterator * pVTIterator) :
	m_pEdit(pEdit),
	m_pVTIterator(pVTIterator)
{
}

CFX_Edit_Iterator::~CFX_Edit_Iterator()
{
}

FX_BOOL	CFX_Edit_Iterator::NextWord()
{
	ASSERT(m_pVTIterator != NULL);

	return m_pVTIterator->NextWord();
}

FX_BOOL CFX_Edit_Iterator::NextLine()
{
	ASSERT(m_pVTIterator != NULL);

	return m_pVTIterator->NextLine();
}

FX_BOOL CFX_Edit_Iterator::NextSection()
{
	ASSERT(m_pVTIterator != NULL);

	return m_pVTIterator->NextSection();
}

FX_BOOL	CFX_Edit_Iterator::PrevWord()
{
	ASSERT(m_pVTIterator != NULL);

	return m_pVTIterator->PrevWord();
}

FX_BOOL	CFX_Edit_Iterator::PrevLine()
{
	ASSERT(m_pVTIterator != NULL);

	return m_pVTIterator->PrevLine();
}

FX_BOOL	CFX_Edit_Iterator::PrevSection()
{
	ASSERT(m_pVTIterator != NULL);

	return m_pVTIterator->PrevSection();
}

FX_BOOL CFX_Edit_Iterator::GetWord(CPVT_Word & word) const
{
	ASSERT(m_pEdit != NULL);
	ASSERT(m_pVTIterator != NULL);

	if (m_pVTIterator->GetWord(word))
	{
		word.ptWord = m_pEdit->VTToEdit(word.ptWord);
		return TRUE;
	}

	return FALSE;
}

FX_BOOL CFX_Edit_Iterator::GetLine(CPVT_Line & line) const
{
	ASSERT(m_pEdit != NULL);
	ASSERT(m_pVTIterator != NULL);

	if (m_pVTIterator->GetLine(line))
	{
		line.ptLine = m_pEdit->VTToEdit(line.ptLine);
		return TRUE;
	}

	return FALSE;
}

FX_BOOL CFX_Edit_Iterator::GetSection(CPVT_Section & section) const
{
	ASSERT(m_pEdit != NULL);
	ASSERT(m_pVTIterator != NULL);

	if (m_pVTIterator->GetSection(section))
	{
		section.rcSection = m_pEdit->VTToEdit(section.rcSection);
		return TRUE;
	}

	return FALSE;
}

void CFX_Edit_Iterator::SetAt(int32_t nWordIndex)
{
	ASSERT(m_pVTIterator != NULL);

	m_pVTIterator->SetAt(nWordIndex);
}

void CFX_Edit_Iterator::SetAt(const CPVT_WordPlace & place)
{
	ASSERT(m_pVTIterator != NULL);

	m_pVTIterator->SetAt(place);
}

const CPVT_WordPlace & CFX_Edit_Iterator::GetAt() const
{
	ASSERT(m_pVTIterator != NULL);

	return m_pVTIterator->GetAt();
}

IFX_Edit* CFX_Edit_Iterator::GetEdit() const
{
	return m_pEdit;
}

/* --------------------------- CFX_Edit_Provider ------------------------------- */

CFX_Edit_Provider::CFX_Edit_Provider(IFX_Edit_FontMap * pFontMap) : m_pFontMap(pFontMap)
{
	ASSERT(m_pFontMap != NULL);
}

CFX_Edit_Provider::~CFX_Edit_Provider()
{
}

IFX_Edit_FontMap* CFX_Edit_Provider::GetFontMap()
{
	return m_pFontMap;
}

int32_t CFX_Edit_Provider::GetCharWidth(int32_t nFontIndex, FX_WORD word, int32_t nWordStyle)
{
	if (CPDF_Font* pPDFFont = m_pFontMap->GetPDFFont(nFontIndex))
	{
		FX_DWORD charcode = word;

		if (pPDFFont->IsUnicodeCompatible())
			charcode = pPDFFont->CharCodeFromUnicode(word);
		else
			charcode = m_pFontMap->CharCodeFromUnicode(nFontIndex, word);

		if (charcode != -1)
			return pPDFFont->GetCharWidthF(charcode);
	}

	return 0;
}

int32_t CFX_Edit_Provider::GetTypeAscent(int32_t nFontIndex)
{
	if (CPDF_Font* pPDFFont = m_pFontMap->GetPDFFont(nFontIndex))
		return pPDFFont->GetTypeAscent();

	return 0;
}

int32_t CFX_Edit_Provider::GetTypeDescent(int32_t nFontIndex)
{
	if (CPDF_Font* pPDFFont = m_pFontMap->GetPDFFont(nFontIndex))
		return pPDFFont->GetTypeDescent();

	return 0;
}

int32_t CFX_Edit_Provider::GetWordFontIndex(FX_WORD word, int32_t charset, int32_t nFontIndex)
{
	return m_pFontMap->GetWordFontIndex(word,charset,nFontIndex);
}

int32_t CFX_Edit_Provider::GetDefaultFontIndex()
{
	return 0;
}

FX_BOOL	CFX_Edit_Provider::IsLatinWord(FX_WORD word)
{
	return FX_EDIT_ISLATINWORD(word);
}

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

CFX_Edit_Refresh::CFX_Edit_Refresh()
{
}

CFX_Edit_Refresh::~CFX_Edit_Refresh()
{
}

void CFX_Edit_Refresh::BeginRefresh()
{
	m_RefreshRects.Empty();
	m_OldLineRects = m_NewLineRects;
}

void CFX_Edit_Refresh::Push(const CPVT_WordRange & linerange,const CPDF_Rect & rect)
{
	m_NewLineRects.Add(linerange,rect);
}

void CFX_Edit_Refresh::NoAnalyse()
{
	{
		for (int32_t i = 0, sz = m_OldLineRects.GetSize(); i < sz; i++)
			if (CFX_Edit_LineRect * pOldRect = m_OldLineRects.GetAt(i))
				m_RefreshRects.Add(pOldRect->m_rcLine);
	}

	{
		for (int32_t i = 0, sz = m_NewLineRects.GetSize(); i < sz; i++)
			if (CFX_Edit_LineRect * pNewRect = m_NewLineRects.GetAt(i))
				m_RefreshRects.Add(pNewRect->m_rcLine);
	}
}

void CFX_Edit_Refresh::Analyse(int32_t nAlignment)
{
	FX_BOOL bLineTopChanged = FALSE;
	CPDF_Rect rcResult;
	FX_FLOAT fWidthDiff;

	int32_t szMax = FX_EDIT_MAX(m_OldLineRects.GetSize(),m_NewLineRects.GetSize());
	int32_t i = 0;

	while (i < szMax)
	{
		CFX_Edit_LineRect * pOldRect = m_OldLineRects.GetAt(i);
		CFX_Edit_LineRect * pNewRect = m_NewLineRects.GetAt(i);

		if (pOldRect)
		{
			if (pNewRect)
			{
				if (bLineTopChanged)
				{
					rcResult = pOldRect->m_rcLine;
					rcResult.Union(pNewRect->m_rcLine);
					m_RefreshRects.Add(rcResult);
				}
				else
				{
					if (*pNewRect != *pOldRect)
					{
						if (!pNewRect->IsSameTop(*pOldRect) || !pNewRect->IsSameHeight(*pOldRect))
						{
							bLineTopChanged = TRUE;
							continue;
						}

						if (nAlignment == 0)
						{
							if (pNewRect->m_wrLine.BeginPos != pOldRect->m_wrLine.BeginPos)
							{
								rcResult = pOldRect->m_rcLine;
								rcResult.Union(pNewRect->m_rcLine);
								m_RefreshRects.Add(rcResult);
							}
							else
							{
								if (!pNewRect->IsSameLeft(*pOldRect))
								{
									rcResult = pOldRect->m_rcLine;
									rcResult.Union(pNewRect->m_rcLine);
								}
								else
								{
									fWidthDiff = pNewRect->m_rcLine.Width() - pOldRect->m_rcLine.Width();
									rcResult = pNewRect->m_rcLine;
									if (fWidthDiff > 0.0f)
										rcResult.left = rcResult.right - fWidthDiff;
									else
									{
										rcResult.left = rcResult.right;
										rcResult.right += (-fWidthDiff);
									}
								}
								m_RefreshRects.Add(rcResult);
							}
						}
						else
						{
							rcResult = pOldRect->m_rcLine;
							rcResult.Union(pNewRect->m_rcLine);
							m_RefreshRects.Add(rcResult);
						}
					}
					else
					{
						//don't need to do anything
					}
				}
			}
			else
			{
				m_RefreshRects.Add(pOldRect->m_rcLine);
			}
		}
		else
		{
			if (pNewRect)
			{
				m_RefreshRects.Add(pNewRect->m_rcLine);
			}
			else
			{
				//error
			}
		}
		i++;
	}
}

void CFX_Edit_Refresh::AddRefresh(const CPDF_Rect & rect)
{
	m_RefreshRects.Add(rect);
}

const CFX_Edit_RectArray * CFX_Edit_Refresh::GetRefreshRects() const
{
	return &m_RefreshRects;
}

void CFX_Edit_Refresh::EndRefresh()
{
	m_RefreshRects.Empty();
}

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

CFX_Edit_Undo::CFX_Edit_Undo(int32_t nBufsize) : m_nCurUndoPos(0),
	m_nBufSize(nBufsize),
	m_bModified(FALSE),
	m_bVirgin(TRUE),
	m_bWorking(FALSE)
{
}

CFX_Edit_Undo::~CFX_Edit_Undo()
{
	Reset();
}

FX_BOOL CFX_Edit_Undo::CanUndo() const
{
	return m_nCurUndoPos > 0;
}

void CFX_Edit_Undo::Undo()
{
	m_bWorking = TRUE;

	if (m_nCurUndoPos > 0)
	{
		IFX_Edit_UndoItem * pItem = m_UndoItemStack.GetAt(m_nCurUndoPos-1);
		ASSERT(pItem != NULL);

		pItem->Undo();

		m_nCurUndoPos--;
		m_bModified = (m_nCurUndoPos != 0);
	}

	m_bWorking = FALSE;
}

FX_BOOL	CFX_Edit_Undo::CanRedo() const
{
	return m_nCurUndoPos < m_UndoItemStack.GetSize();
}

void CFX_Edit_Undo::Redo()
{
	m_bWorking = TRUE;

	int32_t nStackSize = m_UndoItemStack.GetSize();

	if (m_nCurUndoPos < nStackSize)
	{
		IFX_Edit_UndoItem * pItem = m_UndoItemStack.GetAt(m_nCurUndoPos);
		ASSERT(pItem != NULL);

		pItem->Redo();

		m_nCurUndoPos++;
		m_bModified = (m_nCurUndoPos != 0);
	}

	m_bWorking = FALSE;
}

FX_BOOL	CFX_Edit_Undo::IsWorking() const
{
	return m_bWorking;
}

void CFX_Edit_Undo::AddItem(IFX_Edit_UndoItem* pItem)
{
	ASSERT(!m_bWorking);
	ASSERT(pItem != NULL);
	ASSERT(m_nBufSize > 1);

	if (m_nCurUndoPos < m_UndoItemStack.GetSize())
		RemoveTails();

	if (m_UndoItemStack.GetSize() >= m_nBufSize)
	{
		RemoveHeads();
		m_bVirgin = FALSE;
	}

	m_UndoItemStack.Add(pItem);
	m_nCurUndoPos = m_UndoItemStack.GetSize();

	m_bModified = (m_nCurUndoPos != 0);
}

FX_BOOL	CFX_Edit_Undo::IsModified() const
{
	if (m_bVirgin)
		return m_bModified;
	else
		return TRUE;
}

IFX_Edit_UndoItem* CFX_Edit_Undo::GetItem(int32_t nIndex)
{
	if (nIndex>=0 && nIndex < m_UndoItemStack.GetSize())
		return m_UndoItemStack.GetAt(nIndex);

	return NULL;
}

void CFX_Edit_Undo::RemoveHeads()
{
	ASSERT(m_UndoItemStack.GetSize() > 1);

	delete m_UndoItemStack.GetAt(0);
	m_UndoItemStack.RemoveAt(0);
}

void CFX_Edit_Undo::RemoveTails()
{
	for (int32_t i = m_UndoItemStack.GetSize()-1; i >= m_nCurUndoPos; i--)
	{
		delete m_UndoItemStack.GetAt(i);
		m_UndoItemStack.RemoveAt(i);
	}
}

void CFX_Edit_Undo::Reset()
{
	for (int32_t i=0, sz=m_UndoItemStack.GetSize(); i < sz; i++)
	{
		delete m_UndoItemStack.GetAt(i);
	}
	m_nCurUndoPos = 0;
	m_UndoItemStack.RemoveAll();
}

/* -------------------------------- CFX_Edit_GroupUndoItem -------------------------------- */

CFX_Edit_GroupUndoItem::CFX_Edit_GroupUndoItem(const CFX_WideString& sTitle) : m_sTitle(sTitle)
{
}

CFX_Edit_GroupUndoItem::~CFX_Edit_GroupUndoItem()
{
	for (int i=0,sz=m_Items.GetSize(); i<sz; i++)
	{
		delete m_Items[i];
	}

	m_Items.RemoveAll();
}

void CFX_Edit_GroupUndoItem::AddUndoItem(CFX_Edit_UndoItem* pUndoItem)
{
	ASSERT(pUndoItem != NULL);

	pUndoItem->SetFirst(FALSE);
	pUndoItem->SetLast(FALSE);

	m_Items.Add(pUndoItem);

	if (m_sTitle.IsEmpty())
		m_sTitle = pUndoItem->GetUndoTitle();
}

void CFX_Edit_GroupUndoItem::UpdateItems()
{
	if (m_Items.GetSize() > 0)
	{
		CFX_Edit_UndoItem* pFirstItem = m_Items[0];
		ASSERT(pFirstItem != NULL);
		pFirstItem->SetFirst(TRUE);

		CFX_Edit_UndoItem* pLastItem = m_Items[m_Items.GetSize() - 1];
		ASSERT(pLastItem != NULL);
		pLastItem->SetLast(TRUE);
	}
}

void CFX_Edit_GroupUndoItem::Undo()
{
	for (int i=m_Items.GetSize()-1; i>=0; i--)
	{
		CFX_Edit_UndoItem* pUndoItem = m_Items[i];
		ASSERT(pUndoItem != NULL);

		pUndoItem->Undo();
	}
}

void CFX_Edit_GroupUndoItem::Redo()
{
	for (int i=0,sz=m_Items.GetSize(); i<sz; i++)
	{
		CFX_Edit_UndoItem* pUndoItem = m_Items[i];
		ASSERT(pUndoItem != NULL);

		pUndoItem->Redo();
	}
}

CFX_WideString CFX_Edit_GroupUndoItem::GetUndoTitle()
{
	return m_sTitle;
}

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

CFXEU_InsertWord::CFXEU_InsertWord(CFX_Edit * pEdit, const CPVT_WordPlace & wpOldPlace, const CPVT_WordPlace & wpNewPlace,
								 FX_WORD word, int32_t charset, const CPVT_WordProps * pWordProps)
	: m_pEdit(pEdit), m_wpOld(wpOldPlace), m_wpNew(wpNewPlace), m_Word(word), m_nCharset(charset), m_WordProps()
{
	if (pWordProps)
		m_WordProps = *pWordProps;
}

CFXEU_InsertWord::~CFXEU_InsertWord()
{
}

void CFXEU_InsertWord::Redo()
{
	if (m_pEdit)
	{
		m_pEdit->SelectNone();
		m_pEdit->SetCaret(m_wpOld);
		m_pEdit->InsertWord(m_Word,m_nCharset,&m_WordProps,FALSE,TRUE);
	}
}

void CFXEU_InsertWord::Undo()
{
	if (m_pEdit)
	{
		m_pEdit->SelectNone();
		m_pEdit->SetCaret(m_wpNew);
		m_pEdit->Backspace(FALSE,TRUE);
	}
}

/* -------------------------------------------------------------------------- */

CFXEU_InsertReturn::CFXEU_InsertReturn(CFX_Edit * pEdit, const CPVT_WordPlace & wpOldPlace, const CPVT_WordPlace & wpNewPlace,
			 const CPVT_SecProps * pSecProps, const CPVT_WordProps * pWordProps) :
			m_pEdit(pEdit),
			m_wpOld(wpOldPlace),
			m_wpNew(wpNewPlace),
			m_SecProps(),
			m_WordProps()
{
	if (pSecProps)
		m_SecProps = *pSecProps;
	if (pWordProps)
		m_WordProps = *pWordProps;
}

CFXEU_InsertReturn::~CFXEU_InsertReturn()
{
}

void CFXEU_InsertReturn::Redo()
{
	if (m_pEdit)
	{
		m_pEdit->SelectNone();
		m_pEdit->SetCaret(m_wpOld);
		m_pEdit->InsertReturn(&m_SecProps,&m_WordProps,FALSE,TRUE);
	}
}

void CFXEU_InsertReturn::Undo()
{
	if (m_pEdit)
	{
		m_pEdit->SelectNone();
		m_pEdit->SetCaret(m_wpNew);
		m_pEdit->Backspace(FALSE,TRUE);
	}
}

/* -------------------------------------------------------------------------- */
//CFXEU_Backspace

CFXEU_Backspace::CFXEU_Backspace(CFX_Edit * pEdit, const CPVT_WordPlace & wpOldPlace, const CPVT_WordPlace & wpNewPlace,
							   FX_WORD word, int32_t charset,
							   const CPVT_SecProps & SecProps, const CPVT_WordProps & WordProps) :
			m_pEdit(pEdit),
			m_wpOld(wpOldPlace),
			m_wpNew(wpNewPlace),
			m_Word(word),
			m_nCharset(charset),
			m_SecProps(SecProps),
			m_WordProps(WordProps)
{
}

CFXEU_Backspace::~CFXEU_Backspace()
{
}

void CFXEU_Backspace::Redo()
{
	if (m_pEdit)
	{
		m_pEdit->SelectNone();
		m_pEdit->SetCaret(m_wpOld);
		m_pEdit->Backspace(FALSE,TRUE);
	}
}

void CFXEU_Backspace::Undo()
{
	if (m_pEdit)
	{
		m_pEdit->SelectNone();
		m_pEdit->SetCaret(m_wpNew);
		if (m_wpNew.SecCmp(m_wpOld) != 0)
		{
			m_pEdit->InsertReturn(&m_SecProps,&m_WordProps,FALSE,TRUE);
		}
		else
		{
			m_pEdit->InsertWord(m_Word,m_nCharset,&m_WordProps,FALSE,TRUE);
		}
	}
}

/* -------------------------------------------------------------------------- */
//CFXEU_Delete

CFXEU_Delete::CFXEU_Delete(CFX_Edit * pEdit, const CPVT_WordPlace & wpOldPlace, const CPVT_WordPlace & wpNewPlace,
							   FX_WORD word, int32_t charset,
							   const CPVT_SecProps & SecProps, const CPVT_WordProps & WordProps, FX_BOOL bSecEnd) :
			m_pEdit(pEdit),
			m_wpOld(wpOldPlace),
			m_wpNew(wpNewPlace),
			m_Word(word),
			m_nCharset(charset),
			m_SecProps(SecProps),
			m_WordProps(WordProps),
			m_bSecEnd(bSecEnd)
{
}

CFXEU_Delete::~CFXEU_Delete()
{
}

void CFXEU_Delete::Redo()
{
	if (m_pEdit)
	{
		m_pEdit->SelectNone();
		m_pEdit->SetCaret(m_wpOld);
		m_pEdit->Delete(FALSE,TRUE);
	}
}

void CFXEU_Delete::Undo()
{
	if (m_pEdit)
	{
		m_pEdit->SelectNone();
		m_pEdit->SetCaret(m_wpNew);
		if (m_bSecEnd)
		{
			m_pEdit->InsertReturn(&m_SecProps,&m_WordProps,FALSE,TRUE);
		}
		else
		{
			m_pEdit->InsertWord(m_Word,m_nCharset,&m_WordProps,FALSE,TRUE);
		}
	}
}

/* -------------------------------------------------------------------------- */
//CFXEU_Clear

CFXEU_Clear::CFXEU_Clear(CFX_Edit * pEdit,  const CPVT_WordRange & wrSel, const CFX_WideString & swText) :
			m_pEdit(pEdit),
			m_wrSel(wrSel),
			m_swText(swText)
{
}

CFXEU_Clear::~CFXEU_Clear()
{
}

void CFXEU_Clear::Redo()
{
	if (m_pEdit)
	{
		m_pEdit->SelectNone();
		m_pEdit->SetSel(m_wrSel.BeginPos,m_wrSel.EndPos);
		m_pEdit->Clear(FALSE,TRUE);
	}
}

void CFXEU_Clear::Undo()
{
	if (m_pEdit)
	{
		m_pEdit->SelectNone();
		m_pEdit->SetCaret(m_wrSel.BeginPos);
		m_pEdit->InsertText(m_swText.c_str(), DEFAULT_CHARSET, NULL, NULL, FALSE, TRUE);
		m_pEdit->SetSel(m_wrSel.BeginPos,m_wrSel.EndPos);
	}
}

/* -------------------------------------------------------------------------- */
//CFXEU_ClearRich

CFXEU_ClearRich::CFXEU_ClearRich(CFX_Edit * pEdit, const CPVT_WordPlace & wpOldPlace, const CPVT_WordPlace & wpNewPlace,
							   const CPVT_WordRange & wrSel, FX_WORD word, int32_t charset,
							   const CPVT_SecProps & SecProps, const CPVT_WordProps & WordProps) :
			m_pEdit(pEdit),
			m_wpOld(wpOldPlace),
			m_wpNew(wpNewPlace),
			m_wrSel(wrSel),
			m_Word(word),
			m_nCharset(charset),
			m_SecProps(SecProps),
			m_WordProps(WordProps)
{
}

CFXEU_ClearRich::~CFXEU_ClearRich()
{
}

void CFXEU_ClearRich::Redo()
{
	if (m_pEdit && IsLast())
	{
		m_pEdit->SelectNone();
		m_pEdit->SetSel(m_wrSel.BeginPos,m_wrSel.EndPos);
		m_pEdit->Clear(FALSE,TRUE);
	}
}

void CFXEU_ClearRich::Undo()
{
	if (m_pEdit)
	{
		m_pEdit->SelectNone();
		m_pEdit->SetCaret(m_wpOld);
		if (m_wpNew.SecCmp(m_wpOld) != 0)
		{
			m_pEdit->InsertReturn(&m_SecProps,&m_WordProps,FALSE,FALSE);
		}
		else
		{
			m_pEdit->InsertWord(m_Word,m_nCharset,&m_WordProps,FALSE,FALSE);
		}

		if (IsFirst())
		{
			m_pEdit->PaintInsertText(m_wrSel.BeginPos,m_wrSel.EndPos);
			m_pEdit->SetSel(m_wrSel.BeginPos,m_wrSel.EndPos);
		}
	}
}
/* -------------------------------------------------------------------------- */
//CFXEU_InsertText

CFXEU_InsertText::CFXEU_InsertText(CFX_Edit * pEdit, const CPVT_WordPlace & wpOldPlace, const CPVT_WordPlace & wpNewPlace,
							   const CFX_WideString & swText, int32_t charset,
							   const CPVT_SecProps * pSecProps, const CPVT_WordProps * pWordProps) :
			m_pEdit(pEdit),
			m_wpOld(wpOldPlace),
			m_wpNew(wpNewPlace),
			m_swText(swText),
			m_nCharset(charset),
			m_SecProps(),
			m_WordProps()
{
	if (pSecProps)
		m_SecProps = *pSecProps;
	if (pWordProps)
		m_WordProps = *pWordProps;
}

CFXEU_InsertText::~CFXEU_InsertText()
{
}

void CFXEU_InsertText::Redo()
{
	if (m_pEdit && IsLast())
	{
		m_pEdit->SelectNone();
		m_pEdit->SetCaret(m_wpOld);
		m_pEdit->InsertText(m_swText.c_str(), m_nCharset, &m_SecProps, &m_WordProps, FALSE, TRUE);
	}
}

void CFXEU_InsertText::Undo()
{
	if (m_pEdit)
	{
		m_pEdit->SelectNone();
		m_pEdit->SetSel(m_wpOld,m_wpNew);
		m_pEdit->Clear(FALSE,TRUE);
	}
}

/* -------------------------------------------------------------------------- */

CFXEU_SetSecProps::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)
		: m_pEdit(pEdit),
		m_wpPlace(place),
		m_wrPlace(range),
		m_eProps(ep),
		m_OldSecProps(oldsecprops),
		m_NewSecProps(newsecprops),
		m_OldWordProps(oldwordprops),
		m_NewWordProps(newwordprops)
{
}

CFXEU_SetSecProps::~CFXEU_SetSecProps()
{
}

void CFXEU_SetSecProps::Redo()
{
	if (m_pEdit)
	{
		m_pEdit->SetSecProps(m_eProps,m_wpPlace,&m_NewSecProps,&m_NewWordProps,m_wrPlace,FALSE);
		if (IsLast())
		{
			m_pEdit->SelectNone();
			m_pEdit->PaintSetProps(m_eProps,m_wrPlace);
			m_pEdit->SetSel(m_wrPlace.BeginPos,m_wrPlace.EndPos);
		}
	}
}

void CFXEU_SetSecProps::Undo()
{
	if (m_pEdit)
	{
		m_pEdit->SetSecProps(m_eProps,m_wpPlace,&m_OldSecProps,&m_OldWordProps,m_wrPlace,FALSE);
		if (IsFirst())
		{
			m_pEdit->SelectNone();
			m_pEdit->PaintSetProps(m_eProps,m_wrPlace);
			m_pEdit->SetSel(m_wrPlace.BeginPos,m_wrPlace.EndPos);
		}
	}
}

/* -------------------------------------------------------------------------- */

CFXEU_SetWordProps::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)
		: m_pEdit(pEdit),
		m_wpPlace(place),
		m_wrPlace(range),
		m_eProps(ep),
		m_OldWordProps(oldprops),
		m_NewWordProps(newprops)
{
}

CFXEU_SetWordProps::~CFXEU_SetWordProps()
{
}

void CFXEU_SetWordProps::Redo()
{
	if (m_pEdit)
	{
		m_pEdit->SetWordProps(m_eProps,m_wpPlace,&m_NewWordProps,m_wrPlace,FALSE);
		if (IsLast())
		{
			m_pEdit->SelectNone();
			m_pEdit->PaintSetProps(m_eProps,m_wrPlace);
			m_pEdit->SetSel(m_wrPlace.BeginPos,m_wrPlace.EndPos);
		}
	}
}

void CFXEU_SetWordProps::Undo()
{
	if (m_pEdit)
	{
		m_pEdit->SetWordProps(m_eProps,m_wpPlace,&m_OldWordProps,m_wrPlace,FALSE);
		if (IsFirst())
		{
			m_pEdit->SelectNone();
			m_pEdit->PaintSetProps(m_eProps,m_wrPlace);
			m_pEdit->SetSel(m_wrPlace.BeginPos,m_wrPlace.EndPos);
		}
	}
}

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

CFX_Edit::CFX_Edit(IPDF_VariableText * pVT) :
	m_pVT(pVT),
	m_pNotify(NULL),
	m_pOprNotify(NULL),
	m_pVTProvide(NULL),
	m_wpCaret(-1,-1,-1),
	m_wpOldCaret(-1,-1,-1),
	m_SelState(),
	m_ptScrollPos(0,0),
	m_ptRefreshScrollPos(0,0),
	m_bEnableScroll(FALSE),
	m_pIterator(NULL),
	m_ptCaret(0.0f,0.0f),
	m_Undo(FX_EDIT_UNDO_MAXITEM),
	m_nAlignment(0),
	m_bNotifyFlag(FALSE),
	m_bEnableOverflow(FALSE),
	m_bEnableRefresh(TRUE),
	m_rcOldContent(0.0f,0.0f,0.0f,0.0f),
	m_bEnableUndo(TRUE),
	m_bNotify(TRUE),
	m_bOprNotify(FALSE),
	m_pGroupUndoItem(NULL)
{
	ASSERT(pVT != NULL);
}

CFX_Edit::~CFX_Edit()
{
    delete m_pVTProvide;
    m_pVTProvide = NULL;
    delete m_pIterator;
    m_pIterator = NULL;
    ASSERT(m_pGroupUndoItem == NULL);
}

// public methods

void CFX_Edit::Initialize()
{
	m_pVT->Initialize();
	SetCaret(m_pVT->GetBeginWordPlace());
	SetCaretOrigin();
}

void CFX_Edit::SetFontMap(IFX_Edit_FontMap * pFontMap)
{
    delete m_pVTProvide;
    m_pVT->SetProvider(m_pVTProvide = new CFX_Edit_Provider(pFontMap));
}

void CFX_Edit::SetVTProvider(IPDF_VariableText_Provider* pProvider)
{
	m_pVT->SetProvider(pProvider);
}

void CFX_Edit::SetNotify(IFX_Edit_Notify* pNotify)
{
	m_pNotify = pNotify;
}

void CFX_Edit::SetOprNotify(IFX_Edit_OprNotify* pOprNotify)
{
	m_pOprNotify = pOprNotify;
}

IFX_Edit_Iterator * CFX_Edit::GetIterator()
{
	if (!m_pIterator)
		m_pIterator = new CFX_Edit_Iterator(this,m_pVT->GetIterator());

	return m_pIterator;
}

IPDF_VariableText *	CFX_Edit::GetVariableText()
{
	return m_pVT;
}

IFX_Edit_FontMap* CFX_Edit::GetFontMap()
{
	if (m_pVTProvide)
		return m_pVTProvide->GetFontMap();

	return NULL;
}

void CFX_Edit::SetPlateRect(const CPDF_Rect & rect, FX_BOOL bPaint/* = TRUE*/)
{
	m_pVT->SetPlateRect(rect);
	m_ptScrollPos = CPDF_Point(rect.left,rect.top);
	if (bPaint) Paint();
}

void CFX_Edit::SetAlignmentH(int32_t nFormat/* =0 */, FX_BOOL bPaint/* = TRUE*/)
{
	m_pVT->SetAlignment(nFormat);
	if (bPaint) Paint();
}

void CFX_Edit::SetAlignmentV(int32_t nFormat/* =0 */, FX_BOOL bPaint/* = TRUE*/)
{
	m_nAlignment = nFormat;
	if (bPaint) Paint();
}

void CFX_Edit::SetPasswordChar(FX_WORD wSubWord/* ='*' */, FX_BOOL bPaint/* = TRUE*/)
{
	m_pVT->SetPasswordChar(wSubWord);
	if (bPaint) Paint();
}

void CFX_Edit::SetLimitChar(int32_t nLimitChar/* =0 */, FX_BOOL bPaint/* = TRUE*/)
{
	m_pVT->SetLimitChar(nLimitChar);
	if (bPaint) Paint();
}

void CFX_Edit::SetCharArray(int32_t nCharArray/* =0 */, FX_BOOL bPaint/* = TRUE*/)
{
	m_pVT->SetCharArray(nCharArray);
	if (bPaint) Paint();
}

void CFX_Edit::SetCharSpace(FX_FLOAT fCharSpace/* =0.0f */, FX_BOOL bPaint/* = TRUE*/)
{
	m_pVT->SetCharSpace(fCharSpace);
	if (bPaint) Paint();
}

void CFX_Edit::SetHorzScale(int32_t nHorzScale/* =100 */, FX_BOOL bPaint/* = TRUE*/)
{
	m_pVT->SetHorzScale(nHorzScale);
	if (bPaint) Paint();
}

void CFX_Edit::SetMultiLine(FX_BOOL bMultiLine/* =TRUE */, FX_BOOL bPaint/* = TRUE*/)
{
	m_pVT->SetMultiLine(bMultiLine);
	if (bPaint) Paint();
}

void CFX_Edit::SetAutoReturn(FX_BOOL bAuto/* =TRUE */, FX_BOOL bPaint/* = TRUE*/)
{
	m_pVT->SetAutoReturn(bAuto);
	if (bPaint) Paint();
}

void CFX_Edit::SetLineLeading(FX_FLOAT fLineLeading/* =TRUE */, FX_BOOL bPaint/* = TRUE*/)
{
	m_pVT->SetLineLeading(fLineLeading);
	if (bPaint) Paint();
}

void CFX_Edit::SetAutoFontSize(FX_BOOL bAuto/* =TRUE */, FX_BOOL bPaint/* = TRUE*/)
{
	m_pVT->SetAutoFontSize(bAuto);
	if (bPaint) Paint();
}

void CFX_Edit::SetFontSize(FX_FLOAT fFontSize, FX_BOOL bPaint/* = TRUE*/)
{
	m_pVT->SetFontSize(fFontSize);
	if (bPaint) Paint();
}

void CFX_Edit::SetAutoScroll(FX_BOOL bAuto/* =TRUE */, FX_BOOL bPaint/* = TRUE*/)
{
	m_bEnableScroll = bAuto;
	if (bPaint) Paint();
}

void CFX_Edit::SetTextOverflow(FX_BOOL bAllowed /*= FALSE*/, FX_BOOL bPaint/* = TRUE*/)
{
	m_bEnableOverflow = bAllowed;
	if (bPaint) Paint();
}

void CFX_Edit::SetSel(int32_t nStartChar,int32_t nEndChar)
{
	if (m_pVT->IsValid())
	{
		if (nStartChar == 0 && nEndChar < 0)
		{
			SelectAll();
		}
		else if (nStartChar < 0)
		{
			SelectNone();
		}
		else
		{
			if (nStartChar < nEndChar)
			{
				SetSel(m_pVT->WordIndexToWordPlace(nStartChar),m_pVT->WordIndexToWordPlace(nEndChar));
			}
			else
			{
				SetSel(m_pVT->WordIndexToWordPlace(nEndChar),m_pVT->WordIndexToWordPlace(nStartChar));
			}
		}
	}
}

void CFX_Edit::SetSel(const CPVT_WordPlace & begin,const CPVT_WordPlace & end)
{
	if (m_pVT->IsValid())
	{
		SelectNone();

		m_SelState.Set(begin,end);

		SetCaret(m_SelState.EndPos);

		if (m_SelState.IsExist())
		{
			ScrollToCaret();
			CPVT_WordRange wr(m_SelState.BeginPos,m_SelState.EndPos);
			Refresh(RP_OPTIONAL,&wr);
			SetCaretInfo();
		}
		else
		{
			ScrollToCaret();
			SetCaretInfo();
		}
	}
}

void CFX_Edit::GetSel(int32_t & nStartChar, int32_t & nEndChar) const
{
	nStartChar = -1;
	nEndChar = -1;

	if (m_pVT->IsValid())
	{
		if (m_SelState.IsExist())
		{
			if (m_SelState.BeginPos.WordCmp(m_SelState.EndPos)<0)
			{
				nStartChar = m_pVT->WordPlaceToWordIndex(m_SelState.BeginPos);
				nEndChar = m_pVT->WordPlaceToWordIndex(m_SelState.EndPos);
			}
			else
			{
				nStartChar = m_pVT->WordPlaceToWordIndex(m_SelState.EndPos);
				nEndChar = m_pVT->WordPlaceToWordIndex(m_SelState.BeginPos);
			}
		}
		else
		{
			nStartChar = m_pVT->WordPlaceToWordIndex(m_wpCaret);
			nEndChar = m_pVT->WordPlaceToWordIndex(m_wpCaret);
		}
	}
}

int32_t CFX_Edit::GetCaret() const
{
	if (m_pVT->IsValid())
		return m_pVT->WordPlaceToWordIndex(m_wpCaret);

	return -1;
}

CPVT_WordPlace CFX_Edit::GetCaretWordPlace() const
{
	return m_wpCaret;
}

CFX_WideString CFX_Edit::GetText() const
{
	CFX_WideString swRet;

	if (m_pVT->IsValid())
	{
		if (IPDF_VariableText_Iterator * pIterator = m_pVT->GetIterator())
		{
			FX_BOOL bRich = m_pVT->IsRichText();

			pIterator->SetAt(0);

			CPVT_Word wordinfo;
			CPVT_WordPlace oldplace = pIterator->GetAt();
			while (pIterator->NextWord())
			{
				CPVT_WordPlace place = pIterator->GetAt();

				if (pIterator->GetWord(wordinfo))
				{
					if (bRich)
					{
						swRet += wordinfo.Word;
					}
					else
					{
						swRet += wordinfo.Word;
					}
				}

				if (oldplace.SecCmp(place) != 0)
				{
					swRet += 0x0D;
					swRet += 0x0A;
				}

				oldplace = place;
			}
		}
	}

	return swRet;
}

CFX_WideString CFX_Edit::GetRangeText(const CPVT_WordRange & range) const
{
	CFX_WideString swRet;

	if (m_pVT->IsValid())
	{
		FX_BOOL bRich = m_pVT->IsRichText();

		if (IPDF_VariableText_Iterator * pIterator = m_pVT->GetIterator())
		{
			CPVT_WordRange wrTemp = range;
			m_pVT->UpdateWordPlace(wrTemp.BeginPos);
			m_pVT->UpdateWordPlace(wrTemp.EndPos);
			pIterator->SetAt(wrTemp.BeginPos);

			CPVT_Word wordinfo;
			CPVT_WordPlace oldplace = wrTemp.BeginPos;
			while (pIterator->NextWord())
			{
				CPVT_WordPlace place = pIterator->GetAt();
				if (place.WordCmp(wrTemp.EndPos) > 0)break;

				if (pIterator->GetWord(wordinfo))
				{
					if (bRich)
					{
						swRet += wordinfo.Word;
					}
					else
					{
						swRet += wordinfo.Word;
					}
				}

				if (oldplace.SecCmp(place) != 0)
				{
					swRet += 0x0D;
					swRet += 0x0A;
				}

				oldplace = place;
			}
		}
	}

	return swRet;
}

CFX_WideString CFX_Edit::GetSelText() const
{
	return GetRangeText(m_SelState.ConvertToWordRange());
}

int32_t CFX_Edit::GetTotalWords() const
{
	return m_pVT->GetTotalWords();
}

int32_t CFX_Edit::GetTotalLines() const
{
	int32_t nLines = 0;

	if (IPDF_VariableText_Iterator * pIterator = m_pVT->GetIterator())
	{
		pIterator->SetAt(0);
		while (pIterator->NextLine())
			nLines++;
	}

	return nLines+1;
}

CPVT_WordRange CFX_Edit::GetSelectWordRange() const
{
	return m_SelState.ConvertToWordRange();
}

CPVT_WordRange CFX_Edit::CombineWordRange(const CPVT_WordRange & wr1, const CPVT_WordRange & wr2)
{
	CPVT_WordRange wrRet;

	if (wr1.BeginPos.WordCmp(wr2.BeginPos) < 0)
	{
		wrRet.BeginPos = wr1.BeginPos;
	}
	else
	{
		wrRet.BeginPos = wr2.BeginPos;
	}

	if (wr1.EndPos.WordCmp(wr2.EndPos) < 0)
	{
		wrRet.EndPos = wr2.EndPos;
	}
	else
	{
		wrRet.EndPos = wr1.EndPos;
	}

	return wrRet;
}

FX_BOOL	CFX_Edit::IsRichText() const
{
	return m_pVT->IsRichText();
}

void CFX_Edit::SetRichText(FX_BOOL bRichText/* =TRUE */, FX_BOOL bPaint/* = TRUE*/)
{
	m_pVT->SetRichText(bRichText);
	if (bPaint) Paint();
}

FX_BOOL CFX_Edit::SetRichFontIndex(int32_t nFontIndex)
{
	CPVT_WordProps WordProps;
	WordProps.nFontIndex = nFontIndex;
	return SetRichTextProps(EP_FONTINDEX,NULL,&WordProps);
}

FX_BOOL CFX_Edit::SetRichFontSize(FX_FLOAT fFontSize)
{
	CPVT_WordProps WordProps;
	WordProps.fFontSize = fFontSize;
	return SetRichTextProps(EP_FONTSIZE,NULL,&WordProps);
}

FX_BOOL CFX_Edit::SetRichTextColor(FX_COLORREF dwColor)
{
	CPVT_WordProps WordProps;
	WordProps.dwWordColor = dwColor;
	return SetRichTextProps(EP_WORDCOLOR,NULL,&WordProps);
}

FX_BOOL CFX_Edit::SetRichTextScript(int32_t nScriptType)
{
	CPVT_WordProps WordProps;
	WordProps.nScriptType = nScriptType;
	return SetRichTextProps(EP_SCRIPTTYPE,NULL,&WordProps);
}

FX_BOOL CFX_Edit::SetRichTextBold(FX_BOOL bBold)
{
	CPVT_WordProps WordProps;
	if (bBold)
		WordProps.nWordStyle |= PVTWORD_STYLE_BOLD;
	return SetRichTextProps(EP_BOLD,NULL,&WordProps);
}

FX_BOOL CFX_Edit::SetRichTextItalic(FX_BOOL bItalic)
{
	CPVT_WordProps WordProps;
	if (bItalic)
		WordProps.nWordStyle |= PVTWORD_STYLE_ITALIC;
	return SetRichTextProps(EP_ITALIC,NULL,&WordProps);
}

FX_BOOL CFX_Edit::SetRichTextUnderline(FX_BOOL bUnderline)
{
	CPVT_WordProps WordProps;
	if (bUnderline)
		WordProps.nWordStyle |= PVTWORD_STYLE_UNDERLINE;
	return SetRichTextProps(EP_UNDERLINE,NULL,&WordProps);
}

FX_BOOL CFX_Edit::SetRichTextCrossout(FX_BOOL bCrossout)
{
	CPVT_WordProps WordProps;
	if (bCrossout)
		WordProps.nWordStyle |= PVTWORD_STYLE_CROSSOUT;
	return SetRichTextProps(EP_CROSSOUT,NULL,&WordProps);
}

FX_BOOL CFX_Edit::SetRichTextCharSpace(FX_FLOAT fCharSpace)
{
	CPVT_WordProps WordProps;
	WordProps.fCharSpace = fCharSpace;
	return SetRichTextProps(EP_CHARSPACE,NULL,&WordProps);
}

FX_BOOL CFX_Edit::SetRichTextHorzScale(int32_t nHorzScale /*= 100*/)
{
	CPVT_WordProps WordProps;
	WordProps.nHorzScale = nHorzScale;
	return SetRichTextProps(EP_HORZSCALE,NULL,&WordProps);
}

FX_BOOL CFX_Edit::SetRichTextLineLeading(FX_FLOAT fLineLeading)
{
	CPVT_SecProps SecProps;
	SecProps.fLineLeading = fLineLeading;
	return SetRichTextProps(EP_LINELEADING,&SecProps,NULL);
}

FX_BOOL CFX_Edit::SetRichTextLineIndent(FX_FLOAT fLineIndent)
{
	CPVT_SecProps SecProps;
	SecProps.fLineIndent = fLineIndent;
	return SetRichTextProps(EP_LINEINDENT,&SecProps,NULL);
}

FX_BOOL	CFX_Edit::SetRichTextAlignment(int32_t nAlignment)
{
	CPVT_SecProps SecProps;
	SecProps.nAlignment = nAlignment;
	return SetRichTextProps(EP_ALIGNMENT,&SecProps,NULL);
}

FX_BOOL CFX_Edit::SetRichTextProps(EDIT_PROPS_E eProps, const CPVT_SecProps * pSecProps, const CPVT_WordProps * pWordProps)
{
	FX_BOOL bSet = FALSE;
	FX_BOOL bSet1,bSet2;
	if (m_pVT->IsValid() && m_pVT->IsRichText())
	{
		if (IPDF_VariableText_Iterator * pIterator = m_pVT->GetIterator())
		{
			CPVT_WordRange wrTemp = m_SelState.ConvertToWordRange();

			m_pVT->UpdateWordPlace(wrTemp.BeginPos);
			m_pVT->UpdateWordPlace(wrTemp.EndPos);
			pIterator->SetAt(wrTemp.BeginPos);

			BeginGroupUndo(L"");;

			bSet = SetSecProps(eProps,wrTemp.BeginPos,pSecProps,pWordProps,wrTemp,TRUE);

			while (pIterator->NextWord())
			{
				CPVT_WordPlace place = pIterator->GetAt();
				if (place.WordCmp(wrTemp.EndPos) > 0) break;
				bSet1 = SetSecProps(eProps,place,pSecProps,pWordProps,wrTemp,TRUE);
				bSet2 = SetWordProps(eProps,place,pWordProps,wrTemp,TRUE);

				if (!bSet)
					bSet = (bSet1 || bSet2);
			}

			EndGroupUndo();

			if (bSet)
			{
				PaintSetProps(eProps,wrTemp);
			}
		}
	}

	return bSet;
}

void CFX_Edit::PaintSetProps(EDIT_PROPS_E eProps, const CPVT_WordRange & wr)
{
	switch(eProps)
	{
	case EP_LINELEADING:
	case EP_LINEINDENT:
	case EP_ALIGNMENT:
		RearrangePart(wr);
		ScrollToCaret();
		Refresh(RP_ANALYSE);
		SetCaretOrigin();
		SetCaretInfo();
		break;
	case EP_WORDCOLOR:
	case EP_UNDERLINE:
	case EP_CROSSOUT:
		Refresh(RP_OPTIONAL,&wr);
		break;
	case EP_FONTINDEX:
	case EP_FONTSIZE:
	case EP_SCRIPTTYPE:
	case EP_CHARSPACE:
	case EP_HORZSCALE:
	case EP_BOLD:
	case EP_ITALIC:
		RearrangePart(wr);
		ScrollToCaret();

		CPVT_WordRange wrRefresh(m_pVT->GetSectionBeginPlace(wr.BeginPos),
			m_pVT->GetSectionEndPlace(wr.EndPos));
		Refresh(RP_ANALYSE,&wrRefresh);

		SetCaretOrigin();
		SetCaretInfo();
		break;
	}
}

FX_BOOL CFX_Edit::SetSecProps(EDIT_PROPS_E eProps, const CPVT_WordPlace & place,
							   const CPVT_SecProps * pSecProps, const CPVT_WordProps * pWordProps,
							   const CPVT_WordRange & wr, FX_BOOL bAddUndo)
{
	if (m_pVT->IsValid() && m_pVT->IsRichText())
	{
		if (IPDF_VariableText_Iterator * pIterator = m_pVT->GetIterator())
		{
			FX_BOOL bSet = FALSE;
			CPVT_Section secinfo;
			CPVT_Section OldSecinfo;

			CPVT_WordPlace oldplace = pIterator->GetAt();

			if (eProps == EP_LINELEADING || eProps == EP_LINEINDENT || eProps == EP_ALIGNMENT)
			{
				if (pSecProps)
				{
					pIterator->SetAt(place);
					if (pIterator->GetSection(secinfo))
					{
						if (bAddUndo) OldSecinfo = secinfo;

						switch(eProps)
						{
						case EP_LINELEADING:
							if (!FX_EDIT_IsFloatEqual(secinfo.SecProps.fLineLeading,pSecProps->fLineLeading))
							{
								secinfo.SecProps.fLineLeading = pSecProps->fLineLeading;
								bSet = TRUE;
							}
							break;
						case EP_LINEINDENT:
							if (!FX_EDIT_IsFloatEqual(secinfo.SecProps.fLineIndent,pSecProps->fLineIndent))
							{
								secinfo.SecProps.fLineIndent = pSecProps->fLineIndent;
								bSet = TRUE;
							}
							break;
						case EP_ALIGNMENT:
							if (secinfo.SecProps.nAlignment != pSecProps->nAlignment)
							{
								secinfo.SecProps.nAlignment = pSecProps->nAlignment;
								bSet = TRUE;
							}
							break;
						default:
							break;
						}
					}
				}
			}
			else
			{
				if (pWordProps && place == m_pVT->GetSectionBeginPlace(place))
				{
					pIterator->SetAt(place);
					if (pIterator->GetSection(secinfo))
					{
						if (bAddUndo) OldSecinfo = secinfo;

						switch(eProps)
						{
						case EP_FONTINDEX:
							if (secinfo.WordProps.nFontIndex != pWordProps->nFontIndex)
							{
								secinfo.WordProps.nFontIndex = pWordProps->nFontIndex;
								bSet = TRUE;
							}
							break;
						case EP_FONTSIZE:
							if (!FX_EDIT_IsFloatEqual(secinfo.WordProps.fFontSize,pWordProps->fFontSize))
							{
								secinfo.WordProps.fFontSize = pWordProps->fFontSize;
								bSet = TRUE;
							}
							break;
						case EP_WORDCOLOR:
							if (secinfo.WordProps.dwWordColor != pWordProps->dwWordColor)
							{
								secinfo.WordProps.dwWordColor = pWordProps->dwWordColor;
								bSet = TRUE;
							}
							break;
						case EP_SCRIPTTYPE:
							if (secinfo.WordProps.nScriptType != pWordProps->nScriptType)
							{
								secinfo.WordProps.nScriptType = pWordProps->nScriptType;
								bSet = TRUE;
							}
							break;
						case EP_CHARSPACE:
							if (!FX_EDIT_IsFloatEqual(secinfo.WordProps.fCharSpace,pWordProps->fCharSpace))
							{
								secinfo.WordProps.fCharSpace = pWordProps->fCharSpace;
								bSet = TRUE;
							}
							break;
						case EP_HORZSCALE:
							if (secinfo.WordProps.nHorzScale != pWordProps->nHorzScale)
							{
								secinfo.WordProps.nHorzScale = pWordProps->nHorzScale;
								bSet = TRUE;
							}
							break;
						case EP_UNDERLINE:
							if (pWordProps->nWordStyle & PVTWORD_STYLE_UNDERLINE)
							{
								if ((secinfo.WordProps.nWordStyle & PVTWORD_STYLE_UNDERLINE) == 0)
								{
									secinfo.WordProps.nWordStyle |= PVTWORD_STYLE_UNDERLINE;
									bSet = TRUE;
								}
							}
							else
							{
								if ((secinfo.WordProps.nWordStyle & PVTWORD_STYLE_UNDERLINE) != 0)
								{
									secinfo.WordProps.nWordStyle &= ~PVTWORD_STYLE_UNDERLINE;
									bSet = TRUE;
								}
							}
							break;
						case EP_CROSSOUT:
							if (pWordProps->nWordStyle & PVTWORD_STYLE_CROSSOUT)
							{
								if ((secinfo.WordProps.nWordStyle & PVTWORD_STYLE_CROSSOUT) == 0)
								{
									secinfo.WordProps.nWordStyle |= PVTWORD_STYLE_CROSSOUT;
									bSet = TRUE;
								}
							}
							else
							{
								if ((secinfo.WordProps.nWordStyle & PVTWORD_STYLE_CROSSOUT) != 0)
								{
									secinfo.WordProps.nWordStyle &= ~PVTWORD_STYLE_CROSSOUT;
									bSet = TRUE;
								}
							}
							break;
						case EP_BOLD:
							if (pWordProps->nWordStyle & PVTWORD_STYLE_BOLD)
							{
								if ((secinfo.WordProps.nWordStyle & PVTWORD_STYLE_BOLD) == 0)
								{
									secinfo.WordProps.nWordStyle |= PVTWORD_STYLE_BOLD;
									bSet = TRUE;
								}
							}
							else
							{
								if ((secinfo.WordProps.nWordStyle & PVTWORD_STYLE_BOLD) != 0)
								{
									secinfo.WordProps.nWordStyle &= ~PVTWORD_STYLE_BOLD;
									bSet = TRUE;
								}
							}
							break;
						case EP_ITALIC:
							if (pWordProps->nWordStyle & PVTWORD_STYLE_ITALIC)
							{
								if ((secinfo.WordProps.nWordStyle & PVTWORD_STYLE_ITALIC) == 0)
								{
									secinfo.WordProps.nWordStyle |= PVTWORD_STYLE_ITALIC;
									bSet = TRUE;
								}
							}
							else
							{
								if ((secinfo.WordProps.nWordStyle & PVTWORD_STYLE_ITALIC) != 0)
								{
									secinfo.WordProps.nWordStyle &= ~PVTWORD_STYLE_ITALIC;
									bSet = TRUE;
								}
							}
							break;
						default:
							break;
						}
					}
				}
			}

			if (bSet)
			{
				pIterator->SetSection(secinfo);

				if (bAddUndo && m_bEnableUndo)
				{
					AddEditUndoItem(new CFXEU_SetSecProps
						(this,place,eProps,OldSecinfo.SecProps,OldSecinfo.WordProps,secinfo.SecProps,secinfo.WordProps,wr));
				}
			}

			pIterator->SetAt(oldplace);

			return bSet;
		}
	}

	return FALSE;
}

FX_BOOL CFX_Edit::SetWordProps(EDIT_PROPS_E eProps, const CPVT_WordPlace & place,
								const CPVT_WordProps * pWordProps, const CPVT_WordRange & wr, FX_BOOL bAddUndo)
{
	if (m_pVT->IsValid() && m_pVT->IsRichText())
	{
		if (IPDF_VariableText_Iterator * pIterator = m_pVT->GetIterator())
		{
			FX_BOOL bSet = FALSE;
			CPVT_Word wordinfo;
			CPVT_Word OldWordinfo;

			CPVT_WordPlace oldplace = pIterator->GetAt();

			if (pWordProps)
			{
				pIterator->SetAt(place);
				if (pIterator->GetWord(wordinfo))
				{
					if (bAddUndo) OldWordinfo = wordinfo;

					switch(eProps)
					{
					case EP_FONTINDEX:
						if (wordinfo.WordProps.nFontIndex != pWordProps->nFontIndex)
						{
							if (IFX_Edit_FontMap* pFontMap = GetFontMap())
							{
								wordinfo.WordProps.nFontIndex = pFontMap->GetWordFontIndex(wordinfo.Word,wordinfo.nCharset,pWordProps->nFontIndex);
							}
							bSet = TRUE;
						}
						break;
					case EP_FONTSIZE:
						if (!FX_EDIT_IsFloatEqual(wordinfo.WordProps.fFontSize,pWordProps->fFontSize))
						{
							wordinfo.WordProps.fFontSize = pWordProps->fFontSize;
							bSet = TRUE;
						}
						break;
					case EP_WORDCOLOR:
						if (wordinfo.WordProps.dwWordColor != pWordProps->dwWordColor)
						{
							wordinfo.WordProps.dwWordColor = pWordProps->dwWordColor;
							bSet = TRUE;
						}
						break;
					case EP_SCRIPTTYPE:
						if (wordinfo.WordProps.nScriptType != pWordProps->nScriptType)
						{
							wordinfo.WordProps.nScriptType = pWordProps->nScriptType;
							bSet = TRUE;
						}
						break;
					case EP_CHARSPACE:
						if (!FX_EDIT_IsFloatEqual(wordinfo.WordProps.fCharSpace,pWordProps->fCharSpace))
						{
							wordinfo.WordProps.fCharSpace = pWordProps->fCharSpace;
							bSet = TRUE;
						}
						break;
					case EP_HORZSCALE:
						if (wordinfo.WordProps.nHorzScale != pWordProps->nHorzScale)
						{
							wordinfo.WordProps.nHorzScale = pWordProps->nHorzScale;
							bSet = TRUE;
						}
						break;
					case EP_UNDERLINE:
						if (pWordProps->nWordStyle & PVTWORD_STYLE_UNDERLINE)
						{
							if ((wordinfo.WordProps.nWordStyle & PVTWORD_STYLE_UNDERLINE) == 0)
							{
								wordinfo.WordProps.nWordStyle |= PVTWORD_STYLE_UNDERLINE;
								bSet = TRUE;
							}
						}
						else
						{
							if ((wordinfo.WordProps.nWordStyle & PVTWORD_STYLE_UNDERLINE) != 0)
							{
								wordinfo.WordProps.nWordStyle &= ~PVTWORD_STYLE_UNDERLINE;
								bSet = TRUE;
							}
						}
						break;
					case EP_CROSSOUT:
						if (pWordProps->nWordStyle & PVTWORD_STYLE_CROSSOUT)
						{
							if ((wordinfo.WordProps.nWordStyle & PVTWORD_STYLE_CROSSOUT) == 0)
							{
								wordinfo.WordProps.nWordStyle |= PVTWORD_STYLE_CROSSOUT;
								bSet = TRUE;
							}
						}
						else
						{
							if ((wordinfo.WordProps.nWordStyle & PVTWORD_STYLE_CROSSOUT) != 0)
							{
								wordinfo.WordProps.nWordStyle &= ~PVTWORD_STYLE_CROSSOUT;
								bSet = TRUE;
							}
						}
						break;
					case EP_BOLD:
						if (pWordProps->nWordStyle & PVTWORD_STYLE_BOLD)
						{
							if ((wordinfo.WordProps.nWordStyle & PVTWORD_STYLE_BOLD) == 0)
							{
								wordinfo.WordProps.nWordStyle |= PVTWORD_STYLE_BOLD;
								bSet = TRUE;
							}
						}
						else
						{
							if ((wordinfo.WordProps.nWordStyle & PVTWORD_STYLE_BOLD) != 0)
							{
								wordinfo.WordProps.nWordStyle &= ~PVTWORD_STYLE_BOLD;
								bSet = TRUE;
							}
						}
						break;
					case EP_ITALIC:
						if (pWordProps->nWordStyle & PVTWORD_STYLE_ITALIC)
						{
							if ((wordinfo.WordProps.nWordStyle & PVTWORD_STYLE_ITALIC) == 0)
							{
								wordinfo.WordProps.nWordStyle |= PVTWORD_STYLE_ITALIC;
								bSet = TRUE;
							}
						}
						else
						{
							if ((wordinfo.WordProps.nWordStyle & PVTWORD_STYLE_ITALIC) != 0)
							{
								wordinfo.WordProps.nWordStyle &= ~PVTWORD_STYLE_ITALIC;
								bSet = TRUE;
							}
						}
						break;
					default:
						break;
					}
				}
			}

			if (bSet)
			{
				pIterator->SetWord(wordinfo);

				if (bAddUndo && m_bEnableUndo)
				{
					AddEditUndoItem(new CFXEU_SetWordProps
						(this,place,eProps,OldWordinfo.WordProps,wordinfo.WordProps,wr));
				}
			}

			pIterator->SetAt(oldplace);
			return bSet;
		}
	}

	return FALSE;
}

void CFX_Edit::SetText(const FX_WCHAR* text,int32_t charset /*= DEFAULT_CHARSET*/,
						const CPVT_SecProps * pSecProps /*= NULL*/,const CPVT_WordProps * pWordProps /*= NULL*/)
{
	SetText(text,charset,pSecProps,pWordProps,TRUE,TRUE);
}

FX_BOOL CFX_Edit::InsertWord(FX_WORD word, int32_t charset /*= DEFAULT_CHARSET*/, const CPVT_WordProps * pWordProps /*= NULL*/)
{
	return InsertWord(word,charset,pWordProps,TRUE,TRUE);
}

FX_BOOL CFX_Edit::InsertReturn(const CPVT_SecProps * pSecProps /*= NULL*/,const CPVT_WordProps * pWordProps /*= NULL*/)
{
	return InsertReturn(pSecProps,pWordProps,TRUE,TRUE);
}

FX_BOOL CFX_Edit::Backspace()
{
	return Backspace(TRUE,TRUE);
}

FX_BOOL CFX_Edit::Delete()
{
	return Delete(TRUE,TRUE);
}

FX_BOOL CFX_Edit::Clear()
{
	return Clear(TRUE,TRUE);
}

FX_BOOL CFX_Edit::InsertText(const FX_WCHAR* text, int32_t charset /*= DEFAULT_CHARSET*/,
								const CPVT_SecProps * pSecProps /*= NULL*/,const CPVT_WordProps * pWordProps /*= NULL*/)
{
	return InsertText(text,charset,pSecProps,pWordProps,TRUE,TRUE);
}

FX_FLOAT CFX_Edit::GetFontSize() const
{
	return m_pVT->GetFontSize();
}

FX_WORD CFX_Edit::GetPasswordChar() const
{
	return m_pVT->GetPasswordChar();
}

int32_t CFX_Edit::GetCharArray() const
{
	return m_pVT->GetCharArray();
}

CPDF_Rect CFX_Edit::GetPlateRect() const
{
	return m_pVT->GetPlateRect();
}

CPDF_Rect CFX_Edit::GetContentRect() const
{
	return VTToEdit(m_pVT->GetContentRect());
}

int32_t CFX_Edit::GetHorzScale() const
{
	return m_pVT->GetHorzScale();
}

FX_FLOAT CFX_Edit::GetCharSpace() const
{
	return m_pVT->GetCharSpace();
}

// inner methods

CPVT_WordRange CFX_Edit::GetWholeWordRange() const
{
	if (m_pVT->IsValid())
		return CPVT_WordRange(m_pVT->GetBeginWordPlace(),m_pVT->GetEndWordPlace());

	return CPVT_WordRange();
}

CPVT_WordRange CFX_Edit::GetVisibleWordRange() const
{
	if (m_bEnableOverflow) return GetWholeWordRange();

	if (m_pVT->IsValid())
	{
		CPDF_Rect rcPlate = m_pVT->GetPlateRect();

		CPVT_WordPlace place1 = m_pVT->SearchWordPlace(EditToVT(CPDF_Point(rcPlate.left,rcPlate.top)));
		CPVT_WordPlace place2 = m_pVT->SearchWordPlace(EditToVT(CPDF_Point(rcPlate.right,rcPlate.bottom)));

		return CPVT_WordRange(place1,place2);
	}

	return CPVT_WordRange();
}

CPVT_WordPlace CFX_Edit::SearchWordPlace(const CPDF_Point& point) const
{
	if (m_pVT->IsValid())
	{
		return m_pVT->SearchWordPlace(EditToVT(point));
	}

	return CPVT_WordPlace();
}

void CFX_Edit::Paint()
{
	if (m_pVT->IsValid())
	{
		RearrangeAll();
		ScrollToCaret();
		Refresh(RP_NOANALYSE);
		SetCaretOrigin();
		SetCaretInfo();
	}
}

void CFX_Edit::RearrangeAll()
{
	if (m_pVT->IsValid())
	{
		m_pVT->UpdateWordPlace(m_wpCaret);
		m_pVT->RearrangeAll();
		m_pVT->UpdateWordPlace(m_wpCaret);
		SetScrollInfo();
		SetContentChanged();
	}
}

void CFX_Edit::RearrangePart(const CPVT_WordRange & range)
{
	if (m_pVT->IsValid())
	{
		m_pVT->UpdateWordPlace(m_wpCaret);
		m_pVT->RearrangePart(range);
		m_pVT->UpdateWordPlace(m_wpCaret);
		SetScrollInfo();
		SetContentChanged();
	}
}

void CFX_Edit::SetContentChanged()
{
	if (m_bNotify && m_pNotify)
	{
		CPDF_Rect rcContent = m_pVT->GetContentRect();
		if (rcContent.Width() != m_rcOldContent.Width() ||
			rcContent.Height() != m_rcOldContent.Height())
		{
			if (!m_bNotifyFlag)
			{
				m_bNotifyFlag = TRUE;
				m_pNotify->IOnContentChange(rcContent);
				m_bNotifyFlag = FALSE;
			}
			m_rcOldContent = rcContent;
		}
	}
}

void CFX_Edit::SelectAll()
{
	if (m_pVT->IsValid())
	{
		m_SelState = GetWholeWordRange();
		SetCaret(m_SelState.EndPos);

		ScrollToCaret();
		CPVT_WordRange wrVisible = GetVisibleWordRange();
		Refresh(RP_OPTIONAL,&wrVisible);
		SetCaretInfo();
	}
}

void CFX_Edit::SelectNone()
{
	if (m_pVT->IsValid())
	{
		if (m_SelState.IsExist())
		{
			CPVT_WordRange wrTemp = m_SelState.ConvertToWordRange();
			m_SelState.Default();
			Refresh(RP_OPTIONAL,&wrTemp);
		}
	}
}

FX_BOOL	CFX_Edit::IsSelected() const
{
	return m_SelState.IsExist();
}

CPDF_Point CFX_Edit::VTToEdit(const CPDF_Point & point) const
{
	CPDF_Rect rcContent = m_pVT->GetContentRect();
	CPDF_Rect rcPlate = m_pVT->GetPlateRect();

	FX_FLOAT fPadding = 0.0f;

	switch (m_nAlignment)
	{
	case 0:
		fPadding = 0.0f;
		break;
	case 1:
		fPadding = (rcPlate.Height() - rcContent.Height()) * 0.5f;
		break;
	case 2:
		fPadding = rcPlate.Height() - rcContent.Height();
		break;
	}

	return CPDF_Point(point.x - (m_ptScrollPos.x - rcPlate.left),
		point.y - (m_ptScrollPos.y + fPadding - rcPlate.top));
}

CPDF_Point CFX_Edit::EditToVT(const CPDF_Point & point) const
{
	CPDF_Rect rcContent = m_pVT->GetContentRect();
	CPDF_Rect rcPlate = m_pVT->GetPlateRect();

	FX_FLOAT fPadding = 0.0f;

	switch (m_nAlignment)
	{
	case 0:
		fPadding = 0.0f;
		break;
	case 1:
		fPadding = (rcPlate.Height() - rcContent.Height()) * 0.5f;
		break;
	case 2:
		fPadding = rcPlate.Height() - rcContent.Height();
		break;
	}

	return CPDF_Point(point.x + (m_ptScrollPos.x - rcPlate.left),
		point.y + (m_ptScrollPos.y + fPadding - rcPlate.top));
}

CPDF_Rect CFX_Edit::VTToEdit(const CPDF_Rect & rect) const
{
	CPDF_Point ptLeftBottom = VTToEdit(CPDF_Point(rect.left,rect.bottom));
	CPDF_Point ptRightTop = VTToEdit(CPDF_Point(rect.right,rect.top));

	return CPDF_Rect(ptLeftBottom.x,ptLeftBottom.y,ptRightTop.x,ptRightTop.y);
}

CPDF_Rect CFX_Edit::EditToVT(const CPDF_Rect & rect) const
{
	CPDF_Point ptLeftBottom = EditToVT(CPDF_Point(rect.left,rect.bottom));
	CPDF_Point ptRightTop = EditToVT(CPDF_Point(rect.right,rect.top));

	return CPDF_Rect(ptLeftBottom.x,ptLeftBottom.y,ptRightTop.x,ptRightTop.y);
}

void CFX_Edit::SetScrollInfo()
{
	if (m_bNotify && m_pNotify)
	{
		CPDF_Rect rcPlate = m_pVT->GetPlateRect();
		CPDF_Rect rcContent = m_pVT->GetContentRect();

		if (!m_bNotifyFlag)
		{
			m_bNotifyFlag = TRUE;
			m_pNotify->IOnSetScrollInfoX(rcPlate.left, rcPlate.right,
								rcContent.left, rcContent.right, rcPlate.Width() / 3, rcPlate.Width());

			m_pNotify->IOnSetScrollInfoY(rcPlate.bottom, rcPlate.top,
					rcContent.bottom, rcContent.top, rcPlate.Height() / 3, rcPlate.Height());
			m_bNotifyFlag = FALSE;
		}
	}
}

void CFX_Edit::SetScrollPosX(FX_FLOAT fx)
{
	if (!m_bEnableScroll) return;

	if (m_pVT->IsValid())
	{
		if (!FX_EDIT_IsFloatEqual(m_ptScrollPos.x,fx))
		{
			m_ptScrollPos.x = fx;
			Refresh(RP_NOANALYSE);

			if (m_bNotify && m_pNotify)
			{
				if (!m_bNotifyFlag)
				{
					m_bNotifyFlag = TRUE;
					m_pNotify->IOnSetScrollPosX(fx);
					m_bNotifyFlag = FALSE;
				}
			}
		}
	}
}

void CFX_Edit::SetScrollPosY(FX_FLOAT fy)
{
	if (!m_bEnableScroll) return;

	if (m_pVT->IsValid())
	{
		if (!FX_EDIT_IsFloatEqual(m_ptScrollPos.y,fy))
		{
			m_ptScrollPos.y = fy;
			Refresh(RP_NOANALYSE);

			if (m_bNotify && m_pNotify)
			{
				if (!m_bNotifyFlag)
				{
					m_bNotifyFlag = TRUE;
					m_pNotify->IOnSetScrollPosY(fy);
					m_bNotifyFlag = FALSE;
				}
			}
		}
	}
}

void CFX_Edit::SetScrollPos(const CPDF_Point & point)
{
	SetScrollPosX(point.x);
	SetScrollPosY(point.y);
	SetScrollLimit();
	SetCaretInfo();
}

CPDF_Point CFX_Edit::GetScrollPos() const
{
	return m_ptScrollPos;
}

void CFX_Edit::SetScrollLimit()
{
	if (m_pVT->IsValid())
	{
		CPDF_Rect rcContent = m_pVT->GetContentRect();
		CPDF_Rect rcPlate = m_pVT->GetPlateRect();

		if (rcPlate.Width() > rcContent.Width())
		{
			SetScrollPosX(rcPlate.left);
		}
		else
		{
			if (FX_EDIT_IsFloatSmaller(m_ptScrollPos.x, rcContent.left))
			{
				SetScrollPosX(rcContent.left);
			}
			else if (FX_EDIT_IsFloatBigger(m_ptScrollPos.x, rcContent.right - rcPlate.Width()))
			{
				SetScrollPosX(rcContent.right - rcPlate.Width());
			}
		}

		if (rcPlate.Height() > rcContent.Height())
		{
			SetScrollPosY(rcPlate.top);
		}
		else
		{
			if (FX_EDIT_IsFloatSmaller(m_ptScrollPos.y, rcContent.bottom + rcPlate.Height()))
			{
				SetScrollPosY(rcContent.bottom + rcPlate.Height());
			}
			else if (FX_EDIT_IsFloatBigger(m_ptScrollPos.y, rcContent.top))
			{
				SetScrollPosY(rcContent.top);
			}
		}
	}
}

void CFX_Edit::ScrollToCaret()
{
	SetScrollLimit();

	if (m_pVT->IsValid())
	{
		CPDF_Point ptHead(0,0);
		CPDF_Point ptFoot(0,0);

		if (IPDF_VariableText_Iterator * pIterator = m_pVT->GetIterator())
		{
			pIterator->SetAt(m_wpCaret);

			CPVT_Word word;
			CPVT_Line line;
			if (pIterator->GetWord(word))
			{
				ptHead.x = word.ptWord.x + word.fWidth;
				ptHead.y = word.ptWord.y + word.fAscent;
				ptFoot.x = word.ptWord.x + word.fWidth;
				ptFoot.y = word.ptWord.y + word.fDescent;
			}
			else if (pIterator->GetLine(line))
			{
				ptHead.x = line.ptLine.x;
				ptHead.y = line.ptLine.y + line.fLineAscent;
				ptFoot.x = line.ptLine.x;
				ptFoot.y = line.ptLine.y + line.fLineDescent;
			}
		}

		CPDF_Point ptHeadEdit = VTToEdit(ptHead);
		CPDF_Point ptFootEdit = VTToEdit(ptFoot);

		CPDF_Rect rcPlate = m_pVT->GetPlateRect();

		if (!FX_EDIT_IsFloatEqual(rcPlate.left,rcPlate.right))
		{
			if (FX_EDIT_IsFloatSmaller(ptHeadEdit.x, rcPlate.left) ||
				FX_EDIT_IsFloatEqual(ptHeadEdit.x, rcPlate.left))
			{
				SetScrollPosX(ptHead.x);
			}
			else if (FX_EDIT_IsFloatBigger(ptHeadEdit.x, rcPlate.right))
			{
				SetScrollPosX(ptHead.x - rcPlate.Width());
			}
		}

		if (!FX_EDIT_IsFloatEqual(rcPlate.top,rcPlate.bottom))
		{
			if (FX_EDIT_IsFloatSmaller(ptFootEdit.y, rcPlate.bottom) ||
				FX_EDIT_IsFloatEqual(ptFootEdit.y, rcPlate.bottom))
			{
				if (FX_EDIT_IsFloatSmaller(ptHeadEdit.y, rcPlate.top))
				{
					SetScrollPosY(ptFoot.y + rcPlate.Height());
				}
			}
			else if (FX_EDIT_IsFloatBigger(ptHeadEdit.y, rcPlate.top))
			{
				if (FX_EDIT_IsFloatBigger(ptFootEdit.y, rcPlate.bottom))
				{
					SetScrollPosY(ptHead.y);
				}
			}
		}
	}
}

void CFX_Edit::Refresh(REFRESH_PLAN_E ePlan,const CPVT_WordRange * pRange1,const CPVT_WordRange * pRange2)
{
	if (m_bEnableRefresh && m_pVT->IsValid())
	{
		m_Refresh.BeginRefresh();
		RefreshPushLineRects(GetVisibleWordRange());

// 		if (!FX_EDIT_IsFloatEqual(m_ptRefreshScrollPos.x,m_ptScrollPos.x) ||
// 			!FX_EDIT_IsFloatEqual(m_ptRefreshScrollPos.y,m_ptScrollPos.y))
// 		{
			m_Refresh.NoAnalyse();
			m_ptRefreshScrollPos = m_ptScrollPos;
// 		}
// 		else
// 		{
// 			switch (ePlan)
// 			{
// 			case RP_ANALYSE:
// 				m_Refresh.Analyse(m_pVT->GetAlignment());
//
// 				if (pRange1) RefreshPushRandomRects(*pRange1);
// 				if (pRange2) RefreshPushRandomRects(*pRange2);
// 				break;
// 			case RP_NOANALYSE:
// 				m_Refresh.NoAnalyse();
// 				break;
// 			case RP_OPTIONAL:
// 				if (pRange1) RefreshPushRandomRects(*pRange1);
// 				if (pRange2) RefreshPushRandomRects(*pRange2);
// 				break;
// 			}
// 		}

		if (m_bNotify && m_pNotify)
		{
			if (!m_bNotifyFlag)
			{
				m_bNotifyFlag = TRUE;
				if (const CFX_Edit_RectArray * pRects = m_Refresh.GetRefreshRects())
				{
					for (int32_t i = 0, sz = pRects->GetSize(); i < sz; i++)
						m_pNotify->IOnInvalidateRect(pRects->GetAt(i));
				}
				m_bNotifyFlag = FALSE;
			}
		}

		m_Refresh.EndRefresh();
	}
}

void CFX_Edit::RefreshPushLineRects(const CPVT_WordRange & wr)
{
	if (m_pVT->IsValid())
	{
		if (IPDF_VariableText_Iterator * pIterator = m_pVT->GetIterator())
		{
			CPVT_WordPlace wpBegin = wr.BeginPos;
			m_pVT->UpdateWordPlace(wpBegin);
			CPVT_WordPlace wpEnd = wr.EndPos;
			m_pVT->UpdateWordPlace(wpEnd);
			pIterator->SetAt(wpBegin);

			CPVT_Line lineinfo;
			do
			{
				if (!pIterator->GetLine(lineinfo))break;
				if (lineinfo.lineplace.LineCmp(wpEnd) > 0)break;

				CPDF_Rect rcLine(lineinfo.ptLine.x,
									lineinfo.ptLine.y + lineinfo.fLineDescent,
									lineinfo.ptLine.x + lineinfo.fLineWidth,
									lineinfo.ptLine.y + lineinfo.fLineAscent);

				m_Refresh.Push(CPVT_WordRange(lineinfo.lineplace,lineinfo.lineEnd),VTToEdit(rcLine));

			}while (pIterator->NextLine());
		}
	}
}

void CFX_Edit::RefreshPushRandomRects(const CPVT_WordRange & wr)
{
	if (m_pVT->IsValid())
	{
		if (IPDF_VariableText_Iterator * pIterator = m_pVT->GetIterator())
		{
			CPVT_WordRange wrTemp = wr;

			m_pVT->UpdateWordPlace(wrTemp.BeginPos);
			m_pVT->UpdateWordPlace(wrTemp.EndPos);
			pIterator->SetAt(wrTemp.BeginPos);

			CPVT_Word wordinfo;
			CPVT_Line lineinfo;
			CPVT_WordPlace place;

			while (pIterator->NextWord())
			{
				place = pIterator->GetAt();
				if (place.WordCmp(wrTemp.EndPos) > 0) break;

				pIterator->GetWord(wordinfo);
				pIterator->GetLine(lineinfo);

				if (place.LineCmp(wrTemp.BeginPos) == 0 || place.LineCmp(wrTemp.EndPos) == 0)
				{
					CPDF_Rect rcWord(wordinfo.ptWord.x,
										lineinfo.ptLine.y + lineinfo.fLineDescent,
										wordinfo.ptWord.x + wordinfo.fWidth,
										lineinfo.ptLine.y + lineinfo.fLineAscent);

					m_Refresh.AddRefresh(VTToEdit(rcWord));
				}
				else
				{
					CPDF_Rect rcLine(lineinfo.ptLine.x,
										lineinfo.ptLine.y + lineinfo.fLineDescent,
										lineinfo.ptLine.x + lineinfo.fLineWidth,
										lineinfo.ptLine.y + lineinfo.fLineAscent);

					m_Refresh.AddRefresh(VTToEdit(rcLine));

					pIterator->NextLine();
				}
			}
		}
	}
}

void CFX_Edit::RefreshWordRange(const CPVT_WordRange& wr)
{
	if (IPDF_VariableText_Iterator * pIterator = m_pVT->GetIterator())
	{
		CPVT_WordRange wrTemp = wr;

		m_pVT->UpdateWordPlace(wrTemp.BeginPos);
		m_pVT->UpdateWordPlace(wrTemp.EndPos);
		pIterator->SetAt(wrTemp.BeginPos);

		CPVT_Word wordinfo;
		CPVT_Line lineinfo;
		CPVT_WordPlace place;

		while (pIterator->NextWord())
		{
			place = pIterator->GetAt();
			if (place.WordCmp(wrTemp.EndPos) > 0) break;

			pIterator->GetWord(wordinfo);
			pIterator->GetLine(lineinfo);

			if (place.LineCmp(wrTemp.BeginPos) == 0 || place.LineCmp(wrTemp.EndPos) == 0)
			{
				CPDF_Rect rcWord(wordinfo.ptWord.x,
									lineinfo.ptLine.y + lineinfo.fLineDescent,
									wordinfo.ptWord.x + wordinfo.fWidth,
									lineinfo.ptLine.y + lineinfo.fLineAscent);

				if (m_bNotify && m_pNotify)
				{
					if (!m_bNotifyFlag)
					{
						m_bNotifyFlag = TRUE;
						CPDF_Rect rcRefresh = VTToEdit(rcWord);
						m_pNotify->IOnInvalidateRect(&rcRefresh);
						m_bNotifyFlag = FALSE;
					}
				}
			}
			else
			{
				CPDF_Rect rcLine(lineinfo.ptLine.x,
									lineinfo.ptLine.y + lineinfo.fLineDescent,
									lineinfo.ptLine.x + lineinfo.fLineWidth,
									lineinfo.ptLine.y + lineinfo.fLineAscent);

				if (m_bNotify && m_pNotify)
				{
					if (!m_bNotifyFlag)
					{
						m_bNotifyFlag = TRUE;
						CPDF_Rect rcRefresh = VTToEdit(rcLine);
						m_pNotify->IOnInvalidateRect(&rcRefresh);
						m_bNotifyFlag = FALSE;
					}
				}

				pIterator->NextLine();
			}
		}
	}
}

void CFX_Edit::SetCaret(const CPVT_WordPlace & place)
{
	m_wpOldCaret = m_wpCaret;
	m_wpCaret = place;
}

void CFX_Edit::SetCaretInfo()
{
	if (m_bNotify && m_pNotify)
	{
		if (!m_bNotifyFlag)
		{
			CPDF_Point ptHead(0.0f,0.0f),ptFoot(0.0f,0.0f);

			if (IPDF_VariableText_Iterator * pIterator = m_pVT->GetIterator())
			{
				pIterator->SetAt(m_wpCaret);
				CPVT_Word word;
				CPVT_Line line;
				if (pIterator->GetWord(word))
				{
					ptHead.x = word.ptWord.x + word.fWidth;
					ptHead.y = word.ptWord.y + word.fAscent;
					ptFoot.x = word.ptWord.x + word.fWidth;
					ptFoot.y = word.ptWord.y + word.fDescent;
				}
				else if (pIterator->GetLine(line))
				{
					ptHead.x = line.ptLine.x;
					ptHead.y = line.ptLine.y + line.fLineAscent;
					ptFoot.x = line.ptLine.x;
					ptFoot.y = line.ptLine.y + line.fLineDescent;
				}
			}

			m_bNotifyFlag = TRUE;
			m_pNotify->IOnSetCaret(!m_SelState.IsExist(),VTToEdit(ptHead),VTToEdit(ptFoot), m_wpCaret);
			m_bNotifyFlag = FALSE;
		}
	}

	SetCaretChange();
}

void CFX_Edit::SetCaretChange()
{
	if (m_wpCaret == m_wpOldCaret) return;

	if (m_bNotify && m_pVT->IsRichText() && m_pNotify)
	{
		CPVT_SecProps SecProps;
		CPVT_WordProps WordProps;

		if (IPDF_VariableText_Iterator * pIterator = m_pVT->GetIterator())
		{
			pIterator->SetAt(m_wpCaret);
			CPVT_Word word;
			CPVT_Section section;

			if (pIterator->GetSection(section))
			{
				SecProps = section.SecProps;
				WordProps = section.WordProps;
			}

			if (pIterator->GetWord(word))
			{
				WordProps = word.WordProps;
			}
		}

		if (!m_bNotifyFlag)
		{
			m_bNotifyFlag = TRUE;
			m_pNotify->IOnCaretChange(SecProps,WordProps);
			m_bNotifyFlag = FALSE;
		}
	}
}

void CFX_Edit::SetCaret(int32_t nPos)
{
	if (m_pVT->IsValid())
	{
		SelectNone();
		SetCaret(m_pVT->WordIndexToWordPlace(nPos));
		m_SelState.Set(m_wpCaret,m_wpCaret);

		ScrollToCaret();
		SetCaretOrigin();
		SetCaretInfo();
	}
}

void CFX_Edit::OnMouseDown(const CPDF_Point & point,FX_BOOL bShift,FX_BOOL bCtrl)
{
	if (m_pVT->IsValid())
	{
		SelectNone();
		SetCaret(m_pVT->SearchWordPlace(EditToVT(point)));
		m_SelState.Set(m_wpCaret,m_wpCaret);

		ScrollToCaret();
		SetCaretOrigin();
		SetCaretInfo();
	}
}

void CFX_Edit::OnMouseMove(const CPDF_Point & point,FX_BOOL bShift,FX_BOOL bCtrl)
{
	if (m_pVT->IsValid())
	{
		SetCaret(m_pVT->SearchWordPlace(EditToVT(point)));

		if (m_wpCaret != m_wpOldCaret)
		{
			m_SelState.SetEndPos(m_wpCaret);

			ScrollToCaret();
			CPVT_WordRange wr(m_wpOldCaret,m_wpCaret);
			Refresh(RP_OPTIONAL,&wr);
			SetCaretOrigin();
			SetCaretInfo();
		}
	}
}

void CFX_Edit::OnVK_UP(FX_BOOL bShift,FX_BOOL bCtrl)
{
	if (m_pVT->IsValid())
	{
		SetCaret(m_pVT->GetUpWordPlace(m_wpCaret,m_ptCaret));

		if (bShift)
		{
			if (m_SelState.IsExist())
				m_SelState.SetEndPos(m_wpCaret);
			else
				m_SelState.Set(m_wpOldCaret,m_wpCaret);

			if (m_wpOldCaret != m_wpCaret)
			{
				ScrollToCaret();
				CPVT_WordRange wr(m_wpOldCaret, m_wpCaret);
				Refresh(RP_OPTIONAL, &wr);
				SetCaretInfo();
			}
		}
		else
		{
			SelectNone();

			ScrollToCaret();
			SetCaretInfo();
		}
	}
}

void CFX_Edit::OnVK_DOWN(FX_BOOL bShift,FX_BOOL bCtrl)
{
	if (m_pVT->IsValid())
	{
		SetCaret(m_pVT->GetDownWordPlace(m_wpCaret,m_ptCaret));

		if (bShift)
		{
			if (m_SelState.IsExist())
				m_SelState.SetEndPos(m_wpCaret);
			else
				m_SelState.Set(m_wpOldCaret,m_wpCaret);

			if (m_wpOldCaret != m_wpCaret)
			{
				ScrollToCaret();
				CPVT_WordRange wr(m_wpOldCaret,m_wpCaret);
				Refresh(RP_OPTIONAL, &wr);
				SetCaretInfo();
			}
		}
		else
		{
			SelectNone();

			ScrollToCaret();
			SetCaretInfo();
		}
	}
}

void CFX_Edit::OnVK_LEFT(FX_BOOL bShift,FX_BOOL bCtrl)
{
	if (m_pVT->IsValid())
	{
		if (bShift)
		{
			if (m_wpCaret == m_pVT->GetLineBeginPlace(m_wpCaret) &&
				m_wpCaret != m_pVT->GetSectionBeginPlace(m_wpCaret))
				SetCaret(m_pVT->GetPrevWordPlace(m_wpCaret));

			SetCaret(m_pVT->GetPrevWordPlace(m_wpCaret));

			if (m_SelState.IsExist())
				m_SelState.SetEndPos(m_wpCaret);
			else
				m_SelState.Set(m_wpOldCaret, m_wpCaret);

			if (m_wpOldCaret != m_wpCaret)
			{
				ScrollToCaret();
				CPVT_WordRange wr(m_wpOldCaret,m_wpCaret);
				Refresh(RP_OPTIONAL,&wr);
				SetCaretInfo();
			}
		}
		else
		{
			if (m_SelState.IsExist())
			{
				if (m_SelState.BeginPos.WordCmp(m_SelState.EndPos)<0)
					SetCaret(m_SelState.BeginPos);
				else
					SetCaret(m_SelState.EndPos);

				SelectNone();
				ScrollToCaret();
				SetCaretInfo();
			}
			else
			{
				if (m_wpCaret == m_pVT->GetLineBeginPlace(m_wpCaret) &&
					m_wpCaret != m_pVT->GetSectionBeginPlace(m_wpCaret))
					SetCaret(m_pVT->GetPrevWordPlace(m_wpCaret));

				SetCaret(m_pVT->GetPrevWordPlace(m_wpCaret));

				ScrollToCaret();
				SetCaretOrigin();
				SetCaretInfo();
			}
		}
	}
}

void CFX_Edit::OnVK_RIGHT(FX_BOOL bShift,FX_BOOL bCtrl)
{
	if (m_pVT->IsValid())
	{
		if (bShift)
		{
			SetCaret(m_pVT->GetNextWordPlace(m_wpCaret));

			if (m_wpCaret == m_pVT->GetLineEndPlace(m_wpCaret) &&
				m_wpCaret != m_pVT->GetSectionEndPlace(m_wpCaret))
				SetCaret(m_pVT->GetNextWordPlace(m_wpCaret));

			if (m_SelState.IsExist())
				m_SelState.SetEndPos(m_wpCaret);
			else
				m_SelState.Set(m_wpOldCaret,m_wpCaret);

			if (m_wpOldCaret != m_wpCaret)
			{
				ScrollToCaret();
				CPVT_WordRange wr(m_wpOldCaret,m_wpCaret);
				Refresh(RP_OPTIONAL,&wr);
				SetCaretInfo();
			}
		}
		else
		{
			if (m_SelState.IsExist())
			{
				if (m_SelState.BeginPos.WordCmp(m_SelState.EndPos)>0)
					SetCaret(m_SelState.BeginPos);
				else
					SetCaret(m_SelState.EndPos);

				SelectNone();
				ScrollToCaret();
				SetCaretInfo();
			}
			else
			{
				SetCaret(m_pVT->GetNextWordPlace(m_wpCaret));

				if (m_wpCaret == m_pVT->GetLineEndPlace(m_wpCaret) &&
					m_wpCaret != m_pVT->GetSectionEndPlace(m_wpCaret))
					SetCaret(m_pVT->GetNextWordPlace(m_wpCaret));

				ScrollToCaret();
				SetCaretOrigin();
				SetCaretInfo();
			}
		}
	}
}

void CFX_Edit::OnVK_HOME(FX_BOOL bShift,FX_BOOL bCtrl)
{
	if (m_pVT->IsValid())
	{
		if (bShift)
		{
			if (bCtrl)
				SetCaret(m_pVT->GetBeginWordPlace());
			else
				SetCaret(m_pVT->GetLineBeginPlace(m_wpCaret));

			if (m_SelState.IsExist())
				m_SelState.SetEndPos(m_wpCaret);
			else
				m_SelState.Set(m_wpOldCaret,m_wpCaret);

			ScrollToCaret();
			CPVT_WordRange wr(m_wpOldCaret, m_wpCaret);
			Refresh(RP_OPTIONAL, &wr);
			SetCaretInfo();
		}
		else
		{
			if (m_SelState.IsExist())
			{
				if (m_SelState.BeginPos.WordCmp(m_SelState.EndPos)<0)
					SetCaret(m_SelState.BeginPos);
				else
					SetCaret(m_SelState.EndPos);

				SelectNone();
				ScrollToCaret();
				SetCaretInfo();
			}
			else
			{
				if (bCtrl)
					SetCaret(m_pVT->GetBeginWordPlace());
				else
					SetCaret(m_pVT->GetLineBeginPlace(m_wpCaret));

				ScrollToCaret();
				SetCaretOrigin();
				SetCaretInfo();
			}
		}
	}
}

void CFX_Edit::OnVK_END(FX_BOOL bShift,FX_BOOL bCtrl)
{
	if (m_pVT->IsValid())
	{
		if (bShift)
		{
			if (bCtrl)
				SetCaret(m_pVT->GetEndWordPlace());
			else
				SetCaret(m_pVT->GetLineEndPlace(m_wpCaret));

			if (m_SelState.IsExist())
				m_SelState.SetEndPos(m_wpCaret);
			else
				m_SelState.Set(m_wpOldCaret, m_wpCaret);

			ScrollToCaret();
			CPVT_WordRange wr(m_wpOldCaret, m_wpCaret);
			Refresh(RP_OPTIONAL, &wr);
			SetCaretInfo();
		}
		else
		{
			if (m_SelState.IsExist())
			{
				if (m_SelState.BeginPos.WordCmp(m_SelState.EndPos)>0)
					SetCaret(m_SelState.BeginPos);
				else
					SetCaret(m_SelState.EndPos);

				SelectNone();
				ScrollToCaret();
				SetCaretInfo();
			}
			else
			{
				if (bCtrl)
					SetCaret(m_pVT->GetEndWordPlace());
				else
					SetCaret(m_pVT->GetLineEndPlace(m_wpCaret));

				ScrollToCaret();
				SetCaretOrigin();
				SetCaretInfo();
			}
		}
	}
}

void CFX_Edit::SetText(const FX_WCHAR* text,int32_t charset,
						const CPVT_SecProps * pSecProps,const CPVT_WordProps * pWordProps, FX_BOOL bAddUndo, FX_BOOL bPaint)
{
	Empty();
	DoInsertText(CPVT_WordPlace(0,0,-1), text, charset, pSecProps, pWordProps);
	if (bPaint) Paint();
	if (m_bOprNotify && m_pOprNotify)
		m_pOprNotify->OnSetText(m_wpCaret, m_wpOldCaret);
	//if (bAddUndo)
}

FX_BOOL CFX_Edit::InsertWord(FX_WORD word, int32_t charset, const CPVT_WordProps * pWordProps, FX_BOOL bAddUndo, FX_BOOL bPaint)
{
	if (IsTextOverflow()) return FALSE;

	if (m_pVT->IsValid())
	{
		m_pVT->UpdateWordPlace(m_wpCaret);

		SetCaret(m_pVT->InsertWord(m_wpCaret,word,GetCharSetFromUnicode(word, charset),pWordProps));
		m_SelState.Set(m_wpCaret,m_wpCaret);

		if (m_wpCaret != m_wpOldCaret)
		{
			if (bAddUndo && m_bEnableUndo)
			{
				AddEditUndoItem(new CFXEU_InsertWord(this,m_wpOldCaret,m_wpCaret,word,charset,pWordProps));
			}

			if (bPaint)
				PaintInsertText(m_wpOldCaret, m_wpCaret);

			if (m_bOprNotify && m_pOprNotify)
				m_pOprNotify->OnInsertWord(m_wpCaret, m_wpOldCaret);

			return TRUE;
		}
	}

	return FALSE;
}

FX_BOOL CFX_Edit::InsertReturn(const CPVT_SecProps * pSecProps,const CPVT_WordProps * pWordProps,
							   FX_BOOL bAddUndo, FX_BOOL bPaint)
{
	if (IsTextOverflow()) return FALSE;

	if (m_pVT->IsValid())
	{
		m_pVT->UpdateWordPlace(m_wpCaret);
		SetCaret(m_pVT->InsertSection(m_wpCaret,pSecProps,pWordProps));
		m_SelState.Set(m_wpCaret,m_wpCaret);

		if (m_wpCaret != m_wpOldCaret)
		{
			if (bAddUndo && m_bEnableUndo)
			{
				AddEditUndoItem(new CFXEU_InsertReturn(this,m_wpOldCaret,m_wpCaret,pSecProps,pWordProps));
			}

			if (bPaint)
			{
				RearrangePart(CPVT_WordRange(m_wpOldCaret, m_wpCaret));
				ScrollToCaret();
				CPVT_WordRange wr(m_wpOldCaret, GetVisibleWordRange().EndPos);
				Refresh(RP_ANALYSE, &wr);
				SetCaretOrigin();
				SetCaretInfo();
			}

			if (m_bOprNotify && m_pOprNotify)
				m_pOprNotify->OnInsertReturn(m_wpCaret, m_wpOldCaret);

			return TRUE;
		}
	}

	return FALSE;
}

FX_BOOL CFX_Edit::Backspace(FX_BOOL bAddUndo, FX_BOOL bPaint)
{
	if (m_pVT->IsValid())
	{
		if (m_wpCaret == m_pVT->GetBeginWordPlace()) return FALSE;

		CPVT_Section section;
		CPVT_Word word;

		if (bAddUndo)
		{
			if (IPDF_VariableText_Iterator * pIterator = m_pVT->GetIterator())
			{
				pIterator->SetAt(m_wpCaret);
				pIterator->GetSection(section);
				pIterator->GetWord(word);
			}
		}

		m_pVT->UpdateWordPlace(m_wpCaret);
		SetCaret(m_pVT->BackSpaceWord(m_wpCaret));
		m_SelState.Set(m_wpCaret,m_wpCaret);

		if (m_wpCaret != m_wpOldCaret)
		{
			if (bAddUndo && m_bEnableUndo)
			{
				if (m_wpCaret.SecCmp(m_wpOldCaret) != 0)
					AddEditUndoItem(new CFXEU_Backspace(this,m_wpOldCaret,m_wpCaret,word.Word,word.nCharset,
						section.SecProps,section.WordProps));
				else
					AddEditUndoItem(new CFXEU_Backspace(this,m_wpOldCaret,m_wpCaret,word.Word,word.nCharset,
						section.SecProps,word.WordProps));
			}

			if (bPaint)
			{
				RearrangePart(CPVT_WordRange(m_wpCaret,m_wpOldCaret));
				ScrollToCaret();

				CPVT_WordRange wr;
				if (m_wpCaret.SecCmp(m_wpOldCaret) !=0)
					wr = CPVT_WordRange(m_pVT->GetPrevWordPlace(m_wpCaret),GetVisibleWordRange().EndPos);
				else if (m_wpCaret.LineCmp(m_wpOldCaret) !=0)
					wr = CPVT_WordRange(m_pVT->GetLineBeginPlace(m_wpCaret),m_pVT->GetSectionEndPlace(m_wpCaret));
				else
					wr = CPVT_WordRange(m_pVT->GetPrevWordPlace(m_wpCaret),m_pVT->GetSectionEndPlace(m_wpCaret));

				Refresh(RP_ANALYSE, &wr);

				SetCaretOrigin();
				SetCaretInfo();
			}

			if (m_bOprNotify && m_pOprNotify)
				m_pOprNotify->OnBackSpace(m_wpCaret, m_wpOldCaret);

			return TRUE;
		}
	}

	return FALSE;
}

FX_BOOL CFX_Edit::Delete(FX_BOOL bAddUndo, FX_BOOL bPaint)
{
	if (m_pVT->IsValid())
	{
		if (m_wpCaret == m_pVT->GetEndWordPlace()) return FALSE;

		CPVT_Section section;
		CPVT_Word word;

		if (bAddUndo)
		{
			if (IPDF_VariableText_Iterator * pIterator = m_pVT->GetIterator())
			{
				pIterator->SetAt(m_pVT->GetNextWordPlace(m_wpCaret));
				pIterator->GetSection(section);
				pIterator->GetWord(word);
			}
		}

		m_pVT->UpdateWordPlace(m_wpCaret);
		FX_BOOL bSecEnd = (m_wpCaret == m_pVT->GetSectionEndPlace(m_wpCaret));

		SetCaret(m_pVT->DeleteWord(m_wpCaret));
		m_SelState.Set(m_wpCaret,m_wpCaret);

		if (bAddUndo && m_bEnableUndo)
		{
			if (bSecEnd)
				AddEditUndoItem(new CFXEU_Delete(this,m_wpOldCaret,m_wpCaret,word.Word,word.nCharset,
					section.SecProps,section.WordProps,bSecEnd));
			else
				AddEditUndoItem(new CFXEU_Delete(this,m_wpOldCaret,m_wpCaret,word.Word,word.nCharset,
					section.SecProps,word.WordProps,bSecEnd));
		}

		if (bPaint)
		{
			RearrangePart(CPVT_WordRange(m_wpOldCaret,m_wpCaret));
			ScrollToCaret();

			CPVT_WordRange wr;
			if (bSecEnd)
				wr = CPVT_WordRange(m_pVT->GetPrevWordPlace(m_wpOldCaret),GetVisibleWordRange().EndPos);
			else if (m_wpCaret.LineCmp(m_wpOldCaret) !=0)
				wr = CPVT_WordRange(m_pVT->GetLineBeginPlace(m_wpCaret),m_pVT->GetSectionEndPlace(m_wpCaret));
			else
				wr = CPVT_WordRange(m_pVT->GetPrevWordPlace(m_wpOldCaret),m_pVT->GetSectionEndPlace(m_wpCaret));

			Refresh(RP_ANALYSE, &wr);

			SetCaretOrigin();
			SetCaretInfo();
		}

		if (m_bOprNotify && m_pOprNotify)
			m_pOprNotify->OnDelete(m_wpCaret, m_wpOldCaret);

		return TRUE;
	}

	return FALSE;
}

FX_BOOL	CFX_Edit::Empty()
{
	if (m_pVT->IsValid())
	{
		m_pVT->DeleteWords(GetWholeWordRange());
		SetCaret(m_pVT->GetBeginWordPlace());

		return TRUE;
	}

	return FALSE;
}

FX_BOOL CFX_Edit::Clear(FX_BOOL bAddUndo, FX_BOOL bPaint)
{
	if (m_pVT->IsValid())
	{
		if (m_SelState.IsExist())
		{
			CPVT_WordRange range = m_SelState.ConvertToWordRange();

			if (bAddUndo && m_bEnableUndo)
			{
				if (m_pVT->IsRichText())
				{
					BeginGroupUndo(L"");

					if (IPDF_VariableText_Iterator * pIterator = m_pVT->GetIterator())
					{
						pIterator->SetAt(range.EndPos);

						CPVT_Word wordinfo;
						CPVT_Section secinfo;
						do
						{
							CPVT_WordPlace place = pIterator->GetAt();
							if (place.WordCmp(range.BeginPos) <= 0)break;

							CPVT_WordPlace oldplace = m_pVT->GetPrevWordPlace(place);

							if (oldplace.SecCmp(place) != 0)
							{
								if (pIterator->GetSection(secinfo))
								{
									AddEditUndoItem(new CFXEU_ClearRich(this,oldplace,place,range,wordinfo.Word,
										wordinfo.nCharset,secinfo.SecProps,secinfo.WordProps));
								}
							}
							else
							{
								if (pIterator->GetWord(wordinfo))
								{
									oldplace = m_pVT->AjustLineHeader(oldplace,TRUE);
									place = m_pVT->AjustLineHeader(place,TRUE);

									AddEditUndoItem(new CFXEU_ClearRich(this,oldplace,place,range,wordinfo.Word,
										wordinfo.nCharset,secinfo.SecProps,wordinfo.WordProps));
								}
							}
						}while (pIterator->PrevWord());
					}
					EndGroupUndo();
				}
				else
				{
					AddEditUndoItem(new CFXEU_Clear(this,range,GetSelText()));
				}
			}

			SelectNone();
			SetCaret(m_pVT->DeleteWords(range));
			m_SelState.Set(m_wpCaret,m_wpCaret);

			if (bPaint)
			{
				RearrangePart(range);
				ScrollToCaret();

				CPVT_WordRange wr(m_wpOldCaret, GetVisibleWordRange().EndPos);
				Refresh(RP_ANALYSE, &wr);

				SetCaretOrigin();
				SetCaretInfo();
			}

			if (m_bOprNotify && m_pOprNotify)
				m_pOprNotify->OnClear(m_wpCaret, m_wpOldCaret);

			return TRUE;
		}
	}

	return FALSE;
}

FX_BOOL CFX_Edit::InsertText(const FX_WCHAR* text, int32_t charset,
					const CPVT_SecProps * pSecProps, const CPVT_WordProps * pWordProps, FX_BOOL bAddUndo, FX_BOOL bPaint)
{
	if (IsTextOverflow()) return FALSE;

	m_pVT->UpdateWordPlace(m_wpCaret);
	SetCaret(DoInsertText(m_wpCaret, text, charset, pSecProps, pWordProps));
	m_SelState.Set(m_wpCaret,m_wpCaret);

	if (m_wpCaret != m_wpOldCaret)
	{
		if (bAddUndo && m_bEnableUndo)
		{
			AddEditUndoItem(new CFXEU_InsertText(this,m_wpOldCaret,m_wpCaret,text,charset,pSecProps,pWordProps));
		}

		if (bPaint)
			PaintInsertText(m_wpOldCaret, m_wpCaret);

		if (m_bOprNotify && m_pOprNotify)
			m_pOprNotify->OnInsertText(m_wpCaret, m_wpOldCaret);

		return TRUE;
	}
	return FALSE;
}

void CFX_Edit::PaintInsertText(const CPVT_WordPlace & wpOld, const CPVT_WordPlace & wpNew)
{
	if (m_pVT->IsValid())
	{
		RearrangePart(CPVT_WordRange(wpOld,wpNew));
		ScrollToCaret();

		CPVT_WordRange wr;
		if (m_wpCaret.LineCmp(wpOld) !=0)
			wr = CPVT_WordRange(m_pVT->GetLineBeginPlace(wpOld),m_pVT->GetSectionEndPlace(wpNew));
		else
			wr = CPVT_WordRange(wpOld,m_pVT->GetSectionEndPlace(wpNew));
		Refresh(RP_ANALYSE, &wr);
		SetCaretOrigin();
		SetCaretInfo();
	}
}

FX_BOOL CFX_Edit::Redo()
{
	if (m_bEnableUndo)
	{
		if (m_Undo.CanRedo())
		{
			m_Undo.Redo();
			return TRUE;
		}
	}

	return FALSE;
}

FX_BOOL CFX_Edit::Undo()
{
	if (m_bEnableUndo)
	{
		if (m_Undo.CanUndo())
		{
			m_Undo.Undo();
			return TRUE;
		}
	}

	return FALSE;
}

void CFX_Edit::SetCaretOrigin()
{
	if (m_pVT->IsValid())
	{
		if (IPDF_VariableText_Iterator * pIterator = m_pVT->GetIterator())
		{
			pIterator->SetAt(m_wpCaret);
			CPVT_Word word;
			CPVT_Line line;
			if (pIterator->GetWord(word))
			{
				m_ptCaret.x = word.ptWord.x + word.fWidth;
				m_ptCaret.y = word.ptWord.y;
			}
			else if (pIterator->GetLine(line))
			{
				m_ptCaret.x = line.ptLine.x;
				m_ptCaret.y = line.ptLine.y;
			}
		}
	}
}

int32_t CFX_Edit::WordPlaceToWordIndex(const CPVT_WordPlace & place) const
{
	if (m_pVT->IsValid())
		return m_pVT->WordPlaceToWordIndex(place);

	return -1;
}

CPVT_WordPlace CFX_Edit::WordIndexToWordPlace(int32_t index) const
{
	if (m_pVT->IsValid())
		return m_pVT->WordIndexToWordPlace(index);

	return CPVT_WordPlace();
}

FX_BOOL	CFX_Edit::IsTextFull() const
{
	int32_t nTotalWords = m_pVT->GetTotalWords();
	int32_t nLimitChar = m_pVT->GetLimitChar();
	int32_t nCharArray = m_pVT->GetCharArray();

	return IsTextOverflow() || (nLimitChar>0 && nTotalWords >= nLimitChar)
		|| (nCharArray>0 && nTotalWords >= nCharArray);
}

FX_BOOL	CFX_Edit::IsTextOverflow() const
{
	if (!m_bEnableScroll && !m_bEnableOverflow)
	{
		CPDF_Rect rcPlate = m_pVT->GetPlateRect();
		CPDF_Rect rcContent = m_pVT->GetContentRect();

		if (m_pVT->IsMultiLine() && GetTotalLines() > 1)
		{
			if (FX_EDIT_IsFloatBigger(rcContent.Height(),rcPlate.Height())) return TRUE;
		}

		if (FX_EDIT_IsFloatBigger(rcContent.Width(),rcPlate.Width())) return TRUE;
	}

	return FALSE;
}

CPVT_WordPlace CFX_Edit::GetLineBeginPlace(const CPVT_WordPlace & place) const
{
	return m_pVT->GetLineBeginPlace(place);
}

CPVT_WordPlace CFX_Edit::GetLineEndPlace(const CPVT_WordPlace & place) const
{
	return m_pVT->GetLineEndPlace(place);
}

CPVT_WordPlace CFX_Edit::GetSectionBeginPlace(const CPVT_WordPlace & place) const
{
	return m_pVT->GetSectionBeginPlace(place);
}

CPVT_WordPlace CFX_Edit::GetSectionEndPlace(const CPVT_WordPlace & place) const
{
	return m_pVT->GetSectionEndPlace(place);
}

FX_BOOL	CFX_Edit::CanUndo() const
{
	if (m_bEnableUndo)
	{
		return m_Undo.CanUndo();
	}

	return FALSE;
}

FX_BOOL	CFX_Edit::CanRedo() const
{
	if (m_bEnableUndo)
	{
		return m_Undo.CanRedo();
	}

	return FALSE;
}

FX_BOOL	CFX_Edit::IsModified() const
{
	if (m_bEnableUndo)
	{
		return m_Undo.IsModified();
	}

	return FALSE;
}

void CFX_Edit::EnableRefresh(FX_BOOL bRefresh)
{
	m_bEnableRefresh = bRefresh;
}

void CFX_Edit::EnableUndo(FX_BOOL bUndo)
{
    m_bEnableUndo = bUndo;
}

void CFX_Edit::EnableNotify(FX_BOOL bNotify)
{
    m_bNotify = bNotify;
}

void CFX_Edit::EnableOprNotify(FX_BOOL bNotify)
{
    m_bOprNotify = bNotify;
}

FX_FLOAT CFX_Edit::GetLineTop(const CPVT_WordPlace& place) const
{
	if (IPDF_VariableText_Iterator* pIterator = m_pVT->GetIterator())
	{
		CPVT_WordPlace wpOld = pIterator->GetAt();

		pIterator->SetAt(place);
		CPVT_Line line;
		pIterator->GetLine(line);

		pIterator->SetAt(wpOld);

		return line.ptLine.y + line.fLineAscent;
	}

	return 0.0f;
}

FX_FLOAT CFX_Edit::GetLineBottom(const CPVT_WordPlace& place) const
{
	if (IPDF_VariableText_Iterator* pIterator = m_pVT->GetIterator())
	{
		CPVT_WordPlace wpOld = pIterator->GetAt();

		pIterator->SetAt(place);
		CPVT_Line line;
		pIterator->GetLine(line);

		pIterator->SetAt(wpOld);

		return line.ptLine.y + line.fLineDescent;
	}

	return 0.0f;
}

CPVT_WordPlace CFX_Edit::DoInsertText(const CPVT_WordPlace& place, const FX_WCHAR* text, int32_t charset,
									  const CPVT_SecProps * pSecProps, const CPVT_WordProps * pWordProps)
{
	CPVT_WordPlace wp = place;

	if (m_pVT->IsValid())
	{
		CFX_WideString sText = text;

		for (int32_t i = 0, sz = sText.GetLength(); i < sz; i++)
		{
			FX_WORD word = sText[i];
			switch (word)
			{
			case 0x0D:
				wp = m_pVT->InsertSection(wp,pSecProps,pWordProps);
				if (sText[i+1] == 0x0A)
					i++;
				break;
			case 0x0A:
				wp = m_pVT->InsertSection(wp,pSecProps,pWordProps);
				if (sText[i+1] == 0x0D)
					i++;
				break;
			case 0x09:
				word = 0x20;
			default:
				wp = m_pVT->InsertWord(wp,word,GetCharSetFromUnicode(word, charset),pWordProps);
				break;
			}
		}
	}

	return wp;
}

int32_t CFX_Edit::GetCharSetFromUnicode(FX_WORD word, int32_t nOldCharset)
{
    if (IFX_Edit_FontMap* pFontMap = GetFontMap())
        return pFontMap->CharSetFromUnicode(word, nOldCharset);
    return nOldCharset;
}

void CFX_Edit::BeginGroupUndo(const CFX_WideString& sTitle)
{
	ASSERT(m_pGroupUndoItem == NULL);

	m_pGroupUndoItem = new CFX_Edit_GroupUndoItem(sTitle);
}

void CFX_Edit::EndGroupUndo()
{
	ASSERT(m_pGroupUndoItem != NULL);

	m_pGroupUndoItem->UpdateItems();
	m_Undo.AddItem(m_pGroupUndoItem);
	if (m_bOprNotify && m_pOprNotify)
		m_pOprNotify->OnAddUndo(m_pGroupUndoItem);
	m_pGroupUndoItem = NULL;
}

void CFX_Edit::AddEditUndoItem(CFX_Edit_UndoItem* pEditUndoItem)
{
	if (m_pGroupUndoItem)
		m_pGroupUndoItem->AddUndoItem(pEditUndoItem);
	else
	{
		m_Undo.AddItem(pEditUndoItem);
		if (m_bOprNotify && m_pOprNotify)
			m_pOprNotify->OnAddUndo(pEditUndoItem);
	}
}

void CFX_Edit::AddUndoItem(IFX_Edit_UndoItem* pUndoItem)
{
	m_Undo.AddItem(pUndoItem);
	if (m_bOprNotify && m_pOprNotify)
		m_pOprNotify->OnAddUndo(pUndoItem);
}

