// 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 "core/include/fxcrt/fx_safe_types.h"
#include "core/include/fxcrt/fx_xml.h"
#include "fpdfsdk/include/pdfwindow/PDFWindow.h"
#include "fpdfsdk/include/pdfwindow/PWL_Caret.h"
#include "fpdfsdk/include/pdfwindow/PWL_Edit.h"
#include "fpdfsdk/include/pdfwindow/PWL_EditCtrl.h"
#include "fpdfsdk/include/pdfwindow/PWL_FontMap.h"
#include "fpdfsdk/include/pdfwindow/PWL_ScrollBar.h"
#include "fpdfsdk/include/pdfwindow/PWL_Utils.h"
#include "fpdfsdk/include/pdfwindow/PWL_Wnd.h"

/* ---------------------------- CPWL_Edit ------------------------------ */

CPWL_Edit::CPWL_Edit()
    : m_pFillerNotify(NULL), m_pSpellCheck(NULL), m_bFocus(FALSE) {
  m_pFormFiller = NULL;
}

CPWL_Edit::~CPWL_Edit() {
  ASSERT(m_bFocus == FALSE);
}

CFX_ByteString CPWL_Edit::GetClassName() const {
  return PWL_CLASSNAME_EDIT;
}

void CPWL_Edit::OnDestroy() {}

void CPWL_Edit::SetText(const FX_WCHAR* csText) {
  CFX_WideString swText = csText;

  if (HasFlag(PES_RICH)) {
    CFX_ByteString sValue = CFX_ByteString::FromUnicode(swText);

    if (CXML_Element* pXML =
            CXML_Element::Parse(sValue.c_str(), sValue.GetLength())) {
      int32_t nCount = pXML->CountChildren();
      FX_BOOL bFirst = TRUE;

      swText.Empty();

      for (int32_t i = 0; i < nCount; i++) {
        if (CXML_Element* pSubElement = pXML->GetElement(i)) {
          CFX_ByteString tag = pSubElement->GetTagName();
          if (tag.EqualNoCase("p")) {
            int nChild = pSubElement->CountChildren();
            CFX_WideString swSection;
            for (int32_t j = 0; j < nChild; j++) {
              swSection += pSubElement->GetContent(j);
            }

            if (bFirst)
              bFirst = FALSE;
            else
              swText += FWL_VKEY_Return;
            swText += swSection;
          }
        }
      }

      delete pXML;
    }
  }

  m_pEdit->SetText(swText.c_str());
}

void CPWL_Edit::RePosChildWnd() {
  if (CPWL_ScrollBar* pVSB = GetVScrollBar()) {
    CPDF_Rect rcWindow = m_rcOldWindow;
    CPDF_Rect rcVScroll =
        CPDF_Rect(rcWindow.right, rcWindow.bottom,
                  rcWindow.right + PWL_SCROLLBAR_WIDTH, rcWindow.top);
    pVSB->Move(rcVScroll, TRUE, FALSE);
  }

  if (m_pEditCaret && !HasFlag(PES_TEXTOVERFLOW))
    m_pEditCaret->SetClipRect(CPWL_Utils::InflateRect(
        GetClientRect(), 1.0f));  //+1 for caret beside border

  CPWL_EditCtrl::RePosChildWnd();
}

CPDF_Rect CPWL_Edit::GetClientRect() const {
  CPDF_Rect rcClient = CPWL_Utils::DeflateRect(
      GetWindowRect(), (FX_FLOAT)(GetBorderWidth() + GetInnerBorderWidth()));

  if (CPWL_ScrollBar* pVSB = GetVScrollBar()) {
    if (pVSB->IsVisible()) {
      rcClient.right -= PWL_SCROLLBAR_WIDTH;
    }
  }

  return rcClient;
}

void CPWL_Edit::SetAlignFormatH(PWL_EDIT_ALIGNFORMAT_H nFormat,
                                FX_BOOL bPaint /* = TRUE*/) {
  m_pEdit->SetAlignmentH((int32_t)nFormat, bPaint);
}

void CPWL_Edit::SetAlignFormatV(PWL_EDIT_ALIGNFORMAT_V nFormat,
                                FX_BOOL bPaint /* = TRUE*/) {
  m_pEdit->SetAlignmentV((int32_t)nFormat, bPaint);
}

FX_BOOL CPWL_Edit::CanSelectAll() const {
  return GetSelectWordRange() != m_pEdit->GetWholeWordRange();
}

FX_BOOL CPWL_Edit::CanClear() const {
  return !IsReadOnly() && m_pEdit->IsSelected();
}

FX_BOOL CPWL_Edit::CanCopy() const {
  return !HasFlag(PES_PASSWORD) && !HasFlag(PES_NOREAD) &&
         m_pEdit->IsSelected();
}

FX_BOOL CPWL_Edit::CanCut() const {
  return CanCopy() && !IsReadOnly();
}

FX_BOOL CPWL_Edit::CanPaste() const {
  if (IsReadOnly())
    return FALSE;

  CFX_WideString swClipboard;
  if (IFX_SystemHandler* pSH = GetSystemHandler())
    swClipboard = pSH->GetClipboardText(GetAttachedHWnd());

  return !swClipboard.IsEmpty();
}

void CPWL_Edit::CopyText() {
  if (!CanCopy())
    return;

  CFX_WideString str = m_pEdit->GetSelText();

  if (IFX_SystemHandler* pSH = GetSystemHandler())
    pSH->SetClipboardText(GetAttachedHWnd(), str);
}

