// 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 "../../include/pdfwindow/PDFWindow.h"
#include "../../include/pdfwindow/PWL_Caret.h"
#include "../../include/pdfwindow/PWL_Edit.h"
#include "../../include/pdfwindow/PWL_EditCtrl.h"
#include "../../include/pdfwindow/PWL_FontMap.h"
#include "../../include/pdfwindow/PWL_ScrollBar.h"
#include "../../include/pdfwindow/PWL_Utils.h"
#include "../../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);
}
