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

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);
    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);
    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);
  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) {
  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];
    pFirstItem->SetFirst(TRUE);

    CFX_Edit_UndoItem* pLastItem = m_Items[m_Items.GetSize() - 1];
    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];
    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];
    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);
}

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

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

  m_pGroupUndoItem = new CFX_Edit_GroupUndoItem(sTitle);
}

void CFX_Edit::EndGroupUndo() {
  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);
}