void CPWL_Edit::PasteText() {
  if (!CanPaste())
    return;

  CFX_WideString swClipboard;
  if (IFX_SystemHandler* pSH = GetSystemHandler())
    swClipboard = pSH->GetClipboardText(GetAttachedHWnd());

  if (m_pFillerNotify) {
    FX_BOOL bRC = TRUE;
    FX_BOOL bExit = FALSE;
    CFX_WideString strChangeEx;
    int nSelStart = 0;
    int nSelEnd = 0;
    GetSel(nSelStart, nSelEnd);
    m_pFillerNotify->OnBeforeKeyStroke(GetAttachedData(), swClipboard,
                                       strChangeEx, nSelStart, nSelEnd, TRUE,
                                       bRC, bExit, 0);
    if (!bRC)
      return;
    if (bExit)
      return;
  }

  if (swClipboard.GetLength() > 0) {
    Clear();
    InsertText(swClipboard.c_str());
  }
}

void CPWL_Edit::CutText() {
  if (!CanCut())
    return;

  CFX_WideString str = m_pEdit->GetSelText();

  if (IFX_SystemHandler* pSH = GetSystemHandler())
    pSH->SetClipboardText(GetAttachedHWnd(), str);

  m_pEdit->Clear();
}

void CPWL_Edit::OnCreated() {
  CPWL_EditCtrl::OnCreated();

  if (CPWL_ScrollBar* pScroll = GetVScrollBar()) {
    pScroll->RemoveFlag(PWS_AUTOTRANSPARENT);
    pScroll->SetTransparency(255);
  }

  SetParamByFlag();

  m_rcOldWindow = GetWindowRect();

  m_pEdit->SetOprNotify(this);
  m_pEdit->EnableOprNotify(TRUE);
}

void CPWL_Edit::SetParamByFlag() {
  if (HasFlag(PES_RIGHT)) {
    m_pEdit->SetAlignmentH(2, FALSE);
  } else if (HasFlag(PES_MIDDLE)) {
    m_pEdit->SetAlignmentH(1, FALSE);
  } else {
    m_pEdit->SetAlignmentH(0, FALSE);
  }

  if (HasFlag(PES_BOTTOM)) {
    m_pEdit->SetAlignmentV(2, FALSE);
  } else if (HasFlag(PES_CENTER)) {
    m_pEdit->SetAlignmentV(1, FALSE);
  } else {
    m_pEdit->SetAlignmentV(0, FALSE);
  }

  if (HasFlag(PES_PASSWORD)) {
    m_pEdit->SetPasswordChar('*', FALSE);
  }

  m_pEdit->SetMultiLine(HasFlag(PES_MULTILINE), FALSE);
  m_pEdit->SetAutoReturn(HasFlag(PES_AUTORETURN), FALSE);
  m_pEdit->SetAutoFontSize(HasFlag(PWS_AUTOFONTSIZE), FALSE);
  m_pEdit->SetAutoScroll(HasFlag(PES_AUTOSCROLL), FALSE);
  m_pEdit->EnableUndo(HasFlag(PES_UNDO));

  if (HasFlag(PES_TEXTOVERFLOW)) {
    SetClipRect(CPDF_Rect(0.0f, 0.0f, 0.0f, 0.0f));
    m_pEdit->SetTextOverflow(TRUE, FALSE);
  } else {
    if (m_pEditCaret) {
      m_pEditCaret->SetClipRect(CPWL_Utils::InflateRect(
          GetClientRect(), 1.0f));  //+1 for caret beside border
    }
  }

  if (HasFlag(PES_SPELLCHECK)) {
    m_pSpellCheck = GetCreationParam().pSpellCheck;
  }
}

