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

#include "xfa/src/foxitlib.h"
#include "xfa/src/fwl/src/core/include/fwl_threadimp.h"
#include "xfa/src/fwl/src/core/include/fwl_appimp.h"
#include "xfa/src/fwl/src/core/include/fwl_targetimp.h"
#include "xfa/src/fwl/src/core/include/fwl_noteimp.h"
#include "xfa/src/fwl/src/core/include/fwl_widgetimp.h"
#include "xfa/src/fwl/src/core/include/fwl_widgetmgrimp.h"
#include "xfa/src/fwl/src/basewidget/include/fwl_caretimp.h"
#include "xfa/src/fwl/src/basewidget/include/fwl_comboboximp.h"
#include "xfa/src/fwl/src/basewidget/include/fwl_editimp.h"
#include "xfa/src/fwl/src/basewidget/include/fwl_scrollbarimp.h"

// static
IFWL_Edit* IFWL_Edit::Create(const CFWL_WidgetImpProperties& properties,
                             IFWL_Widget* pOuter) {
  IFWL_Edit* pEdit = new IFWL_Edit;
  CFWL_EditImp* pEditImpl = new CFWL_EditImp(properties, pOuter);
  pEdit->SetImpl(pEditImpl);
  pEditImpl->SetInterface(pEdit);
  return pEdit;
}
// static
IFWL_Edit* IFWL_Edit::CreateComboEdit(
    const CFWL_WidgetImpProperties& properties,
    IFWL_Widget* pOuter) {
  IFWL_Edit* pEdit = new IFWL_Edit;
  CFWL_EditImp* pComboEditImpl = new CFWL_ComboEditImp(properties, pOuter);
  pEdit->SetImpl(pComboEditImpl);
  pComboEditImpl->SetInterface(pEdit);
  return pEdit;
}
IFWL_Edit::IFWL_Edit() {}
FWL_ERR IFWL_Edit::SetText(const CFX_WideString& wsText) {
  return static_cast<CFWL_EditImp*>(GetImpl())->SetText(wsText);
}
int32_t IFWL_Edit::GetTextLength() const {
  return static_cast<CFWL_EditImp*>(GetImpl())->GetTextLength();
}
FWL_ERR IFWL_Edit::GetText(CFX_WideString& wsText,
                           int32_t nStart,
                           int32_t nCount) const {
  return static_cast<CFWL_EditImp*>(GetImpl())->GetText(wsText, nStart, nCount);
}
FWL_ERR IFWL_Edit::ClearText() {
  return static_cast<CFWL_EditImp*>(GetImpl())->ClearText();
}
int32_t IFWL_Edit::GetCaretPos() const {
  return static_cast<CFWL_EditImp*>(GetImpl())->GetCaretPos();
}
int32_t IFWL_Edit::SetCaretPos(int32_t nIndex, FX_BOOL bBefore) {
  return static_cast<CFWL_EditImp*>(GetImpl())->SetCaretPos(nIndex, bBefore);
}
FWL_ERR IFWL_Edit::AddSelRange(int32_t nStart, int32_t nCount) {
  return static_cast<CFWL_EditImp*>(GetImpl())->AddSelRange(nStart, nCount);
}
int32_t IFWL_Edit::CountSelRanges() {
  return static_cast<CFWL_EditImp*>(GetImpl())->CountSelRanges();
}
int32_t IFWL_Edit::GetSelRange(int32_t nIndex, int32_t& nStart) {
  return static_cast<CFWL_EditImp*>(GetImpl())->GetSelRange(nIndex, nStart);
}
FWL_ERR IFWL_Edit::ClearSelections() {
  return static_cast<CFWL_EditImp*>(GetImpl())->ClearSelections();
}
int32_t IFWL_Edit::GetLimit() {
  return static_cast<CFWL_EditImp*>(GetImpl())->GetLimit();
}
FWL_ERR IFWL_Edit::SetLimit(int32_t nLimit) {
  return static_cast<CFWL_EditImp*>(GetImpl())->SetLimit(nLimit);
}
FWL_ERR IFWL_Edit::SetAliasChar(FX_WCHAR wAlias) {
  return static_cast<CFWL_EditImp*>(GetImpl())->SetAliasChar(wAlias);
}
FWL_ERR IFWL_Edit::SetFormatString(const CFX_WideString& wsFormat) {
  return static_cast<CFWL_EditImp*>(GetImpl())->SetFormatString(wsFormat);
}
FWL_ERR IFWL_Edit::Insert(int32_t nStart,
                          const FX_WCHAR* lpText,
                          int32_t nLen) {
  return static_cast<CFWL_EditImp*>(GetImpl())->Insert(nStart, lpText, nLen);
}
FWL_ERR IFWL_Edit::DeleteSelections() {
  return static_cast<CFWL_EditImp*>(GetImpl())->DeleteSelections();
}
FWL_ERR IFWL_Edit::DeleteRange(int32_t nStart, int32_t nCount) {
  return static_cast<CFWL_EditImp*>(GetImpl())->DeleteRange(nStart, nCount);
}
FWL_ERR IFWL_Edit::ReplaceSelections(const CFX_WideStringC& wsReplace) {
  return static_cast<CFWL_EditImp*>(GetImpl())->ReplaceSelections(wsReplace);
}
FWL_ERR IFWL_Edit::Replace(int32_t nStart,
                           int32_t nLen,
                           const CFX_WideStringC& wsReplace) {
  return static_cast<CFWL_EditImp*>(GetImpl())
      ->Replace(nStart, nLen, wsReplace);
}
FWL_ERR IFWL_Edit::DoClipboard(int32_t iCmd) {
  return static_cast<CFWL_EditImp*>(GetImpl())->DoClipboard(iCmd);
}
FX_BOOL IFWL_Edit::Copy(CFX_WideString& wsCopy) {
  return static_cast<CFWL_EditImp*>(GetImpl())->Copy(wsCopy);
}
FX_BOOL IFWL_Edit::Cut(CFX_WideString& wsCut) {
  return static_cast<CFWL_EditImp*>(GetImpl())->Cut(wsCut);
}
FX_BOOL IFWL_Edit::Paste(const CFX_WideString& wsPaste) {
  return static_cast<CFWL_EditImp*>(GetImpl())->Paste(wsPaste);
}
FX_BOOL IFWL_Edit::Delete() {
  return static_cast<CFWL_EditImp*>(GetImpl())->Delete();
}
FX_BOOL IFWL_Edit::Redo(const CFX_ByteStringC& bsRecord) {
  return static_cast<CFWL_EditImp*>(GetImpl())->Redo(bsRecord);
}
FX_BOOL IFWL_Edit::Undo(const CFX_ByteStringC& bsRecord) {
  return static_cast<CFWL_EditImp*>(GetImpl())->Undo(bsRecord);
}
FX_BOOL IFWL_Edit::Undo() {
  return static_cast<CFWL_EditImp*>(GetImpl())->Undo();
}
FX_BOOL IFWL_Edit::Redo() {
  return static_cast<CFWL_EditImp*>(GetImpl())->Redo();
}
FX_BOOL IFWL_Edit::CanUndo() {
  return static_cast<CFWL_EditImp*>(GetImpl())->CanUndo();
}
FX_BOOL IFWL_Edit::CanRedo() {
  return static_cast<CFWL_EditImp*>(GetImpl())->CanRedo();
}
FWL_ERR IFWL_Edit::SetTabWidth(FX_FLOAT fTabWidth, FX_BOOL bEquidistant) {
  return static_cast<CFWL_EditImp*>(GetImpl())
      ->SetTabWidth(fTabWidth, bEquidistant);
}
FWL_ERR IFWL_Edit::SetOuter(IFWL_Widget* pOuter) {
  return static_cast<CFWL_EditImp*>(GetImpl())->SetOuter(pOuter);
}
FWL_ERR IFWL_Edit::SetNumberRange(int32_t iMin, int32_t iMax) {
  return static_cast<CFWL_EditImp*>(GetImpl())->SetNumberRange(iMin, iMax);
}
FWL_ERR IFWL_Edit::SetBackColor(FX_DWORD dwColor) {
  return static_cast<CFWL_EditImp*>(GetImpl())->SetBackgroundColor(dwColor);
}
FWL_ERR IFWL_Edit::SetFont(const CFX_WideString& wsFont, FX_FLOAT fSize) {
  return static_cast<CFWL_EditImp*>(GetImpl())->SetFont(wsFont, fSize);
}
void IFWL_Edit::SetScrollOffset(FX_FLOAT fScrollOffset) {
  return static_cast<CFWL_EditImp*>(GetImpl())->SetScrollOffset(fScrollOffset);
}
FX_BOOL IFWL_Edit::GetSuggestWords(CFX_PointF pointf,
                                   CFX_ByteStringArray& sSuggest) {
  return static_cast<CFWL_EditImp*>(GetImpl())
      ->GetSuggestWords(pointf, sSuggest);
}
FX_BOOL IFWL_Edit::ReplaceSpellCheckWord(CFX_PointF pointf,
                                         const CFX_ByteStringC& bsReplace) {
  return static_cast<CFWL_EditImp*>(GetImpl())
      ->ReplaceSpellCheckWord(pointf, bsReplace);
}
#define FWL_EDIT_Margin 3
CFWL_EditImp::CFWL_EditImp(const CFWL_WidgetImpProperties& properties,
                           IFWL_Widget* pOuter)
    : CFWL_WidgetImp(properties, pOuter),
      m_fVAlignOffset(0.0f),
      m_fScrollOffsetX(0.0f),
      m_fScrollOffsetY(0.0f),
      m_pEdtEngine(NULL),
      m_bLButtonDown(FALSE),
      m_nSelStart(0),
      m_nLimit(-1),
      m_fSpaceAbove(0),
      m_fSpaceBelow(0),
      m_fFontSize(0),
      m_bSetRange(FALSE),
      m_iMin(-1),
      m_iMax(0xFFFFFFF),
      m_backColor(0),
      m_updateBackColor(FALSE),
      m_iCurRecord(-1),
      m_iMaxRecord(128) {
  m_rtClient.Reset();
  m_rtEngine.Reset();
  m_rtStatic.Reset();
}
CFWL_EditImp::~CFWL_EditImp() {
  if (m_pEdtEngine) {
    m_pEdtEngine->Release();
    m_pEdtEngine = NULL;
  }
  ClearRecord();
}
FWL_ERR CFWL_EditImp::GetClassName(CFX_WideString& wsClass) const {
  wsClass = FWL_CLASS_Edit;
  return FWL_ERR_Succeeded;
}
FX_DWORD CFWL_EditImp::GetClassID() const {
  return FWL_CLASSHASH_Edit;
}
FWL_ERR CFWL_EditImp::Initialize() {
  if (CFWL_WidgetImp::Initialize() != FWL_ERR_Succeeded)
    return FWL_ERR_Indefinite;
  if (!m_pDelegate) {
    m_pDelegate = new CFWL_EditImpDelegate(this);
  }
  InitCaret();
  if (!m_pEdtEngine) {
    InitEngine();
  }
  return FWL_ERR_Succeeded;
}
FWL_ERR CFWL_EditImp::Finalize() {
  if (m_pProperties->m_dwStates & FWL_WGTSTATE_Focused) {
    ShowCaret(FALSE);
  }
  if (m_pHorzScrollBar) {
    m_pHorzScrollBar->Finalize();
  }
  if (m_pVertScrollBar) {
    m_pVertScrollBar->Finalize();
  }
  delete m_pDelegate;
  m_pDelegate = nullptr;
  return CFWL_WidgetImp::Finalize();
}
FWL_ERR CFWL_EditImp::GetWidgetRect(CFX_RectF& rect, FX_BOOL bAutoSize) {
  if (bAutoSize) {
    rect.Set(0, 0, 0, 0);
    if (m_pEdtEngine) {
      int32_t iTextLen = m_pEdtEngine->GetTextLength();
      if (iTextLen > 0) {
        CFX_WideString wsText;
        m_pEdtEngine->GetText(wsText, 0);
        CFX_SizeF sz = CalcTextSize(
            wsText, m_pProperties->m_pThemeProvider,
            m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_MultiLine);
        rect.Set(0, 0, sz.x, sz.y);
      }
    }
    CFWL_WidgetImp::GetWidgetRect(rect, TRUE);
  } else {
    rect = m_pProperties->m_rtWidget;
    if (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_OuterScrollbar) {
      if (IsShowScrollBar(TRUE)) {
        FX_FLOAT* pfWidth = static_cast<FX_FLOAT*>(
            GetThemeCapacity(FWL_WGTCAPACITY_ScrollBarWidth));
        rect.width += *pfWidth;
        rect.width += FWL_EDIT_Margin;
      }
      if (IsShowScrollBar(FALSE)) {
        FX_FLOAT* pfWidth = static_cast<FX_FLOAT*>(
            GetThemeCapacity(FWL_WGTCAPACITY_ScrollBarWidth));
        rect.height += *pfWidth;
        rect.height += FWL_EDIT_Margin;
      }
    }
  }
  return FWL_ERR_Succeeded;
}
FWL_ERR CFWL_EditImp::SetStates(FX_DWORD dwStates, FX_BOOL bSet) {
  if ((m_pProperties->m_dwStates & FWL_WGTSTATE_Invisible) ||
      (m_pProperties->m_dwStates & FWL_WGTSTATE_Disabled)) {
    ShowCaret(FALSE);
  }
  return CFWL_WidgetImp::SetStates(dwStates, bSet);
}
FWL_ERR CFWL_EditImp::SetWidgetRect(const CFX_RectF& rect) {
  return CFWL_WidgetImp::SetWidgetRect(rect);
}
FWL_ERR CFWL_EditImp::Update() {
  if (IsLocked()) {
    return FWL_ERR_Indefinite;
  }
  if (!m_pProperties->m_pThemeProvider) {
    m_pProperties->m_pThemeProvider = GetAvailableTheme();
  }
  Layout();
  if (m_rtClient.IsEmpty()) {
    return FWL_ERR_Indefinite;
  }
  UpdateEditEngine();
  UpdateVAlignment();
  UpdateScroll();
  InitCaret();
  return FWL_ERR_Succeeded;
}
FX_DWORD CFWL_EditImp::HitTest(FX_FLOAT fx, FX_FLOAT fy) {
  if (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_OuterScrollbar) {
    if (IsShowScrollBar(TRUE)) {
      CFX_RectF rect;
      m_pVertScrollBar->GetWidgetRect(rect);
      if (rect.Contains(fx, fy)) {
        return FWL_WGTHITTEST_VScrollBar;
      }
    }
    if (IsShowScrollBar(FALSE)) {
      CFX_RectF rect;
      m_pHorzScrollBar->GetWidgetRect(rect);
      if (rect.Contains(fx, fy)) {
        return FWL_WGTHITTEST_HScrollBar;
      }
    }
  }
  if (m_rtClient.Contains(fx, fy)) {
    return FWL_WGTHITTEST_Edit;
  }
  return FWL_WGTHITTEST_Unknown;
}
#define FX_EDIT_ISLATINWORD(u)                                     \
  (u == 0x2D || (u <= 0x005A && u >= 0x0041) ||                    \
   (u <= 0x007A && u >= 0x0061) || (u <= 0x02AF && u >= 0x00C0) || \
   u == 0x0027)
