// 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 "fpdfsdk/include/fxedit/fxet_edit.h"
#include "fpdfsdk/include/fxedit/fxet_stub.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() {
  return m_pVTIterator->NextWord();
}

FX_BOOL CFX_Edit_Iterator::NextLine() {
  return m_pVTIterator->NextLine();
}

FX_BOOL CFX_Edit_Iterator::NextSection() {
  return m_pVTIterator->NextSection();
}

FX_BOOL CFX_Edit_Iterator::PrevWord() {
  return m_pVTIterator->PrevWord();
}

FX_BOOL CFX_Edit_Iterator::PrevLine() {
  return m_pVTIterator->PrevLine();
}

FX_BOOL CFX_Edit_Iterator::PrevSection() {
  return m_pVTIterator->PrevSection();
}

FX_BOOL CFX_Edit_Iterator::GetWord(CPVT_Word& word) const {
  ASSERT(m_pEdit);

  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);

  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);

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

void CFX_Edit_Iterator::SetAt(int32_t nWordIndex) {
  m_pVTIterator->SetAt(nWordIndex);
}

void CFX_Edit_Iterator::SetAt(const CPVT_WordPlace& place) {
  m_pVTIterator->SetAt(place);
}

const CPVT_WordPlace& CFX_Edit_Iterator::GetAt() const {
  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 {
  return m_bVirgin ? m_bModified : 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->AdjustLineHeader(oldplace, TRUE);
                  place = m_pVT->AdjustLineHeader(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);
}