void CPWL_Edit::GetThisAppearanceStream(CFX_ByteTextBuf& sAppStream) {
  CPWL_Wnd::GetThisAppearanceStream(sAppStream);

  CPDF_Rect rcClient = GetClientRect();
  CFX_ByteTextBuf sLine;

  int32_t nCharArray = m_pEdit->GetCharArray();

  if (nCharArray > 0) {
    switch (GetBorderStyle()) {
      case PBS_SOLID: {
        sLine << "q\n" << GetBorderWidth() << " w\n"
              << CPWL_Utils::GetColorAppStream(GetBorderColor(), FALSE)
              << " 2 J 0 j\n";

        for (int32_t i = 1; i < nCharArray; i++) {
          sLine << rcClient.left +
                       ((rcClient.right - rcClient.left) / nCharArray) * i
                << " " << rcClient.bottom << " m\n"
                << rcClient.left +
                       ((rcClient.right - rcClient.left) / nCharArray) * i
                << " " << rcClient.top << " l S\n";
        }

        sLine << "Q\n";
      } break;
      case PBS_DASH: {
        sLine << "q\n" << GetBorderWidth() << " w\n"
              << CPWL_Utils::GetColorAppStream(GetBorderColor(), FALSE)
              << " 2 J 0 j\n"
              << "[" << GetBorderDash().nDash << " " << GetBorderDash().nGap
              << "] " << GetBorderDash().nPhase << " d\n";

        for (int32_t i = 1; i < nCharArray; i++) {
          sLine << rcClient.left +
                       ((rcClient.right - rcClient.left) / nCharArray) * i
                << " " << rcClient.bottom << " m\n"
                << rcClient.left +
                       ((rcClient.right - rcClient.left) / nCharArray) * i
                << " " << rcClient.top << " l S\n";
        }

        sLine << "Q\n";
      } break;
    }
  }

  sAppStream << sLine;

  CFX_ByteTextBuf sText;

  CPDF_Point ptOffset = CPDF_Point(0.0f, 0.0f);

  CPVT_WordRange wrWhole = m_pEdit->GetWholeWordRange();
  CPVT_WordRange wrSelect = GetSelectWordRange();
  CPVT_WordRange wrVisible =
      (HasFlag(PES_TEXTOVERFLOW) ? wrWhole : m_pEdit->GetVisibleWordRange());
  CPVT_WordRange wrSelBefore(wrWhole.BeginPos, wrSelect.BeginPos);
  CPVT_WordRange wrSelAfter(wrSelect.EndPos, wrWhole.EndPos);

  CPVT_WordRange wrTemp =
      CPWL_Utils::OverlapWordRange(GetSelectWordRange(), wrVisible);
  CFX_ByteString sEditSel =
      CPWL_Utils::GetEditSelAppStream(m_pEdit, ptOffset, &wrTemp);

  if (sEditSel.GetLength() > 0)
    sText << CPWL_Utils::GetColorAppStream(PWL_DEFAULT_SELBACKCOLOR)
          << sEditSel;

  wrTemp = CPWL_Utils::OverlapWordRange(wrVisible, wrSelBefore);
  CFX_ByteString sEditBefore = CPWL_Utils::GetEditAppStream(
      m_pEdit, ptOffset, &wrTemp, !HasFlag(PES_CHARARRAY),
      m_pEdit->GetPasswordChar());

  if (sEditBefore.GetLength() > 0)
    sText << "BT\n" << CPWL_Utils::GetColorAppStream(GetTextColor())
          << sEditBefore << "ET\n";

  wrTemp = CPWL_Utils::OverlapWordRange(wrVisible, wrSelect);
  CFX_ByteString sEditMid = CPWL_Utils::GetEditAppStream(
      m_pEdit, ptOffset, &wrTemp, !HasFlag(PES_CHARARRAY),
      m_pEdit->GetPasswordChar());

  if (sEditMid.GetLength() > 0)
    sText << "BT\n"
          << CPWL_Utils::GetColorAppStream(CPWL_Color(COLORTYPE_GRAY, 1))
          << sEditMid << "ET\n";

  wrTemp = CPWL_Utils::OverlapWordRange(wrVisible, wrSelAfter);
  CFX_ByteString sEditAfter = CPWL_Utils::GetEditAppStream(
      m_pEdit, ptOffset, &wrTemp, !HasFlag(PES_CHARARRAY),
      m_pEdit->GetPasswordChar());

  if (sEditAfter.GetLength() > 0)
    sText << "BT\n" << CPWL_Utils::GetColorAppStream(GetTextColor())
          << sEditAfter << "ET\n";

  if (HasFlag(PES_SPELLCHECK)) {
    CFX_ByteString sSpellCheck = CPWL_Utils::GetSpellCheckAppStream(
        m_pEdit, m_pSpellCheck, ptOffset, &wrVisible);
    if (sSpellCheck.GetLength() > 0)
      sText << CPWL_Utils::GetColorAppStream(CPWL_Color(COLORTYPE_RGB, 1, 0, 0),
                                             FALSE)
            << sSpellCheck;
  }

  if (sText.GetLength() > 0) {
    CPDF_Rect rcClient = GetClientRect();
    sAppStream << "q\n/Tx BMC\n";

    if (!HasFlag(PES_TEXTOVERFLOW))
      sAppStream << rcClient.left << " " << rcClient.bottom << " "
                 << rcClient.right - rcClient.left << " "
                 << rcClient.top - rcClient.bottom << " re W n\n";

    sAppStream << sText;

    sAppStream << "EMC\nQ\n";
  }
}

void CPWL_Edit::DrawThisAppearance(CFX_RenderDevice* pDevice,
                                   CPDF_Matrix* pUser2Device) {
  CPWL_Wnd::DrawThisAppearance(pDevice, pUser2Device);

  CPDF_Rect rcClient = GetClientRect();
  CFX_ByteTextBuf sLine;

  int32_t nCharArray = m_pEdit->GetCharArray();
  FX_SAFE_INT32 nCharArraySafe = nCharArray;
  nCharArraySafe -= 1;
  nCharArraySafe *= 2;

  if (nCharArray > 0 && nCharArraySafe.IsValid()) {
    switch (GetBorderStyle()) {
      case PBS_SOLID: {
        CFX_GraphStateData gsd;
        gsd.m_LineWidth = (FX_FLOAT)GetBorderWidth();

        CFX_PathData path;
        path.SetPointCount(nCharArraySafe.ValueOrDie());

        for (int32_t i = 0; i < nCharArray - 1; i++) {
          path.SetPoint(
              i * 2,
              rcClient.left +
                  ((rcClient.right - rcClient.left) / nCharArray) * (i + 1),
              rcClient.bottom, FXPT_MOVETO);
          path.SetPoint(
              i * 2 + 1,
              rcClient.left +
                  ((rcClient.right - rcClient.left) / nCharArray) * (i + 1),
              rcClient.top, FXPT_LINETO);
        }
        if (path.GetPointCount() > 0)
          pDevice->DrawPath(
              &path, pUser2Device, &gsd, 0,
              CPWL_Utils::PWLColorToFXColor(GetBorderColor(), 255),
              FXFILL_ALTERNATE);
      } break;
      case PBS_DASH: {
        CFX_GraphStateData gsd;
        gsd.m_LineWidth = (FX_FLOAT)GetBorderWidth();

        gsd.SetDashCount(2);
        gsd.m_DashArray[0] = (FX_FLOAT)GetBorderDash().nDash;
        gsd.m_DashArray[1] = (FX_FLOAT)GetBorderDash().nGap;
        gsd.m_DashPhase = (FX_FLOAT)GetBorderDash().nPhase;

        CFX_PathData path;
        path.SetPointCount(nCharArraySafe.ValueOrDie());

        for (int32_t i = 0; i < nCharArray - 1; i++) {
          path.SetPoint(
              i * 2,
              rcClient.left +
                  ((rcClient.right - rcClient.left) / nCharArray) * (i + 1),
              rcClient.bottom, FXPT_MOVETO);
          path.SetPoint(
              i * 2 + 1,
              rcClient.left +
                  ((rcClient.right - rcClient.left) / nCharArray) * (i + 1),
              rcClient.top, FXPT_LINETO);
        }
        if (path.GetPointCount() > 0)
          pDevice->DrawPath(
              &path, pUser2Device, &gsd, 0,
              CPWL_Utils::PWLColorToFXColor(GetBorderColor(), 255),
              FXFILL_ALTERNATE);
      } break;
    }
  }

  CPDF_Rect rcClip;
  CPVT_WordRange wrRange = m_pEdit->GetVisibleWordRange();
  CPVT_WordRange* pRange = NULL;

  if (!HasFlag(PES_TEXTOVERFLOW)) {
    rcClip = GetClientRect();
    pRange = &wrRange;
  }
  IFX_SystemHandler* pSysHandler = GetSystemHandler();
  IFX_Edit::DrawEdit(
      pDevice, pUser2Device, m_pEdit,
      CPWL_Utils::PWLColorToFXColor(GetTextColor(), GetTransparency()),
      CPWL_Utils::PWLColorToFXColor(GetTextStrokeColor(), GetTransparency()),
      rcClip, CPDF_Point(0.0f, 0.0f), pRange, pSysHandler, m_pFormFiller);

  if (HasFlag(PES_SPELLCHECK)) {
    CPWL_Utils::DrawEditSpellCheck(pDevice, pUser2Device, m_pEdit, rcClip,
                                   CPDF_Point(0.0f, 0.0f), pRange,
                                   GetCreationParam().pSpellCheck);
  }
}