static void AddSquigglyPath(CFX_Path& PathData,
                            FX_FLOAT fStartX,
                            FX_FLOAT fEndX,
                            FX_FLOAT fY,
                            FX_FLOAT fStep) {
  PathData.MoveTo(fStartX, fY);
  FX_FLOAT fx;
  int32_t i;
  for (i = 1, fx = fStartX + fStep; fx < fEndX; fx += fStep, i++) {
    PathData.LineTo(fx, fY + (i & 1) * fStep);
  }
}
void CFWL_EditImp::AddSpellCheckObj(CFX_Path& PathData,
                                    int32_t nStart,
                                    int32_t nCount,
                                    FX_FLOAT fOffSetX,
                                    FX_FLOAT fOffSetY) {
  FX_FLOAT fStartX = 0.0f;
  FX_FLOAT fEndX = 0.0f;
  FX_FLOAT fY = 0.0f;
  FX_FLOAT fStep = 0.0f;
  IFDE_TxtEdtPage* pPage = m_pEdtEngine->GetPage(0);
  CFX_RectFArray rectArray;
  CFX_RectF rectText;
  const FDE_TXTEDTPARAMS* txtEdtParams = m_pEdtEngine->GetEditParams();
  FX_FLOAT fAsent = (FX_FLOAT)txtEdtParams->pFont->GetAscent() *
                    txtEdtParams->fFontSize / 1000;
  pPage->CalcRangeRectArray(nStart, nCount, rectArray);
  for (int i = 0; i < rectArray.GetSize(); i++) {
    rectText = rectArray.GetAt(i);
    fY = rectText.top + fAsent + fOffSetY;
    fStep = txtEdtParams->fFontSize / 16.0f;
    fStartX = rectText.left + fOffSetX;
    fEndX = fStartX + rectText.Width();
    AddSquigglyPath(PathData, fStartX, fEndX, fY, fStep);
  }
}
int32_t CFWL_EditImp::GetWordAtPoint(CFX_PointF pointf, int32_t& nCount) {
  return 0;
}
FX_BOOL CFWL_EditImp::GetSuggestWords(CFX_PointF pointf,
                                      CFX_ByteStringArray& sSuggest) {
  int32_t nWordCount = 0;
  int32_t nWordStart = GetWordAtPoint(pointf, nWordCount);
  if (nWordCount < 1) {
    return FALSE;
  }
  CFX_WideString wsSpell;
  GetText(wsSpell, nWordStart, nWordCount);
  CFX_ByteString sLatinWord;
  for (int i = 0; i < nWordCount; i++) {
    if (!FX_EDIT_ISLATINWORD(wsSpell[i])) {
      break;
    }
    sLatinWord += (FX_CHAR)wsSpell[i];
  }
  if (sLatinWord.IsEmpty()) {
    return FALSE;
  }
  CFWL_EvtEdtCheckWord checkWordEvent;
  checkWordEvent.m_pSrcTarget = m_pInterface;
  checkWordEvent.bsWord = sLatinWord;
  checkWordEvent.bCheckWord = TRUE;
  DispatchEvent(&checkWordEvent);
  if (checkWordEvent.bCheckWord) {
    return FALSE;
  }
  CFWL_EvtEdtGetSuggestWords suggestWordsEvent;
  suggestWordsEvent.m_pSrcTarget = m_pInterface;
  suggestWordsEvent.bsWord = sLatinWord;
  suggestWordsEvent.bsArraySuggestWords = sSuggest;
  suggestWordsEvent.bSuggestWords = FALSE;
  DispatchEvent(&checkWordEvent);
  return suggestWordsEvent.bSuggestWords;
}
FX_BOOL CFWL_EditImp::ReplaceSpellCheckWord(CFX_PointF pointf,
                                            const CFX_ByteStringC& bsReplace) {
  int32_t nWordCount = 0;
  int32_t nWordStart = GetWordAtPoint(pointf, nWordCount);
  if (nWordCount < 1) {
    return FALSE;
  }
  CFX_WideString wsSpell;
  GetText(wsSpell, nWordStart, nWordCount);
  for (int i = 0; i < nWordCount; i++) {
    if (!FX_EDIT_ISLATINWORD(wsSpell[i])) {
      nWordCount = i;
      break;
    }
  }
  int32_t nDestLen = bsReplace.GetLength();
  CFX_WideString wsDest;
  FX_WCHAR* pBuffer = wsDest.GetBuffer(nDestLen);
  for (int32_t i = 0; i < nDestLen; i++) {
    pBuffer[i] = bsReplace[i];
  }
  wsDest.ReleaseBuffer(nDestLen);
  Replace(nWordStart, nWordCount, wsDest);
  return TRUE;
}
void CFWL_EditImp::DrawSpellCheck(CFX_Graphics* pGraphics,
                                  const CFX_Matrix* pMatrix) {
  pGraphics->SaveGraphState();
  if (pMatrix) {
    pGraphics->ConcatMatrix(const_cast<CFX_Matrix*>(pMatrix));
  }
  FX_ARGB cr = 0xFFFF0000;
  CFX_Color crLine(cr);
  CFWL_EvtEdtCheckWord checkWordEvent;
  checkWordEvent.m_pSrcTarget = m_pInterface;
  CFX_ByteString sLatinWord;
  CFX_Path pathSpell;
  pathSpell.Create();
  int32_t nStart = 0;
  FX_FLOAT fOffSetX = m_rtEngine.left - m_fScrollOffsetX;
  FX_FLOAT fOffSetY = m_rtEngine.top - m_fScrollOffsetY + m_fVAlignOffset;
  CFX_WideString wsSpell;
  this->GetText(wsSpell);
  int32_t nContentLen = wsSpell.GetLength();
  for (int i = 0; i < nContentLen; i++) {
    if (FX_EDIT_ISLATINWORD(wsSpell[i])) {
      if (sLatinWord.IsEmpty()) {
        nStart = i;
      }
      sLatinWord += (FX_CHAR)wsSpell[i];
    } else {
      checkWordEvent.bsWord = sLatinWord;
      checkWordEvent.bCheckWord = TRUE;
      DispatchEvent(&checkWordEvent);
      if (!sLatinWord.IsEmpty() && !checkWordEvent.bCheckWord) {
        AddSpellCheckObj(pathSpell, nStart, sLatinWord.GetLength(), fOffSetX,
                         fOffSetY);
      }
      sLatinWord.Empty();
    }
  }
  checkWordEvent.bsWord = sLatinWord;
  checkWordEvent.bCheckWord = TRUE;
  DispatchEvent(&checkWordEvent);
  if (!sLatinWord.IsEmpty() && !checkWordEvent.bCheckWord) {
    AddSpellCheckObj(pathSpell, nStart, sLatinWord.GetLength(), fOffSetX,
                     fOffSetY);
  }
  if (!pathSpell.IsEmpty()) {
    CFX_RectF rtClip = m_rtEngine;
    CFX_Matrix mt;
    mt.Set(1, 0, 0, 1, fOffSetX, fOffSetY);
    if (pMatrix) {
      pMatrix->TransformRect(rtClip);
      mt.Concat(*pMatrix);
    }
    pGraphics->SetClipRect(rtClip);
    pGraphics->SetStrokeColor(&crLine);
    pGraphics->SetLineWidth(0);
    pGraphics->StrokePath(&pathSpell, NULL);
  }
  pGraphics->RestoreGraphState();
}
FWL_ERR CFWL_EditImp::DrawWidget(CFX_Graphics* pGraphics,
                                 const CFX_Matrix* pMatrix) {
  if (!pGraphics)
    return FWL_ERR_Indefinite;
  if (!m_pProperties->m_pThemeProvider)
    return FWL_ERR_Indefinite;
  if (m_rtClient.IsEmpty()) {
    return FWL_ERR_Indefinite;
  }
  IFWL_ThemeProvider* pTheme = m_pProperties->m_pThemeProvider;
  if (!m_pWidgetMgr->IsFormDisabled()) {
    DrawTextBk(pGraphics, pTheme, pMatrix);
  }
  if (m_pEdtEngine) {
    DrawContent(pGraphics, pTheme, pMatrix);
  }
  if ((m_pProperties->m_dwStates & FWL_WGTSTATE_Focused) &&
      !(m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_ReadOnly)) {
    DrawSpellCheck(pGraphics, pMatrix);
  }
  if (HasBorder()) {
    DrawBorder(pGraphics, FWL_PART_EDT_Border, pTheme, pMatrix);
  }
  if (HasEdge()) {
    DrawEdge(pGraphics, FWL_PART_EDT_Edge, pTheme, pMatrix);
  }
  return FWL_ERR_Succeeded;
}
FWL_ERR CFWL_EditImp::SetThemeProvider(IFWL_ThemeProvider* pThemeProvider) {
  if (!pThemeProvider)
    return FWL_ERR_Indefinite;
  if (m_pHorzScrollBar) {
    m_pHorzScrollBar->SetThemeProvider(pThemeProvider);
  }
  if (m_pVertScrollBar) {
    m_pVertScrollBar->SetThemeProvider(pThemeProvider);
  }
  if (m_pCaret) {
    m_pCaret->SetThemeProvider(pThemeProvider);
  }
  m_pProperties->m_pThemeProvider = pThemeProvider;
  return FWL_ERR_Succeeded;
}
FWL_ERR CFWL_EditImp::SetText(const CFX_WideString& wsText) {
  m_pEdtEngine->SetText(wsText);
  return FWL_ERR_Succeeded;
}
int32_t CFWL_EditImp::GetTextLength() const {
  if (!m_pEdtEngine)
    return -1;
  return m_pEdtEngine->GetTextLength();
}
FWL_ERR CFWL_EditImp::GetText(CFX_WideString& wsText,
                              int32_t nStart,
                              int32_t nCount) const {
  if (!m_pEdtEngine)
    return FWL_ERR_Succeeded;
  m_pEdtEngine->GetText(wsText, nStart, nCount);
  return FWL_ERR_Succeeded;
}
FWL_ERR CFWL_EditImp::ClearText() {
  if (!m_pEdtEngine)
    return FWL_ERR_Succeeded;
  m_pEdtEngine->ClearText();
  return FWL_ERR_Succeeded;
}
int32_t CFWL_EditImp::GetCaretPos() const {
  if (!m_pEdtEngine)
    return -1;
  return m_pEdtEngine->GetCaretPos();
}
int32_t CFWL_EditImp::SetCaretPos(int32_t nIndex, FX_BOOL bBefore) {
  if (!m_pEdtEngine)
    return -1;
  return m_pEdtEngine->SetCaretPos(nIndex, bBefore);
}
FWL_ERR CFWL_EditImp::AddSelRange(int32_t nStart, int32_t nCount) {
  if (!m_pEdtEngine)
    return FWL_ERR_Succeeded;
  m_pEdtEngine->AddSelRange(nStart, nCount);
  return FWL_ERR_Succeeded;
}
int32_t CFWL_EditImp::CountSelRanges() {
  if (!m_pEdtEngine)
    return 0;
  return m_pEdtEngine->CountSelRanges();
  return FWL_ERR_Succeeded;
}
int32_t CFWL_EditImp::GetSelRange(int32_t nIndex, int32_t& nStart) {
  if (!m_pEdtEngine)
    return -1;
  return m_pEdtEngine->GetSelRange(nIndex, nStart);
}
FWL_ERR CFWL_EditImp::ClearSelections() {
  if (!m_pEdtEngine)
    return FWL_ERR_Succeeded;
  m_pEdtEngine->ClearSelection();
  return FWL_ERR_Succeeded;
}
int32_t CFWL_EditImp::GetLimit() {
  return m_nLimit;
}
FWL_ERR CFWL_EditImp::SetLimit(int32_t nLimit) {
  m_nLimit = nLimit;
  if (!m_pEdtEngine)
    return FWL_ERR_Succeeded;
  m_pEdtEngine->SetLimit(nLimit);
  return FWL_ERR_Succeeded;
}
FWL_ERR CFWL_EditImp::SetAliasChar(FX_WCHAR wAlias) {
  if (!m_pEdtEngine)
    return FWL_ERR_Indefinite;
  m_pEdtEngine->SetAliasChar(wAlias);
  return FWL_ERR_Succeeded;
}
FWL_ERR CFWL_EditImp::SetFormatString(const CFX_WideString& wsFormat) {
  if (!m_pEdtEngine)
    return FWL_ERR_Succeeded;
  m_pEdtEngine->SetFormatBlock(0, wsFormat);
  return FWL_ERR_Succeeded;
}
FWL_ERR CFWL_EditImp::Insert(int32_t nStart,
                             const FX_WCHAR* lpText,
                             int32_t nLen) {
  if (!m_pEdtEngine)
    return FWL_ERR_Succeeded;
  if ((m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_ReadOnly) ||
      (m_pProperties->m_dwStates & FWL_WGTSTATE_Disabled)) {
    return FWL_ERR_Indefinite;
  }
  m_pEdtEngine->Insert(nStart, lpText, nLen);
  return FWL_ERR_Succeeded;
}
FWL_ERR CFWL_EditImp::DeleteSelections() {
  if (!m_pEdtEngine)
    return FWL_ERR_Succeeded;
  int32_t iCount = m_pEdtEngine->CountSelRanges();
  if (iCount > 0) {
    m_pEdtEngine->Delete(-1);
  }
  return FWL_ERR_Succeeded;
}
FWL_ERR CFWL_EditImp::DeleteRange(int32_t nStart, int32_t nCount) {
  if (!m_pEdtEngine)
    return FWL_ERR_Succeeded;
  m_pEdtEngine->DeleteRange(nStart, nCount);
  return FWL_ERR_Succeeded;
}
FWL_ERR CFWL_EditImp::ReplaceSelections(const CFX_WideStringC& wsReplace) {
  if (!m_pEdtEngine)
    return FWL_ERR_Succeeded;
  int32_t iCount = m_pEdtEngine->CountSelRanges();
  for (int i = 0; i < iCount; i++) {
    int32_t nStart;
    int32_t nCount = m_pEdtEngine->GetSelRange(i, nStart);
    m_pEdtEngine->Replace(nStart, nCount, wsReplace);
  }
  return FWL_ERR_Succeeded;
}
FWL_ERR CFWL_EditImp::Replace(int32_t nStart,
                              int32_t nLen,
                              const CFX_WideStringC& wsReplace) {
  if (!m_pEdtEngine)
    return FWL_ERR_Succeeded;
  m_pEdtEngine->Replace(nStart, nLen, wsReplace);
  return FWL_ERR_Succeeded;
}
FWL_ERR CFWL_EditImp::DoClipboard(int32_t iCmd) {
  if (!m_pEdtEngine)
    return FWL_ERR_Succeeded;
  if ((m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_ReadOnly) ||
      (m_pProperties->m_dwStates & FWL_WGTSTATE_Disabled)) {
    return FWL_ERR_Succeeded;
  }
  return FWL_ERR_Indefinite;
}
FX_BOOL CFWL_EditImp::Copy(CFX_WideString& wsCopy) {
  if (!m_pEdtEngine)
    return FALSE;
  int32_t nCount = m_pEdtEngine->CountSelRanges();
  if (nCount == 0) {
    return FALSE;
  }
  wsCopy.Empty();
  CFX_WideString wsTemp;
  int32_t nStart, nLength;
  for (int32_t i = 0; i < nCount; i++) {
    nLength = m_pEdtEngine->GetSelRange(i, nStart);
    m_pEdtEngine->GetText(wsTemp, nStart, nLength);
    wsCopy += wsTemp;
    wsTemp.Empty();
  }
  return TRUE;
}
FX_BOOL CFWL_EditImp::Cut(CFX_WideString& wsCut) {
  if (!m_pEdtEngine)
    return FALSE;
  int32_t nCount = m_pEdtEngine->CountSelRanges();
  if (nCount == 0) {
    return FALSE;
  }
  wsCut.Empty();
  CFX_WideString wsTemp;
  int32_t nStart, nLength;
  for (int32_t i = 0; i < nCount; i++) {
    nLength = m_pEdtEngine->GetSelRange(i, nStart);
    m_pEdtEngine->GetText(wsTemp, nStart, nLength);
    wsCut += wsTemp;
    wsTemp.Empty();
  }
  m_pEdtEngine->Delete(0);
  return TRUE;
}
FX_BOOL CFWL_EditImp::Paste(const CFX_WideString& wsPaste) {
  if (!m_pEdtEngine)
    return FALSE;
  int32_t nCaret = m_pEdtEngine->GetCaretPos();
  int32_t iError =
      m_pEdtEngine->Insert(nCaret, wsPaste.c_str(), wsPaste.GetLength());
  if (iError < 0) {
    ProcessInsertError(iError);
    return FALSE;
  }
  return TRUE;
}
FX_BOOL CFWL_EditImp::Delete() {
  if (!m_pEdtEngine)
    return FALSE;
  int32_t nCount = m_pEdtEngine->CountSelRanges();
  if (nCount < 1) {
    return FALSE;
  }
  m_pEdtEngine->Delete(0);
  return TRUE;
}
FX_BOOL CFWL_EditImp::Redo(const CFX_ByteStringC& bsRecord) {
  if (!m_pEdtEngine)
    return FALSE;
  if (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_NoRedoUndo) {
    return TRUE;
  }
  return m_pEdtEngine->Redo(bsRecord);
}
FX_BOOL CFWL_EditImp::Undo(const CFX_ByteStringC& bsRecord) {
  if (!m_pEdtEngine)
    return FALSE;
  if (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_NoRedoUndo) {
    return TRUE;
  }
  return m_pEdtEngine->Undo(bsRecord);
}
FX_BOOL CFWL_EditImp::Undo() {
  if (!CanUndo()) {
    return FALSE;
  }
  CFX_ByteString bsRecord = m_RecordArr[m_iCurRecord--];
  return Undo(bsRecord);
}
FX_BOOL CFWL_EditImp::Redo() {
  if (!CanRedo()) {
    return FALSE;
  }
  CFX_ByteString bsRecord = m_RecordArr[++m_iCurRecord];
  return Redo(bsRecord);
}
FX_BOOL CFWL_EditImp::CanUndo() {
  return m_iCurRecord >= 0;
}
FX_BOOL CFWL_EditImp::CanRedo() {
  return m_iCurRecord < m_RecordArr.GetSize() - 1;
}
FWL_ERR CFWL_EditImp::SetTabWidth(FX_FLOAT fTabWidth, FX_BOOL bEquidistant) {
  if (!m_pEdtEngine)
    return FWL_ERR_Succeeded;
  FDE_LPTXTEDTPARAMS pParams =
      (FDE_LPTXTEDTPARAMS)m_pEdtEngine->GetEditParams();
  pParams->fTabWidth = fTabWidth;
  pParams->bTabEquidistant = bEquidistant;
  return FWL_ERR_Succeeded;
}
FWL_ERR CFWL_EditImp::SetOuter(IFWL_Widget* pOuter) {
  m_pOuter = pOuter;
  return FWL_ERR_Succeeded;
}
FWL_ERR CFWL_EditImp::SetNumberRange(int32_t iMin, int32_t iMax) {
  m_iMin = iMin;
  m_iMax = iMax;
  m_bSetRange = TRUE;
  return FWL_ERR_Succeeded;
}
void CFWL_EditImp::On_CaretChanged(IFDE_TxtEdtEngine* pEdit,
                                   int32_t nPage,
                                   FX_BOOL bVisible) {
  if (m_rtEngine.IsEmpty()) {
    return;
  }
  if ((m_pProperties->m_dwStates & FWL_WGTSTATE_Focused) == 0) {
    return;
  }
  FX_BOOL bRepaintContent = UpdateOffset();
  UpdateCaret();
  CFX_RectF rtInvalid;
  rtInvalid.Set(0, 0, 0, 0);
  FX_BOOL bRepaintScroll = FALSE;
  if (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_MultiLine) {
    IFWL_ScrollBar* pScroll = UpdateScroll();
    if (pScroll) {
      pScroll->GetWidgetRect(rtInvalid);
      bRepaintScroll = TRUE;
    }
  }
  if (bRepaintContent || bRepaintScroll) {
    if (bRepaintContent) {
      rtInvalid.Union(m_rtEngine);
    }
    Repaint(&rtInvalid);
  }
}
void CFWL_EditImp::On_TextChanged(IFDE_TxtEdtEngine* pEdit,
                                  FDE_TXTEDT_TEXTCHANGE_INFO& ChangeInfo) {
  FX_DWORD dwStyleEx = m_pProperties->m_dwStyleExes;
  if (dwStyleEx & FWL_STYLEEXT_EDT_VAlignMask) {
    UpdateVAlignment();
  }
  IFDE_TxtEdtPage* page = m_pEdtEngine->GetPage(0);
  FX_FLOAT fContentWidth = page->GetContentsBox().width;
  FX_FLOAT fContentHeight = page->GetContentsBox().height;
  CFX_RectF rtTemp;
  GetClientRect(rtTemp);
  FX_BOOL bHSelfAdaption =
      m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_HSelfAdaption;
  FX_BOOL bVSelfAdaption =
      m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_VSelfAdaption;
  FX_BOOL bNeedUpdate = FALSE;
  if (bHSelfAdaption || bVSelfAdaption) {
    CFWL_EvtEdtPreSelfAdaption evt;
    evt.m_pSrcTarget = m_pInterface;
    evt.bHSelfAdaption = TRUE;
    evt.bVSelfAdaption = TRUE;
    FX_FLOAT fWidth;
    FX_FLOAT fHight;
    fWidth = bHSelfAdaption ? fContentWidth : m_pProperties->m_rtWidget.width;
    fHight = bVSelfAdaption ? fContentHeight : m_pProperties->m_rtWidget.height;
    evt.rtAfterChange.Set(0, 0, fWidth, fHight);
    DispatchEvent(&evt);
    if (!evt.bHSelfAdaption) {
      ModifyStylesEx(
          0, FWL_STYLEEXT_EDT_HSelfAdaption | FWL_STYLEEXT_EDT_AutoHScroll);
    }
    if (!evt.bVSelfAdaption) {
      ModifyStylesEx(
          0, FWL_STYLEEXT_EDT_VSelfAdaption | FWL_STYLEEXT_EDT_AutoVScroll);
    }
    bNeedUpdate = (bHSelfAdaption && !evt.bHSelfAdaption) ||
                  (bVSelfAdaption && !evt.bVSelfAdaption);
  }
  FX_FLOAT fContentWidth1 = fContentWidth;
  FX_FLOAT fContentHeight1 = fContentHeight;
  if (bNeedUpdate) {
    UpdateEditParams();
    UpdateEditLayout();
    IFDE_TxtEdtPage* page1 = m_pEdtEngine->GetPage(0);
    fContentWidth1 = page1->GetContentsBox().width;
    fContentHeight1 = page1->GetContentsBox().height;
  }
  if (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_HSelfAdaption) {
    rtTemp.width = std::max(m_pProperties->m_rtWidget.width, fContentWidth1);
    m_pProperties->m_rtWidget.width = fContentWidth1;
  }
  if (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_VSelfAdaption) {
    rtTemp.height = std::max(m_pProperties->m_rtWidget.height, fContentHeight1);
    m_pProperties->m_rtWidget.height = fContentHeight1;
  }
  CFWL_EvtEdtTextChanged event;
  event.m_pSrcTarget = m_pInterface;
  event.nChangeType = ChangeInfo.nChangeType;
  event.wsInsert = ChangeInfo.wsInsert;
  event.wsDelete = ChangeInfo.wsDelete;
  event.wsPrevText = ChangeInfo.wsPrevText;
  DispatchEvent(&event);
  LayoutScrollBar();
  Repaint(&rtTemp);
}
void CFWL_EditImp::On_SelChanged(IFDE_TxtEdtEngine* pEdit) {
  CFX_RectF rtTemp;
  GetClientRect(rtTemp);
  Repaint(&rtTemp);
}
FX_BOOL CFWL_EditImp::On_PageLoad(IFDE_TxtEdtEngine* pEdit,
                                  int32_t nPageIndex,
                                  int32_t nPurpose) {
  IFDE_TxtEdtEngine* pEdtEngine = m_pEdtEngine;
  IFDE_TxtEdtPage* pPage = pEdtEngine->GetPage(nPageIndex);
  if (!pPage)
    return FALSE;
  pPage->LoadPage();
  return TRUE;
}
FX_BOOL CFWL_EditImp::On_PageUnload(IFDE_TxtEdtEngine* pEdit,
                                    int32_t nPageIndex,
                                    int32_t nPurpose) {
  IFDE_TxtEdtEngine* pEdtEngine = m_pEdtEngine;
  IFDE_TxtEdtPage* pPage = pEdtEngine->GetPage(nPageIndex);
  if (!pPage)
    return FALSE;
  pPage->UnloadPage();
  return TRUE;
}