FX_BOOL CPWL_Edit::OnLButtonDown(const CPDF_Point& point, FX_DWORD nFlag) {
  CPWL_Wnd::OnLButtonDown(point, nFlag);

  if (HasFlag(PES_TEXTOVERFLOW) || ClientHitTest(point)) {
    if (m_bMouseDown)
      InvalidateRect();

    m_bMouseDown = TRUE;
    SetCapture();

    m_pEdit->OnMouseDown(point, IsSHIFTpressed(nFlag), IsCTRLpressed(nFlag));
  }

  return TRUE;
}

FX_BOOL CPWL_Edit::OnLButtonDblClk(const CPDF_Point& point, FX_DWORD nFlag) {
  CPWL_Wnd::OnLButtonDblClk(point, nFlag);

  if (HasFlag(PES_TEXTOVERFLOW) || ClientHitTest(point)) {
    m_pEdit->SelectAll();
  }

  return TRUE;
}

#define WM_PWLEDIT_UNDO 0x01
#define WM_PWLEDIT_REDO 0x02
#define WM_PWLEDIT_CUT 0x03
#define WM_PWLEDIT_COPY 0x04
#define WM_PWLEDIT_PASTE 0x05
#define WM_PWLEDIT_DELETE 0x06
#define WM_PWLEDIT_SELECTALL 0x07
#define WM_PWLEDIT_SUGGEST 0x08