void CFWL_EditImp::On_AddDoRecord(IFDE_TxtEdtEngine* pEdit,
                                  const CFX_ByteStringC& bsDoRecord) {
  AddDoRecord(bsDoRecord);
}

FX_BOOL CFWL_EditImp::On_ValidateField(IFDE_TxtEdtEngine* pEdit,
                                       int32_t nBlockIndex,
                                       int32_t nFieldIndex,
                                       const CFX_WideString& wsFieldText,
                                       int32_t nCharIndex) {
  return TRUE;
}
FX_BOOL CFWL_EditImp::On_ValidateBlock(IFDE_TxtEdtEngine* pEdit,
                                       int32_t nBlockIndex) {
  return TRUE;
}
FX_BOOL CFWL_EditImp::On_GetBlockFormatText(IFDE_TxtEdtEngine* pEdit,
                                            int32_t nBlockIndex,
                                            CFX_WideString& wsBlockText) {
  return FALSE;
}
FX_BOOL CFWL_EditImp::On_Validate(IFDE_TxtEdtEngine* pEdit,
                                  CFX_WideString& wsText) {
  IFWL_Widget* pDst = GetOuter();
  if (!pDst) {
    pDst = m_pInterface;
  }
  CFWL_EvtEdtValidate event;
  event.pDstWidget = pDst;
  event.m_pSrcTarget = m_pInterface;
  event.wsInsert = wsText;
  event.bValidate = TRUE;
  DispatchEvent(&event);
  return event.bValidate;
}
FWL_ERR CFWL_EditImp::SetBackgroundColor(FX_DWORD color) {
  m_backColor = color;
  m_updateBackColor = TRUE;
  return FWL_ERR_Succeeded;
}
FWL_ERR CFWL_EditImp::SetFont(const CFX_WideString& wsFont, FX_FLOAT fSize) {
  m_wsFont = wsFont;
  m_fFontSize = fSize;
  return FWL_ERR_Succeeded;
}
void CFWL_EditImp::SetScrollOffset(FX_FLOAT fScrollOffset) {
  m_fScrollOffsetY = fScrollOffset;
}
void CFWL_EditImp::DrawTextBk(CFX_Graphics* pGraphics,
                              IFWL_ThemeProvider* pTheme,
                              const CFX_Matrix* pMatrix) {
  CFWL_ThemeBackground param;
  param.m_pWidget = m_pInterface;
  param.m_iPart = FWL_PART_EDT_Background;
  param.m_dwData = FWL_PARTDATA_EDT_Background;
  param.m_dwStates = m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_ReadOnly
                         ? FWL_PARTSTATE_EDT_ReadOnly
                         : FWL_PARTSTATE_EDT_Normal;
  FX_DWORD dwStates = (m_pProperties->m_dwStates & FWL_WGTSTATE_Disabled);
  if (dwStates) {
    param.m_dwStates = FWL_PARTSTATE_EDT_Disable;
  }
  param.m_pGraphics = pGraphics;
  param.m_matrix = *pMatrix;
  param.m_rtPart = m_rtClient;
  pTheme->DrawBackground(&param);
  if (!IsShowScrollBar(TRUE) || !IsShowScrollBar(FALSE)) {
    return;
  }
  CFX_RectF rtScorll;
  m_pHorzScrollBar->GetWidgetRect(rtScorll);
  CFX_RectF rtStatic;
  rtStatic.Set(m_rtClient.right() - rtScorll.height,
               m_rtClient.bottom() - rtScorll.height, rtScorll.height,
               rtScorll.height);
  param.m_dwData = FWL_PARTDATA_EDT_StaticBackground;
  param.m_rtPart = rtStatic;
  pTheme->DrawBackground(&param);
}
void CFWL_EditImp::DrawContent(CFX_Graphics* pGraphics,
                               IFWL_ThemeProvider* pTheme,
                               const CFX_Matrix* pMatrix) {
  if (!m_pEdtEngine)
    return;
  IFDE_TxtEdtPage* pPage = m_pEdtEngine->GetPage(0);
  if (!pPage)
    return;
  pGraphics->SaveGraphState();
  if (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_CombText) {
    pGraphics->SaveGraphState();
  }
  CFX_RectF rtClip = m_rtEngine;
  FX_FLOAT fOffSetX = m_rtEngine.left - m_fScrollOffsetX;
  FX_FLOAT fOffSetY = m_rtEngine.top - m_fScrollOffsetY + m_fVAlignOffset;
  CFX_Matrix mt;
  mt.Set(1, 0, 0, 1, fOffSetX, fOffSetY);
  if (pMatrix) {
    pMatrix->TransformRect(rtClip);
    mt.Concat(*pMatrix);
  }
  FX_BOOL bShowSel =
      (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_NoHideSel) ||
      (m_pProperties->m_dwStates & FWL_WGTSTATE_Focused);
  if (bShowSel) {
    IFWL_Widget* pForm =
        m_pWidgetMgr->GetWidget(m_pInterface, FWL_WGTRELATION_SystemForm);
    if (pForm) {
      bShowSel = (pForm->GetStates() & FWL_WGTSTATE_Deactivated) !=
                 FWL_WGTSTATE_Deactivated;
    }
  }
  int32_t nSelCount = m_pEdtEngine->CountSelRanges();
  if (bShowSel && nSelCount > 0) {
    int32_t nPageCharStart = pPage->GetCharStart();
    int32_t nPageCharCount = pPage->GetCharCount();
    int32_t nPageCharEnd = nPageCharStart + nPageCharCount - 1;
    int32_t nCharCount;
    int32_t nCharStart;
    CFX_RectFArray rectArr;
    int32_t i = 0;
    for (i = 0; i < nSelCount; i++) {
      nCharCount = m_pEdtEngine->GetSelRange(i, nCharStart);
      int32_t nCharEnd = nCharStart + nCharCount - 1;
      if (nCharEnd < nPageCharStart || nCharStart > nPageCharEnd) {
        continue;
      }
      int32_t nBgn = std::max(nCharStart, nPageCharStart);
      int32_t nEnd = std::min(nCharEnd, nPageCharEnd);
      pPage->CalcRangeRectArray(nBgn - nPageCharStart, nEnd - nBgn + 1,
                                rectArr);
    }
    int32_t nCount = rectArr.GetSize();
    CFX_Path path;
    path.Create();
    for (i = 0; i < nCount; i++) {
      rectArr[i].left += fOffSetX;
      rectArr[i].top += fOffSetY;
      path.AddRectangle(rectArr[i].left, rectArr[i].top, rectArr[i].width,
                        rectArr[i].height);
    }
    pGraphics->SetClipRect(rtClip);
    CFWL_ThemeBackground param;
    param.m_pGraphics = pGraphics;
    param.m_matrix = *pMatrix;
    param.m_pWidget = m_pInterface;
    param.m_iPart = FWL_PART_EDT_Background;
    param.m_pPath = &path;
    pTheme->DrawBackground(&param);
  }
  CFX_RenderDevice* pRenderDev = pGraphics->GetRenderDevice();
  if (!pRenderDev)
    return;
  IFDE_RenderDevice* pRenderDevice = IFDE_RenderDevice::Create(pRenderDev);
  if (!pRenderDevice)
    return;
  IFDE_RenderContext* pRenderContext = IFDE_RenderContext::Create();
  if (!pRenderContext)
    return;
  pRenderDevice->SetClipRect(rtClip);
  pRenderContext->StartRender(pRenderDevice, pPage, mt);
  pRenderContext->DoRender(NULL);
  pRenderContext->Release();
  pRenderDevice->Release();
  if (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_CombText) {
    pGraphics->RestoreGraphState();
    CFX_Path path;
    path.Create();
    int32_t iLimit = m_nLimit > 0 ? m_nLimit : 1;
    FX_FLOAT fStep = m_rtEngine.width / iLimit;
    FX_FLOAT fLeft = m_rtEngine.left + 1;
    for (int32_t i = 1; i < iLimit; i++) {
      fLeft += fStep;
      path.AddLine(fLeft, m_rtClient.top, fLeft, m_rtClient.bottom());
    }
    CFWL_ThemeBackground param;
    param.m_pGraphics = pGraphics;
    param.m_matrix = *pMatrix;
    param.m_pWidget = m_pInterface;
    param.m_iPart = FWL_PART_EDT_CombTextLine;
    param.m_pPath = &path;
    pTheme->DrawBackground(&param);
  }
  pGraphics->RestoreGraphState();
}
void CFWL_EditImp::UpdateEditEngine() {
  UpdateEditParams();
  UpdateEditLayout();
  if (m_nLimit > -1) {
    m_pEdtEngine->SetLimit(m_nLimit);
  }
}
void CFWL_EditImp::UpdateEditParams() {
  FDE_TXTEDTPARAMS params;
  params.nHorzScale = 100;
  params.fPlateWidth = m_rtEngine.width;
  params.fPlateHeight = m_rtEngine.height;
  if (m_pProperties->m_dwStyles & FWL_WGTSTYLE_RTLLayout) {
    params.dwLayoutStyles |= FDE_TEXTEDITLAYOUT_RTL;
  }
  if (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_VerticalLayout) {
    params.dwLayoutStyles |= FDE_TEXTEDITLAYOUT_DocVertical;
  }
  if (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_VerticalChars) {
    params.dwLayoutStyles |= FDE_TEXTEDITLAYOUT_CharVertial;
  }
  if (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_ReverseLine) {
    params.dwLayoutStyles |= FDE_TEXTEDITLAYOUT_LineReserve;
  }
  if (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_ArabicShapes) {
    params.dwLayoutStyles |= FDE_TEXTEDITLAYOUT_ArabicShapes;
  }
  if (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_ExpandTab) {
    params.dwLayoutStyles |= FDE_TEXTEDITLAYOUT_ExpandTab;
  }
  if (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_CombText) {
    params.dwLayoutStyles |= FDE_TEXTEDITLAYOUT_CombText;
  }
  if (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_LastLineHeight) {
    params.dwLayoutStyles |= FDE_TEXTEDITLAYOUT_LastLineHeight;
  }
  if (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_Validate) {
    params.dwMode |= FDE_TEXTEDITMODE_Validate;
  }
  if (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_Password) {
    params.dwMode |= FDE_TEXTEDITMODE_Password;
  }
  switch (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_HAlignMask) {
    case FWL_STYLEEXT_EDT_HNear: {
      params.dwAlignment |= FDE_TEXTEDITALIGN_Left;
      break;
    }
    case FWL_STYLEEXT_EDT_HCenter: {
      params.dwAlignment |= FDE_TEXTEDITALIGN_Center;
      break;
    }
    case FWL_STYLEEXT_EDT_HFar: {
      params.dwAlignment |= FDE_TEXTEDITALIGN_Right;
      break;
    }
    default: {}
  }
  switch (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_HAlignModeMask) {
    case FWL_STYLEEXT_EDT_Justified: {
      params.dwAlignment |= FDE_TEXTEDITALIGN_Justified;
      break;
    }
    case FWL_STYLEEXT_EDT_Distributed: {
      params.dwAlignment |= FDE_TEXTEDITALIGN_Distributed;
      break;
    }
    default: { params.dwAlignment |= FDE_TEXTEDITALIGN_Normal; }
  }
  if (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_MultiLine) {
    params.dwMode |= FDE_TEXTEDITMODE_MultiLines;
    if ((m_pProperties->m_dwStyles & FWL_WGTSTYLE_HScroll) == 0 &&
        (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_AutoHScroll) == 0) {
      params.dwMode |=
          FDE_TEXTEDITMODE_AutoLineWrap | FDE_TEXTEDITMODE_LimitArea_Horz;
    }
    if ((m_pProperties->m_dwStyles & FWL_WGTSTYLE_VScroll) == 0 &&
        (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_AutoVScroll) == 0) {
      params.dwMode |= FDE_TEXTEDITMODE_LimitArea_Vert;
    } else {
      params.fPlateHeight = 0x00FFFFFF;
    }
  } else {
    if ((m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_AutoHScroll) == 0) {
      params.dwMode |= FDE_TEXTEDITMODE_LimitArea_Horz;
    }
  }
  if ((m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_ReadOnly) ||
      (m_pProperties->m_dwStates & FWL_WGTSTATE_Disabled)) {
    params.dwMode |= FDE_TEXTEDITMODE_ReadOnly;
  }
  FX_FLOAT* pFontSize =
      static_cast<FX_FLOAT*>(GetThemeCapacity(FWL_WGTCAPACITY_FontSize));
  if (!pFontSize)
    return;
  m_fFontSize = *pFontSize;
  FX_DWORD* pFontColor =
      static_cast<FX_DWORD*>(GetThemeCapacity(FWL_WGTCAPACITY_TextColor));
  if (!pFontColor)
    return;
  params.dwFontColor = *pFontColor;
  FX_FLOAT* pLineHeight =
      static_cast<FX_FLOAT*>(GetThemeCapacity(FWL_WGTCAPACITY_LineHeight));
  if (!pLineHeight)
    return;
  params.fLineSpace = *pLineHeight;
  IFX_Font* pFont =
      static_cast<IFX_Font*>(GetThemeCapacity(FWL_WGTCAPACITY_Font));
  if (!pFont)
    return;
  params.pFont = pFont;
  params.fFontSize = m_fFontSize;
  params.nLineCount = (int32_t)(params.fPlateHeight / params.fLineSpace);
  if (params.nLineCount <= 0) {
    params.nLineCount = 1;
  }
  params.fTabWidth = params.fFontSize * 1;
  params.bTabEquidistant = TRUE;
  params.wLineBreakChar = L'\n';
  params.nCharRotation = 0;
  params.pEventSink = this;
  m_pEdtEngine->SetEditParams(params);
}
void CFWL_EditImp::UpdateEditLayout() {
  if (m_pEdtEngine->GetTextLength() <= 0) {
    m_pEdtEngine->SetTextByStream(NULL);
  }
  IFDE_TxtEdtPage* pPage = m_pEdtEngine->GetPage(0);
  if (pPage) {
    pPage->UnloadPage();
    pPage = NULL;
  }
  m_pEdtEngine->StartLayout();
  m_pEdtEngine->DoLayout(NULL);
  m_pEdtEngine->EndLayout();
  pPage = m_pEdtEngine->GetPage(0);
  if (pPage) {
    pPage->LoadPage();
  }
}
FX_BOOL CFWL_EditImp::UpdateOffset() {
  CFX_RectF rtCaret;
  m_pEdtEngine->GetCaretRect(rtCaret);
  FX_FLOAT fOffSetX = m_rtEngine.left - m_fScrollOffsetX;
  FX_FLOAT fOffSetY = m_rtEngine.top - m_fScrollOffsetY + m_fVAlignOffset;
  rtCaret.Offset(fOffSetX, fOffSetY);
  const CFX_RectF& rtEidt = m_rtEngine;
  if (rtEidt.Contains(rtCaret)) {
    IFDE_TxtEdtPage* pPage = m_pEdtEngine->GetPage(0);
    if (!pPage)
      return FALSE;
    CFX_RectF rtFDE = pPage->GetContentsBox();
    rtFDE.Offset(fOffSetX, fOffSetY);
    if (rtFDE.right() < rtEidt.right() && m_fScrollOffsetX > 0) {
      m_fScrollOffsetX += rtFDE.right() - rtEidt.right();
      if (m_fScrollOffsetX < 0) {
        m_fScrollOffsetX = 0;
      }
    }
    if (rtFDE.bottom() < rtEidt.bottom() && m_fScrollOffsetY > 0) {
      m_fScrollOffsetY += rtFDE.bottom() - rtEidt.bottom();
      if (m_fScrollOffsetY < 0) {
        m_fScrollOffsetY = 0;
      }
    }
    return FALSE;
  } else {
    FX_FLOAT offsetX = 0.0;
    FX_FLOAT offsetY = 0.0;
    if (rtCaret.left < rtEidt.left) {
      offsetX = rtCaret.left - rtEidt.left;
    }
    if (rtCaret.right() > rtEidt.right()) {
      offsetX = rtCaret.right() - rtEidt.right();
    }
    if (rtCaret.top < rtEidt.top) {
      offsetY = rtCaret.top - rtEidt.top;
    }
    if (rtCaret.bottom() > rtEidt.bottom()) {
      offsetY = rtCaret.bottom() - rtEidt.bottom();
    }
    if (!(m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_HSelfAdaption)) {
      m_fScrollOffsetX += offsetX;
    }
    if (!(m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_VSelfAdaption)) {
      m_fScrollOffsetY += offsetY;
    }
    if (m_fFontSize > m_rtEngine.height) {
      m_fScrollOffsetY = 0;
    }
    return TRUE;
  }
}
FX_BOOL CFWL_EditImp::UpdateOffset(IFWL_ScrollBar* pScrollBar,
                                   FX_FLOAT fPosChanged) {
  if (pScrollBar == m_pHorzScrollBar.get()) {
    m_fScrollOffsetX += fPosChanged;
  } else {
    m_fScrollOffsetY += fPosChanged;
  }
  return TRUE;
}
void CFWL_EditImp::UpdateVAlignment() {
  IFDE_TxtEdtPage* pPage = m_pEdtEngine->GetPage(0);
  if (!pPage)
    return;
  const CFX_RectF& rtFDE = pPage->GetContentsBox();
  FX_FLOAT fOffsetY = 0.0f;
  FX_FLOAT fSpaceAbove = 0.0f;
  FX_FLOAT fSpaceBelow = 0.0f;
  CFX_SizeF* pSpace = static_cast<CFX_SizeF*>(
      GetThemeCapacity(FWL_WGTCAPACITY_SpaceAboveBelow));
  if (pSpace) {
    fSpaceAbove = pSpace->x;
    fSpaceBelow = pSpace->y;
  }
  if (fSpaceAbove < 0.1f) {
    fSpaceAbove = 0;
  }
  if (fSpaceBelow < 0.1f) {
    fSpaceBelow = 0;
  }
  if (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_VCenter) {
    fOffsetY = (m_rtEngine.height - rtFDE.height) / 2;
    if (fOffsetY < (fSpaceAbove + fSpaceBelow) / 2 &&
        fSpaceAbove < fSpaceBelow) {
      return;
    }
    fOffsetY += (fSpaceAbove - fSpaceBelow) / 2;
  } else if (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_VFar) {
    fOffsetY = (m_rtEngine.height - rtFDE.height);
    fOffsetY -= fSpaceBelow;
  } else {
    fOffsetY += fSpaceAbove;
  }
  m_fVAlignOffset = fOffsetY;
  if (m_fVAlignOffset < 0) {
    m_fVAlignOffset = 0;
  }
}
void CFWL_EditImp::UpdateCaret() {
  CFX_RectF rtFDE;
  m_pEdtEngine->GetCaretRect(rtFDE);
  rtFDE.Offset(m_rtEngine.left - m_fScrollOffsetX,
               m_rtEngine.top - m_fScrollOffsetY + m_fVAlignOffset);
  CFX_RectF rtCaret;
  rtCaret.Set(rtFDE.left, rtFDE.top, rtFDE.width, rtFDE.height);
  CFX_RectF temp = rtCaret;
  CFX_RectF rtClient;
  GetClientRect(rtClient);
  rtCaret.Intersect(rtClient);
  if (rtCaret.left > rtClient.right()) {
    FX_FLOAT right = rtCaret.right();
    rtCaret.left = rtClient.right() - 1;
    rtCaret.width = right - rtCaret.left;
  }
  FX_BOOL bIntersect = !rtCaret.IsEmpty();
  FX_BOOL bShow = TRUE;
  FX_BOOL bShowWhole = FALSE;
  if (!(m_pProperties->m_dwStates & FWL_WGTSTATE_Focused) || !bIntersect) {
    bShow = FALSE;
  }
  if (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_HSelfAdaption &&
      temp.right() > m_rtEngine.right()) {
    bShowWhole = TRUE;
  }
  if (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_VSelfAdaption &&
      temp.bottom() > m_rtEngine.bottom()) {
    bShowWhole = TRUE;
  } else {
    bShow = (m_pProperties->m_dwStates & FWL_WGTSTATE_Focused && bIntersect);
  }
  if (bShowWhole) {
    rtCaret = temp;
  }
  ShowCaret(bShow, &rtCaret);
}
IFWL_ScrollBar* CFWL_EditImp::UpdateScroll() {
  FX_BOOL bShowHorz =
      m_pHorzScrollBar &&
      ((m_pHorzScrollBar->GetStates() & FWL_WGTSTATE_Invisible) == 0);
  FX_BOOL bShowVert =
      m_pVertScrollBar &&
      ((m_pVertScrollBar->GetStates() & FWL_WGTSTATE_Invisible) == 0);
  if (!bShowHorz && !bShowVert) {
    return NULL;
  }
  IFDE_TxtEdtPage* pPage = m_pEdtEngine->GetPage(0);
  if (!pPage)
    return NULL;
  const CFX_RectF& rtFDE = pPage->GetContentsBox();
  IFWL_ScrollBar* pRepaint = NULL;
  if (bShowHorz) {
    CFX_RectF rtScroll;
    m_pHorzScrollBar->GetWidgetRect(rtScroll);
    if (rtScroll.width < rtFDE.width) {
      m_pHorzScrollBar->LockUpdate();
      FX_FLOAT fRange = rtFDE.width - rtScroll.width;
      m_pHorzScrollBar->SetRange(0.0f, fRange);
      FX_FLOAT fPos = m_fScrollOffsetX;
      if (fPos < 0.0f) {
        fPos = 0.0f;
      }
      if (fPos > fRange) {
        fPos = fRange;
      }
      m_pHorzScrollBar->SetPos(fPos);
      m_pHorzScrollBar->SetTrackPos(fPos);
      m_pHorzScrollBar->SetPageSize(rtScroll.width);
      m_pHorzScrollBar->SetStepSize(rtScroll.width / 10);
      m_pHorzScrollBar->SetStates(FWL_WGTSTATE_Disabled, FALSE);
      m_pHorzScrollBar->UnlockUpdate();
      m_pHorzScrollBar->Update();
      pRepaint = m_pHorzScrollBar.get();
    } else if ((m_pHorzScrollBar->GetStates() & FWL_WGTSTATE_Disabled) == 0) {
      m_pHorzScrollBar->LockUpdate();
      m_pHorzScrollBar->SetRange(0, -1);
      m_pHorzScrollBar->SetStates(FWL_WGTSTATE_Disabled, TRUE);
      m_pHorzScrollBar->UnlockUpdate();
      m_pHorzScrollBar->Update();
      pRepaint = m_pHorzScrollBar.get();
    }
  }
  if (bShowVert) {
    CFX_RectF rtScroll;
    m_pVertScrollBar->GetWidgetRect(rtScroll);
    if (rtScroll.height < rtFDE.height) {
      m_pVertScrollBar->LockUpdate();
      FX_FLOAT fStep = m_pEdtEngine->GetEditParams()->fLineSpace;
      FX_FLOAT fRange = rtFDE.height - m_rtEngine.height;
      if (fRange < fStep) {
        fRange = fStep;
      }
      m_pVertScrollBar->SetRange(0.0f, fRange);
      FX_FLOAT fPos = m_fScrollOffsetY;
      if (fPos < 0.0f) {
        fPos = 0.0f;
      }
      if (fPos > fRange) {
        fPos = fRange;
      }
      m_pVertScrollBar->SetPos(fPos);
      m_pVertScrollBar->SetTrackPos(fPos);
      m_pVertScrollBar->SetPageSize(rtScroll.height);
      m_pVertScrollBar->SetStepSize(fStep);
      m_pVertScrollBar->SetStates(FWL_WGTSTATE_Disabled, FALSE);
      m_pVertScrollBar->UnlockUpdate();
      m_pVertScrollBar->Update();
      pRepaint = m_pVertScrollBar.get();
    } else if ((m_pVertScrollBar->GetStates() & FWL_WGTSTATE_Disabled) == 0) {
      m_pVertScrollBar->LockUpdate();
      m_pVertScrollBar->SetRange(0, -1);
      m_pVertScrollBar->SetStates(FWL_WGTSTATE_Disabled, TRUE);
      m_pVertScrollBar->UnlockUpdate();
      m_pVertScrollBar->Update();
      pRepaint = m_pVertScrollBar.get();
    }
  }
  return pRepaint;
}
FX_BOOL CFWL_EditImp::IsShowScrollBar(FX_BOOL bVert) {
  FX_BOOL bShow =
      (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_ShowScrollbarFocus)
          ? (m_pProperties->m_dwStates & FWL_WGTSTATE_Focused) ==
                FWL_WGTSTATE_Focused
          : TRUE;
  if (bVert) {
    return bShow && (m_pProperties->m_dwStyles & FWL_WGTSTYLE_VScroll) &&
           (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_MultiLine) &&
           IsContentHeightOverflow();
  }
  return bShow && (m_pProperties->m_dwStyles & FWL_WGTSTYLE_HScroll) &&
         (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_MultiLine);
}
FX_BOOL CFWL_EditImp::IsContentHeightOverflow() {
  if (!m_pEdtEngine)
    return FALSE;
  IFDE_TxtEdtPage* pPage = m_pEdtEngine->GetPage(0);
  if (!pPage)
    return FALSE;
  return pPage->GetContentsBox().height > m_rtEngine.height + 1.0f;
}
int32_t CFWL_EditImp::AddDoRecord(const CFX_ByteStringC& bsDoRecord) {
  int32_t nCount = m_RecordArr.GetSize();
  if (m_iCurRecord == nCount - 1) {
    if (nCount == m_iMaxRecord) {
      m_RecordArr.RemoveAt(0);
      m_iCurRecord--;
    }
  } else {
    for (int32_t i = nCount - 1; i > m_iCurRecord; i--) {
      m_RecordArr.RemoveAt(i);
    }
  }
  m_RecordArr.Add(bsDoRecord);
  return m_iCurRecord = m_RecordArr.GetSize() - 1;
}
void CFWL_EditImp::Layout() {
  GetClientRect(m_rtClient);
  m_rtEngine = m_rtClient;
  FX_FLOAT* pfWidth =
      static_cast<FX_FLOAT*>(GetThemeCapacity(FWL_WGTCAPACITY_ScrollBarWidth));
  if (!pfWidth)
    return;
  FX_FLOAT fWidth = *pfWidth;
  if (!m_pOuter) {
    CFX_RectF* pUIMargin =
        static_cast<CFX_RectF*>(GetThemeCapacity(FWL_WGTCAPACITY_UIMargin));
    if (pUIMargin) {
      m_rtEngine.Deflate(pUIMargin->left, pUIMargin->top, pUIMargin->width,
                         pUIMargin->height);
    }
  } else if (m_pOuter->GetClassID() == FWL_CLASSHASH_DateTimePicker) {
    CFWL_ThemePart part;
    part.m_pWidget = m_pOuter;
    CFX_RectF* pUIMargin =
        static_cast<CFX_RectF*>(m_pOuter->GetThemeProvider()->GetCapacity(
            &part, FWL_WGTCAPACITY_UIMargin));
    if (pUIMargin) {
      m_rtEngine.Deflate(pUIMargin->left, pUIMargin->top, pUIMargin->width,
                         pUIMargin->height);
    }
  }
  FX_BOOL bShowVertScrollbar = IsShowScrollBar(TRUE);
  FX_BOOL bShowHorzScrollbar = IsShowScrollBar(FALSE);
  if (bShowVertScrollbar) {
    InitScrollBar();
    CFX_RectF rtVertScr;
    if (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_OuterScrollbar) {
      rtVertScr.Set(m_rtClient.right() + FWL_EDIT_Margin, m_rtClient.top,
                    fWidth, m_rtClient.height);
    } else {
      rtVertScr.Set(m_rtClient.right() - fWidth, m_rtClient.top, fWidth,
                    m_rtClient.height);
      if (bShowHorzScrollbar) {
        rtVertScr.height -= fWidth;
      }
      m_rtEngine.width -= fWidth;
    }
    m_pVertScrollBar->SetWidgetRect(rtVertScr);
    m_pVertScrollBar->SetStates(FWL_WGTSTATE_Invisible, FALSE);
    m_pVertScrollBar->Update();
  } else if (m_pVertScrollBar) {
    m_pVertScrollBar->SetStates(FWL_WGTSTATE_Invisible, TRUE);
  }
  if (bShowHorzScrollbar) {
    InitScrollBar(FALSE);
    CFX_RectF rtHoriScr;
    if (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_OuterScrollbar) {
      rtHoriScr.Set(m_rtClient.left, m_rtClient.bottom() + FWL_EDIT_Margin,
                    m_rtClient.width, fWidth);
    } else {
      rtHoriScr.Set(m_rtClient.left, m_rtClient.bottom() - fWidth,
                    m_rtClient.width, fWidth);
      if (bShowVertScrollbar) {
        rtHoriScr.width -= fWidth;
      }
      m_rtEngine.height -= fWidth;
    }
    m_pHorzScrollBar->SetWidgetRect(rtHoriScr);
    m_pHorzScrollBar->SetStates(FWL_WGTSTATE_Invisible, FALSE);
    m_pHorzScrollBar->Update();
  } else if (m_pHorzScrollBar) {
    m_pHorzScrollBar->SetStates(FWL_WGTSTATE_Invisible, TRUE);
  }
}
void CFWL_EditImp::LayoutScrollBar() {
  if ((m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_ShowScrollbarFocus) ==
      0) {
    return;
  }
  FX_FLOAT* pfWidth = NULL;
  FX_BOOL bShowVertScrollbar = IsShowScrollBar(TRUE);
  FX_BOOL bShowHorzScrollbar = IsShowScrollBar(FALSE);
  if (bShowVertScrollbar) {
    if (!m_pVertScrollBar) {
      pfWidth = static_cast<FX_FLOAT*>(
          GetThemeCapacity(FWL_WGTCAPACITY_ScrollBarWidth));
      FX_FLOAT fWidth = pfWidth ? *pfWidth : 0;
      InitScrollBar();
      CFX_RectF rtVertScr;
      if (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_OuterScrollbar) {
        rtVertScr.Set(m_rtClient.right() + FWL_EDIT_Margin, m_rtClient.top,
                      fWidth, m_rtClient.height);
      } else {
        rtVertScr.Set(m_rtClient.right() - fWidth, m_rtClient.top, fWidth,
                      m_rtClient.height);
        if (bShowHorzScrollbar) {
          rtVertScr.height -= fWidth;
        }
      }
      m_pVertScrollBar->SetWidgetRect(rtVertScr);
      m_pVertScrollBar->Update();
    }
    m_pVertScrollBar->SetStates(FWL_WGTSTATE_Invisible, FALSE);
  } else if (m_pVertScrollBar) {
    m_pVertScrollBar->SetStates(FWL_WGTSTATE_Invisible, TRUE);
  }
  if (bShowHorzScrollbar) {
    if (!m_pHorzScrollBar) {
      if (!pfWidth) {
        pfWidth = static_cast<FX_FLOAT*>(
            GetThemeCapacity(FWL_WGTCAPACITY_ScrollBarWidth));
      }
      FX_FLOAT fWidth = pfWidth ? *pfWidth : 0;
      InitScrollBar(FALSE);
      CFX_RectF rtHoriScr;
      if (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_OuterScrollbar) {
        rtHoriScr.Set(m_rtClient.left, m_rtClient.bottom() + FWL_EDIT_Margin,
                      m_rtClient.width, fWidth);
      } else {
        rtHoriScr.Set(m_rtClient.left, m_rtClient.bottom() - fWidth,
                      m_rtClient.width, fWidth);
        if (bShowVertScrollbar) {
          rtHoriScr.width -= (fWidth);
        }
      }
      m_pHorzScrollBar->SetWidgetRect(rtHoriScr);
      m_pHorzScrollBar->Update();
    }
    m_pHorzScrollBar->SetStates(FWL_WGTSTATE_Invisible, FALSE);
  } else if (m_pHorzScrollBar) {
    m_pHorzScrollBar->SetStates(FWL_WGTSTATE_Invisible, TRUE);
  }
  if (bShowVertScrollbar || bShowHorzScrollbar) {
    UpdateScroll();
  }
}
void CFWL_EditImp::DeviceToEngine(CFX_PointF& pt) {
  pt.x += -m_rtEngine.left + m_fScrollOffsetX;
  pt.y += -m_rtEngine.top - m_fVAlignOffset + m_fScrollOffsetY;
}
void CFWL_EditImp::InitScrollBar(FX_BOOL bVert) {
  if ((bVert && m_pVertScrollBar) || (!bVert && m_pHorzScrollBar)) {
    return;
  }
  CFWL_WidgetImpProperties prop;
  prop.m_dwStyleExes = bVert ? FWL_STYLEEXT_SCB_Vert : FWL_STYLEEXT_SCB_Horz;
  prop.m_dwStates = FWL_WGTSTATE_Disabled | FWL_WGTSTATE_Invisible;
  prop.m_pParent = m_pInterface;
  prop.m_pThemeProvider = m_pProperties->m_pThemeProvider;
  IFWL_ScrollBar* pScrollBar = IFWL_ScrollBar::Create(prop, m_pInterface);
  pScrollBar->Initialize();
  (bVert ? &m_pVertScrollBar : &m_pHorzScrollBar)->reset(pScrollBar);
}
void CFWL_EditImp::InitEngine() {
  if (m_pEdtEngine) {
    return;
  }
  m_pEdtEngine = IFDE_TxtEdtEngine::Create();
}
extern FX_BOOL FWL_ShowCaret(IFWL_Widget* pWidget,
                             FX_BOOL bVisible,
                             const CFX_RectF* pRtAnchor);