FX_BOOL CPWL_Edit::OnRButtonUp(const CPDF_Point& point, FX_DWORD nFlag) {
  if (m_bMouseDown)
    return FALSE;

  CPWL_Wnd::OnRButtonUp(point, nFlag);

  if (!HasFlag(PES_TEXTOVERFLOW) && !ClientHitTest(point))
    return TRUE;

  IFX_SystemHandler* pSH = GetSystemHandler();
  if (!pSH)
    return FALSE;

  SetFocus();

  CPVT_WordRange wrLatin = GetLatinWordsRange(point);
  CFX_WideString swLatin = m_pEdit->GetRangeText(wrLatin);

  FX_HMENU hPopup = pSH->CreatePopupMenu();
  if (!hPopup)
    return FALSE;

  CFX_ByteStringArray sSuggestWords;
  CPDF_Point ptPopup = point;

  if (!IsReadOnly()) {
    if (HasFlag(PES_SPELLCHECK) && !swLatin.IsEmpty()) {
      if (m_pSpellCheck) {
        CFX_ByteString sLatin = CFX_ByteString::FromUnicode(swLatin);

        if (!m_pSpellCheck->CheckWord(sLatin)) {
          m_pSpellCheck->SuggestWords(sLatin, sSuggestWords);

          int32_t nSuggest = sSuggestWords.GetSize();

          for (int32_t nWord = 0; nWord < nSuggest; nWord++) {
            pSH->AppendMenuItem(hPopup, WM_PWLEDIT_SUGGEST + nWord,
                                sSuggestWords[nWord].UTF8Decode());
          }

          if (nSuggest > 0)
            pSH->AppendMenuItem(hPopup, 0, L"");

          ptPopup = GetWordRightBottomPoint(wrLatin.EndPos);
        }
      }
    }
  }

  IPWL_Provider* pProvider = GetProvider();

  if (HasFlag(PES_UNDO)) {
    pSH->AppendMenuItem(
        hPopup, WM_PWLEDIT_UNDO,
        pProvider ? pProvider->LoadPopupMenuString(0) : L"&Undo");
    pSH->AppendMenuItem(
        hPopup, WM_PWLEDIT_REDO,
        pProvider ? pProvider->LoadPopupMenuString(1) : L"&Redo");
    pSH->AppendMenuItem(hPopup, 0, L"");

    if (!m_pEdit->CanUndo())
      pSH->EnableMenuItem(hPopup, WM_PWLEDIT_UNDO, FALSE);
    if (!m_pEdit->CanRedo())
      pSH->EnableMenuItem(hPopup, WM_PWLEDIT_REDO, FALSE);
  }

  pSH->AppendMenuItem(hPopup, WM_PWLEDIT_CUT,
                      pProvider ? pProvider->LoadPopupMenuString(2) : L"Cu&t");
  pSH->AppendMenuItem(hPopup, WM_PWLEDIT_COPY,
                      pProvider ? pProvider->LoadPopupMenuString(3) : L"&Copy");
  pSH->AppendMenuItem(
      hPopup, WM_PWLEDIT_PASTE,
      pProvider ? pProvider->LoadPopupMenuString(4) : L"&Paste");
  pSH->AppendMenuItem(
      hPopup, WM_PWLEDIT_DELETE,
      pProvider ? pProvider->LoadPopupMenuString(5) : L"&Delete");

  CFX_WideString swText = pSH->GetClipboardText(GetAttachedHWnd());
  if (swText.IsEmpty())
    pSH->EnableMenuItem(hPopup, WM_PWLEDIT_PASTE, FALSE);

  if (!m_pEdit->IsSelected()) {
    pSH->EnableMenuItem(hPopup, WM_PWLEDIT_CUT, FALSE);
    pSH->EnableMenuItem(hPopup, WM_PWLEDIT_COPY, FALSE);
    pSH->EnableMenuItem(hPopup, WM_PWLEDIT_DELETE, FALSE);
  }

  if (IsReadOnly()) {
    pSH->EnableMenuItem(hPopup, WM_PWLEDIT_CUT, FALSE);
    pSH->EnableMenuItem(hPopup, WM_PWLEDIT_DELETE, FALSE);
    pSH->EnableMenuItem(hPopup, WM_PWLEDIT_PASTE, FALSE);
  }

  if (HasFlag(PES_PASSWORD)) {
    pSH->EnableMenuItem(hPopup, WM_PWLEDIT_CUT, FALSE);
    pSH->EnableMenuItem(hPopup, WM_PWLEDIT_COPY, FALSE);
  }

  if (HasFlag(PES_NOREAD)) {
    pSH->EnableMenuItem(hPopup, WM_PWLEDIT_CUT, FALSE);
    pSH->EnableMenuItem(hPopup, WM_PWLEDIT_COPY, FALSE);
  }

  pSH->AppendMenuItem(hPopup, 0, L"");
  pSH->AppendMenuItem(
      hPopup, WM_PWLEDIT_SELECTALL,
      pProvider ? pProvider->LoadPopupMenuString(6) : L"&Select All");

  if (m_pEdit->GetTotalWords() == 0) {
    pSH->EnableMenuItem(hPopup, WM_PWLEDIT_SELECTALL, FALSE);
  }

  int32_t x, y;
  PWLtoWnd(ptPopup, x, y);
  pSH->ClientToScreen(GetAttachedHWnd(), x, y);
  pSH->SetCursor(FXCT_ARROW);
  int32_t nCmd = pSH->TrackPopupMenu(hPopup, x, y, GetAttachedHWnd());

  switch (nCmd) {
    case WM_PWLEDIT_UNDO:
      Undo();
      break;
    case WM_PWLEDIT_REDO:
      Redo();
      break;
    case WM_PWLEDIT_CUT:
      CutText();
      break;
    case WM_PWLEDIT_COPY:
      CopyText();
      break;
    case WM_PWLEDIT_PASTE:
      PasteText();
      break;
    case WM_PWLEDIT_DELETE:
      Clear();
      break;
    case WM_PWLEDIT_SELECTALL:
      SelectAll();
      break;
    case WM_PWLEDIT_SUGGEST + 0:
      SetSel(m_pEdit->WordPlaceToWordIndex(wrLatin.BeginPos),
             m_pEdit->WordPlaceToWordIndex(wrLatin.EndPos));
      ReplaceSel(sSuggestWords[0].UTF8Decode().c_str());
      break;
    case WM_PWLEDIT_SUGGEST + 1:
      SetSel(m_pEdit->WordPlaceToWordIndex(wrLatin.BeginPos),
             m_pEdit->WordPlaceToWordIndex(wrLatin.EndPos));
      ReplaceSel(sSuggestWords[1].UTF8Decode().c_str());
      break;
    case WM_PWLEDIT_SUGGEST + 2:
      SetSel(m_pEdit->WordPlaceToWordIndex(wrLatin.BeginPos),
             m_pEdit->WordPlaceToWordIndex(wrLatin.EndPos));
      ReplaceSel(sSuggestWords[2].UTF8Decode().c_str());
      break;
    case WM_PWLEDIT_SUGGEST + 3:
      SetSel(m_pEdit->WordPlaceToWordIndex(wrLatin.BeginPos),
             m_pEdit->WordPlaceToWordIndex(wrLatin.EndPos));
      ReplaceSel(sSuggestWords[3].UTF8Decode().c_str());
      break;
    case WM_PWLEDIT_SUGGEST + 4:
      SetSel(m_pEdit->WordPlaceToWordIndex(wrLatin.BeginPos),
             m_pEdit->WordPlaceToWordIndex(wrLatin.EndPos));
      ReplaceSel(sSuggestWords[4].UTF8Decode().c_str());
      break;
    default:
      break;
  }

  pSH->DestroyMenu(hPopup);

  return TRUE;
}

void CPWL_Edit::OnSetFocus() {
  SetEditCaret(TRUE);

  if (!IsReadOnly()) {
    if (IPWL_FocusHandler* pFocusHandler = GetFocusHandler())
      pFocusHandler->OnSetFocus(this);
  }

  m_bFocus = TRUE;
}

void CPWL_Edit::OnKillFocus() {
  ShowVScrollBar(FALSE);

  m_pEdit->SelectNone();
  SetCaret(FALSE, CPDF_Point(0.0f, 0.0f), CPDF_Point(0.0f, 0.0f));

  SetCharSet(0);

  if (!IsReadOnly()) {
    if (IPWL_FocusHandler* pFocusHandler = GetFocusHandler())
      pFocusHandler->OnKillFocus(this);
  }

  m_bFocus = FALSE;
}

void CPWL_Edit::SetHorzScale(int32_t nHorzScale, FX_BOOL bPaint /* = TRUE*/) {
  m_pEdit->SetHorzScale(nHorzScale, bPaint);
}

void CPWL_Edit::SetCharSpace(FX_FLOAT fCharSpace, FX_BOOL bPaint /* = TRUE*/) {
  m_pEdit->SetCharSpace(fCharSpace, bPaint);
}

void CPWL_Edit::SetLineLeading(FX_FLOAT fLineLeading,
                               FX_BOOL bPaint /* = TRUE*/) {
  m_pEdit->SetLineLeading(fLineLeading, bPaint);
}

CFX_ByteString CPWL_Edit::GetSelectAppearanceStream(
    const CPDF_Point& ptOffset) const {
  CPVT_WordRange wr = GetSelectWordRange();
  return CPWL_Utils::GetEditSelAppStream(m_pEdit, ptOffset, &wr);
}

CPVT_WordRange CPWL_Edit::GetSelectWordRange() const {
  if (m_pEdit->IsSelected()) {
    int32_t nStart = -1;
    int32_t nEnd = -1;

    m_pEdit->GetSel(nStart, nEnd);

    CPVT_WordPlace wpStart = m_pEdit->WordIndexToWordPlace(nStart);
    CPVT_WordPlace wpEnd = m_pEdit->WordIndexToWordPlace(nEnd);

    return CPVT_WordRange(wpStart, wpEnd);
  }

  return CPVT_WordRange();
}

CFX_ByteString CPWL_Edit::GetTextAppearanceStream(
    const CPDF_Point& ptOffset) const {
  CFX_ByteTextBuf sRet;
  CFX_ByteString sEdit = CPWL_Utils::GetEditAppStream(m_pEdit, ptOffset);

  if (sEdit.GetLength() > 0) {
    sRet << "BT\n" << CPWL_Utils::GetColorAppStream(GetTextColor()) << sEdit
         << "ET\n";
  }

  return sRet.GetByteString();
}

CFX_ByteString CPWL_Edit::GetCaretAppearanceStream(
    const CPDF_Point& ptOffset) const {
  if (m_pEditCaret)
    return m_pEditCaret->GetCaretAppearanceStream(ptOffset);

  return CFX_ByteString();
}

CPDF_Point CPWL_Edit::GetWordRightBottomPoint(const CPVT_WordPlace& wpWord) {
  CPDF_Point pt(0.0f, 0.0f);

  if (IFX_Edit_Iterator* pIterator = m_pEdit->GetIterator()) {
    CPVT_WordPlace wpOld = pIterator->GetAt();
    pIterator->SetAt(wpWord);
    CPVT_Word word;
    if (pIterator->GetWord(word)) {
      pt = CPDF_Point(word.ptWord.x + word.fWidth,
                      word.ptWord.y + word.fDescent);
    }

    pIterator->SetAt(wpOld);
  }

  return pt;
}

FX_BOOL CPWL_Edit::IsTextFull() const {
  return m_pEdit->IsTextFull();
}

FX_FLOAT CPWL_Edit::GetCharArrayAutoFontSize(CPDF_Font* pFont,
                                             const CPDF_Rect& rcPlate,
                                             int32_t nCharArray) {
  if (pFont && !pFont->IsStandardFont()) {
    FX_RECT rcBBox;
    pFont->GetFontBBox(rcBBox);

    CPDF_Rect rcCell = rcPlate;
    FX_FLOAT xdiv = rcCell.Width() / nCharArray * 1000.0f / rcBBox.Width();
    FX_FLOAT ydiv = -rcCell.Height() * 1000.0f / rcBBox.Height();

    return xdiv < ydiv ? xdiv : ydiv;
  }

  return 0.0f;
}

void CPWL_Edit::SetCharArray(int32_t nCharArray) {
  if (HasFlag(PES_CHARARRAY) && nCharArray > 0) {
    m_pEdit->SetCharArray(nCharArray);
    m_pEdit->SetTextOverflow(TRUE);

    if (HasFlag(PWS_AUTOFONTSIZE)) {
      if (IFX_Edit_FontMap* pFontMap = GetFontMap()) {
        FX_FLOAT fFontSize = GetCharArrayAutoFontSize(
            pFontMap->GetPDFFont(0), GetClientRect(), nCharArray);
        if (fFontSize > 0.0f) {
          m_pEdit->SetAutoFontSize(FALSE);
          m_pEdit->SetFontSize(fFontSize);
        }
      }
    }
  }
}

void CPWL_Edit::SetLimitChar(int32_t nLimitChar) {
  m_pEdit->SetLimitChar(nLimitChar);
}

void CPWL_Edit::ReplaceSel(const FX_WCHAR* csText) {
  m_pEdit->Clear();
  m_pEdit->InsertText(csText);
}

CPDF_Rect CPWL_Edit::GetFocusRect() const {
  return CPDF_Rect();
}

void CPWL_Edit::ShowVScrollBar(FX_BOOL bShow) {
  if (CPWL_ScrollBar* pScroll = GetVScrollBar()) {
    if (bShow) {
      if (!pScroll->IsVisible()) {
        pScroll->SetVisible(TRUE);
        CPDF_Rect rcWindow = GetWindowRect();
        m_rcOldWindow = rcWindow;
        rcWindow.right += PWL_SCROLLBAR_WIDTH;
        Move(rcWindow, TRUE, TRUE);
      }
    } else {
      if (pScroll->IsVisible()) {
        pScroll->SetVisible(FALSE);
        Move(m_rcOldWindow, TRUE, TRUE);
      }
    }
  }
}