void CFWL_EditImp::ShowCaret(FX_BOOL bVisible, CFX_RectF* pRect) {
  if (m_pCaret) {
    m_pCaret->ShowCaret(bVisible);
    if (bVisible && !pRect->IsEmpty()) {
      m_pCaret->SetWidgetRect(*pRect);
    }
    Repaint(&m_rtEngine);
  } else {
    IFWL_Widget* pOuter = m_pInterface;
    if (bVisible) {
      pRect->Offset(m_pProperties->m_rtWidget.left,
                    m_pProperties->m_rtWidget.top);
    }
    while (pOuter->GetOuter()) {
      pOuter = pOuter->GetOuter();
      if (bVisible) {
        CFX_RectF rtOuter;
        pOuter->GetWidgetRect(rtOuter);
        pRect->Offset(rtOuter.left, rtOuter.top);
      }
    }
    FWL_ShowCaret(pOuter, bVisible, pRect);
  }
}
FX_BOOL CFWL_EditImp::ValidateNumberChar(FX_WCHAR cNum) {
  if (!m_pEdtEngine) {
    return FALSE;
  }
  if (!m_bSetRange) {
    return TRUE;
  }
  CFX_WideString wsOld, wsText;
  m_pEdtEngine->GetText(wsText, 0);
  if (wsText.IsEmpty()) {
    if (cNum == L'0') {
      return FALSE;
    }
    return TRUE;
  }
  int32_t caretPos = m_pEdtEngine->GetCaretPos();
  int32_t iSel = CountSelRanges();
  if (iSel == 0) {
    if (cNum == L'0' && caretPos == 0) {
      return FALSE;
    }
    int32_t nLen = wsText.GetLength();
    CFX_WideString l = wsText.Mid(0, caretPos);
    CFX_WideString r = wsText.Mid(caretPos, nLen - caretPos);
    CFX_WideString wsNew = l + cNum + r;
    if (wsNew.GetInteger() <= m_iMax) {
      return TRUE;
    }
  } else {
    if (wsText.GetInteger() <= m_iMax) {
      return TRUE;
    }
  }
  return FALSE;
}
void CFWL_EditImp::InitCaret() {
  if (!m_pCaret) {
    if ((m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_InnerCaret)) {
      CFWL_WidgetImpProperties prop;
      m_pCaret.reset(IFWL_Caret::Create(prop, m_pInterface));
      m_pCaret->Initialize();
      m_pCaret->SetParent(m_pInterface);
      m_pCaret->SetStates(m_pProperties->m_dwStates);
    }
  } else if ((m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_InnerCaret) ==
             0) {
    m_pCaret.reset();
  }
}
void CFWL_EditImp::ClearRecord() {
  m_iCurRecord = -1;
  m_RecordArr.RemoveAll();
}
void CFWL_EditImp::ProcessInsertError(int32_t iError) {
  switch (iError) {
    case -2: {
      CFWL_EvtEdtTextFull textFullEvent;
      textFullEvent.m_pSrcTarget = m_pInterface;
      DispatchEvent(&textFullEvent);
      break;
    }
    default: {}
  }
}
CFWL_EditImpDelegate::CFWL_EditImpDelegate(CFWL_EditImp* pOwner)
    : m_pOwner(pOwner) {}