FX_BOOL CPWL_Edit::IsVScrollBarVisible() const {
  if (CPWL_ScrollBar* pScroll = GetVScrollBar()) {
    return pScroll->IsVisible();
  }

  return FALSE;
}

void CPWL_Edit::EnableSpellCheck(FX_BOOL bEnabled) {
  if (bEnabled)
    AddFlag(PES_SPELLCHECK);
  else
    RemoveFlag(PES_SPELLCHECK);
}

FX_BOOL CPWL_Edit::OnKeyDown(FX_WORD nChar, FX_DWORD nFlag) {
  if (m_bMouseDown)
    return TRUE;

  if (nChar == FWL_VKEY_Delete) {
    if (m_pFillerNotify) {
      FX_BOOL bRC = TRUE;
      FX_BOOL bExit = FALSE;
      CFX_WideString strChange;
      CFX_WideString strChangeEx;

      int nSelStart = 0;
      int nSelEnd = 0;
      GetSel(nSelStart, nSelEnd);

      if (nSelStart == nSelEnd)
        nSelEnd = nSelStart + 1;
      m_pFillerNotify->OnBeforeKeyStroke(GetAttachedData(), strChange,
                                         strChangeEx, nSelStart, nSelEnd, TRUE,
                                         bRC, bExit, nFlag);
      if (!bRC)
        return FALSE;
      if (bExit)
        return FALSE;
    }
  }

  FX_BOOL bRet = CPWL_EditCtrl::OnKeyDown(nChar, nFlag);

  // In case of implementation swallow the OnKeyDown event.
  if (IsProceedtoOnChar(nChar, nFlag))
    return TRUE;

  return bRet;
}

/**
*In case of implementation swallow the OnKeyDown event.
*If the event is swallowed, implementation may do other unexpected things, which
*is not the control means to do.
*/
FX_BOOL CPWL_Edit::IsProceedtoOnChar(FX_WORD nKeyCode, FX_DWORD nFlag) {
  FX_BOOL bCtrl = IsCTRLpressed(nFlag);
  FX_BOOL bAlt = IsALTpressed(nFlag);
  if (bCtrl && !bAlt) {
    // hot keys for edit control.
    switch (nKeyCode) {
      case 'C':
      case 'V':
      case 'X':
      case 'A':
      case 'Z':
        return TRUE;
      default:
        break;
    }
  }
  // control characters.
  switch (nKeyCode) {
    case FWL_VKEY_Escape:
    case FWL_VKEY_Back:
    case FWL_VKEY_Return:
    case FWL_VKEY_Space:
      return TRUE;
    default:
      return FALSE;
  }
}

FX_BOOL CPWL_Edit::OnChar(FX_WORD nChar, FX_DWORD nFlag) {
  if (m_bMouseDown)
    return TRUE;

  FX_BOOL bRC = TRUE;
  FX_BOOL bExit = FALSE;

  if (!IsCTRLpressed(nFlag)) {
    if (m_pFillerNotify) {
      CFX_WideString swChange;

      int nSelStart = 0;
      int nSelEnd = 0;
      GetSel(nSelStart, nSelEnd);

      switch (nChar) {
        case FWL_VKEY_Back:
          if (nSelStart == nSelEnd)
            nSelStart = nSelEnd - 1;
          break;
        case FWL_VKEY_Return:
          break;
        default:
          swChange += nChar;
          break;
      }

      CFX_WideString strChangeEx;
      m_pFillerNotify->OnBeforeKeyStroke(GetAttachedData(), swChange,
                                         strChangeEx, nSelStart, nSelEnd, TRUE,
                                         bRC, bExit, nFlag);
    }
  }

  if (!bRC)
    return TRUE;
  if (bExit)
    return FALSE;

  if (IFX_Edit_FontMap* pFontMap = GetFontMap()) {
    int32_t nOldCharSet = GetCharSet();
    int32_t nNewCharSet = pFontMap->CharSetFromUnicode(nChar, DEFAULT_CHARSET);
    if (nOldCharSet != nNewCharSet) {
      SetCharSet(nNewCharSet);
    }
  }

  return CPWL_EditCtrl::OnChar(nChar, nFlag);
}

FX_BOOL CPWL_Edit::OnMouseWheel(short zDelta,
                                const CPDF_Point& point,
                                FX_DWORD nFlag) {
  if (HasFlag(PES_MULTILINE)) {
    CPDF_Point ptScroll = GetScrollPos();

    if (zDelta > 0) {
      ptScroll.y += GetFontSize();
    } else {
      ptScroll.y -= GetFontSize();
    }
    SetScrollPos(ptScroll);

    return TRUE;
  }

  return FALSE;
}

void CPWL_Edit::OnInsertReturn(const CPVT_WordPlace& place,
                               const CPVT_WordPlace& oldplace) {
  if (HasFlag(PES_SPELLCHECK)) {
    m_pEdit->RefreshWordRange(CombineWordRange(GetLatinWordsRange(oldplace),
                                               GetLatinWordsRange(place)));
  }

  if (m_pEditNotify) {
    m_pEditNotify->OnInsertReturn(place, oldplace);
  }
}

void CPWL_Edit::OnBackSpace(const CPVT_WordPlace& place,
                            const CPVT_WordPlace& oldplace) {
  if (HasFlag(PES_SPELLCHECK)) {
    m_pEdit->RefreshWordRange(CombineWordRange(GetLatinWordsRange(oldplace),
                                               GetLatinWordsRange(place)));
  }

  if (m_pEditNotify) {
    m_pEditNotify->OnBackSpace(place, oldplace);
  }
}