int32_t CFWL_EditImpDelegate::OnProcessMessage(CFWL_Message* pMessage) {
  if (!pMessage)
    return 0;
  FX_DWORD dwMsgCode = pMessage->GetClassID();
  int32_t iRet = 1;
  switch (dwMsgCode) {
    case FWL_MSGHASH_Activate: {
      DoActivate(static_cast<CFWL_MsgActivate*>(pMessage));
      break;
    }
    case FWL_MSGHASH_Deactivate: {
      DoDeactivate(static_cast<CFWL_MsgDeactivate*>(pMessage));
      break;
    }
    case FWL_MSGHASH_SetFocus:
    case FWL_MSGHASH_KillFocus: {
      OnFocusChanged(pMessage, dwMsgCode == FWL_MSGHASH_SetFocus);
      break;
    }
    case FWL_MSGHASH_Mouse: {
      CFWL_MsgMouse* pMsg = static_cast<CFWL_MsgMouse*>(pMessage);
      FX_DWORD dwCmd = pMsg->m_dwCmd;
      switch (dwCmd) {
        case FWL_MSGMOUSECMD_LButtonDown: {
          OnLButtonDown(pMsg);
          break;
        }
        case FWL_MSGMOUSECMD_LButtonUp: {
          OnLButtonUp(pMsg);
          break;
        }
        case FWL_MSGMOUSECMD_LButtonDblClk: {
          OnButtonDblClk(pMsg);
          break;
        }
        case FWL_MSGMOUSECMD_MouseMove: {
          OnMouseMove(pMsg);
          break;
        }
        case FWL_MSGMOUSECMD_RButtonDown: {
          DoButtonDown(pMsg);
          break;
        }
        default: {}
      }
      break;
    }
    case FWL_MSGHASH_Key: {
      CFWL_MsgKey* pKey = static_cast<CFWL_MsgKey*>(pMessage);
      FX_DWORD dwCmd = pKey->m_dwCmd;
      if (dwCmd == FWL_MSGKEYCMD_KeyDown) {
        OnKeyDown(pKey);
      } else if (dwCmd == FWL_MSGKEYCMD_Char) {
        OnChar(pKey);
      }
      break;
    }
    default: { iRet = 0; }
  }
  CFWL_WidgetImpDelegate::OnProcessMessage(pMessage);
  return iRet;
}
FWL_ERR CFWL_EditImpDelegate::OnProcessEvent(CFWL_Event* pEvent) {
  if (!pEvent)
    return FWL_ERR_Indefinite;
  FX_DWORD dwHashCode = pEvent->GetClassID();
  if (dwHashCode != FWL_EVTHASH_Scroll) {
    return FWL_ERR_Succeeded;
  }
  IFWL_Widget* pSrcTarget = pEvent->m_pSrcTarget;
  if ((pSrcTarget == m_pOwner->m_pVertScrollBar.get() &&
       m_pOwner->m_pVertScrollBar) ||
      (pSrcTarget == m_pOwner->m_pHorzScrollBar.get() &&
       m_pOwner->m_pHorzScrollBar)) {
    CFWL_EvtScroll* pScrollEvent = static_cast<CFWL_EvtScroll*>(pEvent);
    OnScroll(static_cast<IFWL_ScrollBar*>(pSrcTarget),
             pScrollEvent->m_iScrollCode, pScrollEvent->m_fPos);
  }
  return FWL_ERR_Succeeded;
}
FWL_ERR CFWL_EditImpDelegate::OnDrawWidget(CFX_Graphics* pGraphics,
                                           const CFX_Matrix* pMatrix) {
  return m_pOwner->DrawWidget(pGraphics, pMatrix);
}
void CFWL_EditImpDelegate::DoActivate(CFWL_MsgActivate* pMsg) {
  m_pOwner->m_pProperties->m_dwStates |= ~FWL_WGTSTATE_Deactivated;
  m_pOwner->Repaint(&m_pOwner->m_rtClient);
}
void CFWL_EditImpDelegate::DoDeactivate(CFWL_MsgDeactivate* pMsg) {
  m_pOwner->m_pProperties->m_dwStates &= FWL_WGTSTATE_Deactivated;
  m_pOwner->Repaint(&m_pOwner->m_rtClient);
}
void CFWL_EditImpDelegate::DoButtonDown(CFWL_MsgMouse* pMsg) {
  if ((m_pOwner->m_pProperties->m_dwStates & FWL_WGTSTATE_Focused) == 0) {
    m_pOwner->SetFocus(TRUE);
  }
  if (!m_pOwner->m_pEdtEngine) {
    m_pOwner->UpdateEditEngine();
  }
  IFDE_TxtEdtPage* pPage = m_pOwner->m_pEdtEngine->GetPage(0);
  if (!pPage)
    return;
  CFX_PointF pt;
  pt.Set(pMsg->m_fx, pMsg->m_fy);
  m_pOwner->DeviceToEngine(pt);
  FX_BOOL bBefore = TRUE;
  int32_t nIndex = pPage->GetCharIndex(pt, bBefore);
  if (nIndex < 0) {
    nIndex = 0;
  }
  m_pOwner->m_pEdtEngine->SetCaretPos(nIndex, bBefore);
}
void CFWL_EditImpDelegate::OnFocusChanged(CFWL_Message* pMsg, FX_BOOL bSet) {
  FX_DWORD dwStyleEx = m_pOwner->GetStylesEx();
  FX_BOOL bRepaint = dwStyleEx & FWL_STYLEEXT_EDT_InnerCaret;
  if (bSet) {
    m_pOwner->m_pProperties->m_dwStates |= FWL_WGTSTATE_Focused;
    if (!m_pOwner->m_pEdtEngine) {
      m_pOwner->UpdateEditEngine();
    }
    m_pOwner->UpdateVAlignment();
    m_pOwner->UpdateOffset();
    m_pOwner->UpdateCaret();
  } else if (m_pOwner->m_pProperties->m_dwStates & FWL_WGTSTATE_Focused) {
    m_pOwner->m_pProperties->m_dwStates &= ~FWL_WGTSTATE_Focused;
    m_pOwner->ShowCaret(FALSE);
    if (m_pOwner->m_pEdtEngine &&
        (dwStyleEx & FWL_STYLEEXT_EDT_NoHideSel) == 0) {
      int32_t nSel = m_pOwner->CountSelRanges();
      if (nSel > 0) {
        m_pOwner->ClearSelections();
        bRepaint = TRUE;
      }
      m_pOwner->SetCaretPos(0);
      m_pOwner->UpdateOffset();
    }
    m_pOwner->ClearRecord();
  }
  m_pOwner->LayoutScrollBar();
  if (bRepaint) {
    CFX_RectF rtInvalidate;
    rtInvalidate.Set(0, 0, m_pOwner->m_pProperties->m_rtWidget.width,
                     m_pOwner->m_pProperties->m_rtWidget.height);
    m_pOwner->Repaint(&rtInvalidate);
  }
}
void CFWL_EditImpDelegate::OnLButtonDown(CFWL_MsgMouse* pMsg) {
  DoCursor(pMsg);
  if (m_pOwner->m_pProperties->m_dwStates & FWL_WGTSTATE_Disabled) {
    return;
  }
  m_pOwner->m_bLButtonDown = TRUE;
  m_pOwner->SetGrab(TRUE);
  DoButtonDown(pMsg);
  int32_t nIndex = m_pOwner->m_pEdtEngine->GetCaretPos();
  FX_BOOL bRepaint = FALSE;
  int32_t iCount = m_pOwner->m_pEdtEngine->CountSelRanges();
  if (iCount > 0) {
    m_pOwner->m_pEdtEngine->ClearSelection();
    bRepaint = TRUE;
  }
  FX_BOOL bShift = pMsg->m_dwFlags & FWL_KEYFLAG_Shift;
  if (bShift && m_pOwner->m_nSelStart != nIndex) {
    int32_t iStart = std::min(m_pOwner->m_nSelStart, nIndex);
    int32_t iEnd = std::max(m_pOwner->m_nSelStart, nIndex);
    m_pOwner->m_pEdtEngine->AddSelRange(iStart, iEnd - iStart);
    bRepaint = TRUE;
  } else {
    m_pOwner->m_nSelStart = nIndex;
  }
  if (bRepaint) {
    m_pOwner->Repaint(&m_pOwner->m_rtEngine);
  }
}
void CFWL_EditImpDelegate::OnLButtonUp(CFWL_MsgMouse* pMsg) {
  DoCursor(pMsg);
  m_pOwner->m_bLButtonDown = FALSE;
  m_pOwner->SetGrab(FALSE);
}
void CFWL_EditImpDelegate::OnButtonDblClk(CFWL_MsgMouse* pMsg) {
  if (!m_pOwner->m_pEdtEngine)
    return;
  DoCursor(pMsg);
  IFDE_TxtEdtPage* pPage = m_pOwner->m_pEdtEngine->GetPage(0);
  if (!pPage)
    return;
  CFX_PointF pt;
  pt.Set(pMsg->m_fx, pMsg->m_fy);
  m_pOwner->DeviceToEngine(pt);
  int32_t nCount = 0;
  int32_t nIndex = pPage->SelectWord(pt, nCount);
  if (nIndex < 0) {
    return;
  }
  m_pOwner->m_pEdtEngine->AddSelRange(nIndex, nCount);
  m_pOwner->m_pEdtEngine->SetCaretPos(nIndex + nCount - 1, FALSE);
  m_pOwner->Repaint(&m_pOwner->m_rtEngine);
}
void CFWL_EditImpDelegate::OnMouseMove(CFWL_MsgMouse* pMsg) {
  if (!m_pOwner->m_pEdtEngine)
    return;
  DoCursor(pMsg);
  if (m_pOwner->m_nSelStart == -1 || !m_pOwner->m_bLButtonDown) {
    return;
  }
  IFDE_TxtEdtPage* pPage = m_pOwner->m_pEdtEngine->GetPage(0);
  if (!pPage)
    return;
  CFX_PointF pt;
  pt.Set(pMsg->m_fx, pMsg->m_fy);
  m_pOwner->DeviceToEngine(pt);
  FX_BOOL bBefore = TRUE;
  int32_t nIndex = pPage->GetCharIndex(pt, bBefore);
  m_pOwner->m_pEdtEngine->SetCaretPos(nIndex, bBefore);
  nIndex = m_pOwner->m_pEdtEngine->GetCaretPos();
  m_pOwner->m_pEdtEngine->ClearSelection();
  if (nIndex != m_pOwner->m_nSelStart) {
    int32_t nLen = m_pOwner->m_pEdtEngine->GetTextLength();
    if (m_pOwner->m_nSelStart >= nLen) {
      m_pOwner->m_nSelStart = nLen;
    }
    m_pOwner->m_pEdtEngine->AddSelRange(
        std::min(m_pOwner->m_nSelStart, nIndex),
        FXSYS_abs(nIndex - m_pOwner->m_nSelStart));
  }
}
void CFWL_EditImpDelegate::OnKeyDown(CFWL_MsgKey* pMsg) {
  if (!m_pOwner->m_pEdtEngine)
    return;
  FDE_TXTEDTMOVECARET MoveCaret = MC_MoveNone;
  FX_BOOL bShift = pMsg->m_dwFlags & FWL_KEYFLAG_Shift;
  FX_BOOL bCtrl = pMsg->m_dwFlags & FWL_KEYFLAG_Ctrl;
  FX_DWORD dwKeyCode = pMsg->m_dwKeyCode;
  switch (dwKeyCode) {
    case FWL_VKEY_Left: {
      MoveCaret = MC_Left;
      break;
    }
    case FWL_VKEY_Right: {
      MoveCaret = MC_Right;
      break;
    }
    case FWL_VKEY_Up: {
      MoveCaret = MC_Up;
      break;
    }
    case FWL_VKEY_Down: {
      MoveCaret = MC_Down;
      break;
    }
    case FWL_VKEY_Home: {
      if (bCtrl) {
        MoveCaret = MC_Home;
      } else {
        MoveCaret = MC_LineStart;
      }
      break;
    }
    case FWL_VKEY_End: {
      if (bCtrl) {
        MoveCaret = MC_End;
      } else {
        MoveCaret = MC_LineEnd;
      }
      break;
    }
    case FWL_VKEY_Insert: {
      break;
    }
    case FWL_VKEY_Delete: {
      if ((m_pOwner->m_pProperties->m_dwStyleExes &
           FWL_STYLEEXT_EDT_ReadOnly) ||
          (m_pOwner->m_pProperties->m_dwStates & FWL_WGTSTATE_Disabled)) {
        break;
      }
      int32_t nCaret = m_pOwner->m_pEdtEngine->GetCaretPos();
#if (_FX_OS_ == _FX_MACOSX_)
      m_pOwner->m_pEdtEngine->Delete(nCaret, TRUE);
#else
      m_pOwner->m_pEdtEngine->Delete(nCaret);
#endif
      break;
    }
    case FWL_VKEY_F2: {
      break;
    }
    case FWL_VKEY_Tab: {
      m_pOwner->DispatchKeyEvent(pMsg);
      break;
    }
    default: {
#if (_FX_OS_ == _FX_MACOSX_)
      if (pMsg->m_dwFlags & FWL_KEYFLAG_Command)
#else
      if (pMsg->m_dwFlags & FWL_KEYFLAG_Ctrl)
#endif
      {
        if (dwKeyCode == 0x43 || dwKeyCode == 0x63) {
          m_pOwner->DoClipboard(1);
          return;
        }
        if (dwKeyCode == 0x58 || dwKeyCode == 0x78) {
          m_pOwner->DoClipboard(2);
          return;
        }
        if (dwKeyCode == 0x56 || dwKeyCode == 0x76) {
          m_pOwner->DoClipboard(3);
          return;
        }
      }
    }
  }
  if (MoveCaret != MC_MoveNone) {
    m_pOwner->m_pEdtEngine->MoveCaretPos(MoveCaret, bShift, bCtrl);
  }
}
void CFWL_EditImpDelegate::OnChar(CFWL_MsgKey* pMsg) {
  if ((m_pOwner->m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_ReadOnly) ||
      (m_pOwner->m_pProperties->m_dwStates & FWL_WGTSTATE_Disabled)) {
    return;
  }
  if (!m_pOwner->m_pEdtEngine)
    return;
  int32_t iError = 0;
  FX_WCHAR c = (FX_WCHAR)pMsg->m_dwKeyCode;
  int32_t nCaret = m_pOwner->m_pEdtEngine->GetCaretPos();
  switch (c) {
    case FWL_VKEY_Back: {
      m_pOwner->m_pEdtEngine->Delete(nCaret, TRUE);
      break;
    }
    case 0x0A: {
      break;
    }
    case FWL_VKEY_Escape: {
      break;
    }
    case FWL_VKEY_Tab: {
      iError = m_pOwner->m_pEdtEngine->Insert(nCaret, L"\t", 1);
      break;
    }
    case FWL_VKEY_Return: {
      if (m_pOwner->m_pProperties->m_dwStyleExes &
          FWL_STYLEEXT_EDT_WantReturn) {
        iError = m_pOwner->m_pEdtEngine->Insert(nCaret, L"\n", 1);
      }
      break;
    }
    default: {
      if (!m_pOwner->m_pWidgetMgr->IsFormDisabled()) {
        if (m_pOwner->m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_Number) {
          if (((pMsg->m_dwKeyCode < FWL_VKEY_0) &&
               (pMsg->m_dwKeyCode != 0x2E && pMsg->m_dwKeyCode != 0x2D)) ||
              pMsg->m_dwKeyCode > FWL_VKEY_9) {
            break;
          }
          if (!m_pOwner->ValidateNumberChar(c)) {
            break;
          }
        }
      }
#if (_FX_OS_ == _FX_MACOSX_)
      if (pMsg->m_dwFlags & FWL_KEYFLAG_Command)
#else
      if (pMsg->m_dwFlags & FWL_KEYFLAG_Ctrl)
#endif
      {
        break;
      }
      iError = m_pOwner->m_pEdtEngine->Insert(nCaret, &c, 1);
      break;
    }
  }
  if (iError < 0) {
    m_pOwner->ProcessInsertError(iError);
  }
}
FX_BOOL CFWL_EditImpDelegate::OnScroll(IFWL_ScrollBar* pScrollBar,
                                       FX_DWORD dwCode,
                                       FX_FLOAT fPos) {
  CFX_SizeF fs;
  pScrollBar->GetRange(fs.x, fs.y);
  FX_FLOAT iCurPos = pScrollBar->GetPos();
  FX_FLOAT fStep = pScrollBar->GetStepSize();
  switch (dwCode) {
    case FWL_SCBCODE_Min: {
      fPos = fs.x;
      break;
    }
    case FWL_SCBCODE_Max: {
      fPos = fs.y;
      break;
    }
    case FWL_SCBCODE_StepBackward: {
      fPos -= fStep;
      if (fPos < fs.x + fStep / 2) {
        fPos = fs.x;
      }
      break;
    }
    case FWL_SCBCODE_StepForward: {
      fPos += fStep;
      if (fPos > fs.y - fStep / 2) {
        fPos = fs.y;
      }
      break;
    }
    case FWL_SCBCODE_PageBackward: {
      fPos -= pScrollBar->GetPageSize();
      if (fPos < fs.x) {
        fPos = fs.x;
      }
      break;
    }
    case FWL_SCBCODE_PageForward: {
      fPos += pScrollBar->GetPageSize();
      if (fPos > fs.y) {
        fPos = fs.y;
      }
      break;
    }
    case FWL_SCBCODE_Pos:
    case FWL_SCBCODE_TrackPos: {
      break;
    }
    case FWL_SCBCODE_EndScroll: {
      return FALSE;
    }
    default: {}
  }
  if (iCurPos != fPos) {
    pScrollBar->SetPos(fPos);
    pScrollBar->SetTrackPos(fPos);
    m_pOwner->UpdateOffset(pScrollBar, fPos - iCurPos);
    if (m_pOwner->m_pEdtEngine) {
      m_pOwner->UpdateCaret();
    }
    CFX_RectF rect;
    m_pOwner->GetWidgetRect(rect);
    CFX_RectF rtInvalidate;
    rtInvalidate.Set(0, 0, rect.width + 2, rect.height + 2);
    m_pOwner->Repaint(&rtInvalidate);
  }
  return TRUE;
}
void CFWL_EditImpDelegate::DoCursor(CFWL_MsgMouse* pMsg) {
}