void CPWL_Edit::OnDelete(const CPVT_WordPlace& place,
                         const CPVT_WordPlace& oldplace) {
  if (HasFlag(PES_SPELLCHECK)) {
    m_pEdit->RefreshWordRange(CombineWordRange(GetLatinWordsRange(oldplace),
                                               GetLatinWordsRange(place)));
  }

  if (m_pEditNotify) {
    m_pEditNotify->OnDelete(place, oldplace);
  }
}

void CPWL_Edit::OnClear(const CPVT_WordPlace& place,
                        const CPVT_WordPlace& oldplace) {
  if (HasFlag(PES_SPELLCHECK)) {
    m_pEdit->RefreshWordRange(CombineWordRange(GetLatinWordsRange(oldplace),
                                               GetLatinWordsRange(place)));
  }

  if (m_pEditNotify) {
    m_pEditNotify->OnClear(place, oldplace);
  }
}

void CPWL_Edit::OnInsertWord(const CPVT_WordPlace& place,
                             const CPVT_WordPlace& oldplace) {
  if (HasFlag(PES_SPELLCHECK)) {
    m_pEdit->RefreshWordRange(CombineWordRange(GetLatinWordsRange(oldplace),
                                               GetLatinWordsRange(place)));
  }

  if (m_pEditNotify) {
    m_pEditNotify->OnInsertWord(place, oldplace);
  }
}

void CPWL_Edit::OnSetText(const CPVT_WordPlace& place,
                          const CPVT_WordPlace& oldplace) {}

void CPWL_Edit::OnInsertText(const CPVT_WordPlace& place,
                             const CPVT_WordPlace& oldplace) {
  if (HasFlag(PES_SPELLCHECK)) {
    m_pEdit->RefreshWordRange(CombineWordRange(GetLatinWordsRange(oldplace),
                                               GetLatinWordsRange(place)));
  }

  if (m_pEditNotify) {
    m_pEditNotify->OnInsertText(place, oldplace);
  }
}

void CPWL_Edit::OnAddUndo(IFX_Edit_UndoItem* pUndoItem) {
  if (m_pEditNotify) {
    m_pEditNotify->OnAddUndo(this);
  }
}

CPVT_WordRange CPWL_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;
}

CPVT_WordRange CPWL_Edit::GetLatinWordsRange(const CPDF_Point& point) const {
  return GetSameWordsRange(m_pEdit->SearchWordPlace(point), TRUE, FALSE);
}

CPVT_WordRange CPWL_Edit::GetLatinWordsRange(
    const CPVT_WordPlace& place) const {
  return GetSameWordsRange(place, TRUE, FALSE);
}

CPVT_WordRange CPWL_Edit::GetArabicWordsRange(
    const CPVT_WordPlace& place) const {
  return GetSameWordsRange(place, FALSE, TRUE);
}

#define PWL_ISARABICWORD(word) \
  ((word >= 0x0600 && word <= 0x06FF) || (word >= 0xFB50 && word <= 0xFEFC))

CPVT_WordRange CPWL_Edit::GetSameWordsRange(const CPVT_WordPlace& place,
                                            FX_BOOL bLatin,
                                            FX_BOOL bArabic) const {
  CPVT_WordRange range;

  if (IFX_Edit_Iterator* pIterator = m_pEdit->GetIterator()) {
    CPVT_Word wordinfo;
    CPVT_WordPlace wpStart(place), wpEnd(place);
    pIterator->SetAt(place);

    if (bLatin) {
      while (pIterator->NextWord()) {
        if (pIterator->GetWord(wordinfo) &&
            FX_EDIT_ISLATINWORD(wordinfo.Word)) {
          wpEnd = pIterator->GetAt();
          continue;
        } else
          break;
      };
    } else if (bArabic) {
      while (pIterator->NextWord()) {
        if (pIterator->GetWord(wordinfo) && PWL_ISARABICWORD(wordinfo.Word)) {
          wpEnd = pIterator->GetAt();
          continue;
        } else
          break;
      };
    }

    pIterator->SetAt(place);

    if (bLatin) {
      do {
        if (pIterator->GetWord(wordinfo) &&
            FX_EDIT_ISLATINWORD(wordinfo.Word)) {
          continue;
        } else {
          wpStart = pIterator->GetAt();
          break;
        }
      } while (pIterator->PrevWord());
    } else if (bArabic) {
      do {
        if (pIterator->GetWord(wordinfo) && PWL_ISARABICWORD(wordinfo.Word)) {
          continue;
        } else {
          wpStart = pIterator->GetAt();
          break;
        }
      } while (pIterator->PrevWord());
    }

    range.Set(wpStart, wpEnd);
  }

  return range;
}

void CPWL_Edit::GeneratePageObjects(
    CPDF_PageObjects* pPageObjects,
    const CPDF_Point& ptOffset,
    CFX_ArrayTemplate<CPDF_TextObject*>& ObjArray) {
  IFX_Edit::GeneratePageObjects(
      pPageObjects, m_pEdit, ptOffset, NULL,
      CPWL_Utils::PWLColorToFXColor(GetTextColor(), GetTransparency()),
      ObjArray);
}

void CPWL_Edit::GeneratePageObjects(CPDF_PageObjects* pPageObjects,
                                    const CPDF_Point& ptOffset) {
  CFX_ArrayTemplate<CPDF_TextObject*> ObjArray;
  IFX_Edit::GeneratePageObjects(
      pPageObjects, m_pEdit, ptOffset, NULL,
      CPWL_Utils::PWLColorToFXColor(GetTextColor(), GetTransparency()),
      ObjArray);
}
