// 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 "public/fpdf_formfill.h"

#include <memory>
#include <vector>

#include "core/fpdfapi/page/cpdf_page.h"
#include "core/fpdfapi/parser/cpdf_document.h"
#include "core/fpdfapi/render/cpdf_renderoptions.h"
#include "core/fpdfdoc/cpdf_formcontrol.h"
#include "core/fpdfdoc/cpdf_formfield.h"
#include "core/fpdfdoc/cpdf_interform.h"
#include "core/fpdfdoc/cpdf_occontext.h"
#include "core/fxge/cfx_defaultrenderdevice.h"
#include "fpdfsdk/cpdfsdk_formfillenvironment.h"
#include "fpdfsdk/cpdfsdk_interform.h"
#include "fpdfsdk/cpdfsdk_pageview.h"
#include "fpdfsdk/fsdk_actionhandler.h"
#include "fpdfsdk/fsdk_define.h"
#include "public/fpdfview.h"
#include "third_party/base/ptr_util.h"
#include "third_party/base/stl_util.h"

#ifdef PDF_ENABLE_XFA
#include "fpdfsdk/fpdfxfa/cpdfxfa_context.h"
#include "fpdfsdk/fpdfxfa/cpdfxfa_page.h"
#include "xfa/fxfa/cxfa_ffdocview.h"
#include "xfa/fxfa/cxfa_ffpageview.h"
#include "xfa/fxfa/cxfa_ffwidget.h"

static_assert(static_cast<int>(XFA_DocType::PDF) == DOCTYPE_PDF,
              "PDF doctype must match");
static_assert(static_cast<int>(XFA_DocType::Dynamic) == DOCTYPE_DYNAMIC_XFA,
              "Dynamic XFA doctype must match");
static_assert(static_cast<int>(XFA_DocType::Static) == DOCTYPE_STATIC_XFA,
              "Static XFA doctype must match");
#endif  // PDF_ENABLE_XFA

namespace {

CPDFSDK_FormFillEnvironment* HandleToCPDFSDKEnvironment(
    FPDF_FORMHANDLE handle) {
  return static_cast<CPDFSDK_FormFillEnvironment*>(handle);
}

CPDFSDK_InterForm* FormHandleToInterForm(FPDF_FORMHANDLE hHandle) {
  CPDFSDK_FormFillEnvironment* pFormFillEnv =
      HandleToCPDFSDKEnvironment(hHandle);
  return pFormFillEnv ? pFormFillEnv->GetInterForm() : nullptr;
}

CPDFSDK_PageView* FormHandleToPageView(FPDF_FORMHANDLE hHandle,
                                       FPDF_PAGE page) {
  UnderlyingPageType* pPage = UnderlyingFromFPDFPage(page);
  if (!pPage)
    return nullptr;

  CPDFSDK_FormFillEnvironment* pFormFillEnv =
      HandleToCPDFSDKEnvironment(hHandle);
  return pFormFillEnv ? pFormFillEnv->GetPageView(pPage, true) : nullptr;
}

#ifdef PDF_ENABLE_XFA
std::vector<CFX_ByteString>* FromFPDFStringHandle(FPDF_STRINGHANDLE handle) {
  return static_cast<std::vector<CFX_ByteString>*>(handle);
}

FPDF_STRINGHANDLE ToFPDFStringHandle(std::vector<CFX_ByteString>* strings) {
  return static_cast<FPDF_STRINGHANDLE>(strings);
}
#endif  // PDF_ENABLE_XFA

void FFLCommon(FPDF_FORMHANDLE hHandle,
               FPDF_BITMAP bitmap,
               FPDF_RECORDER recorder,
               FPDF_PAGE page,
               int start_x,
               int start_y,
               int size_x,
               int size_y,
               int rotate,
               int flags) {
  if (!hHandle)
    return;

  UnderlyingPageType* pPage = UnderlyingFromFPDFPage(page);
  if (!pPage)
    return;

#ifdef PDF_ENABLE_XFA
  CPDFXFA_Context* pContext = pPage->GetContext();
  if (!pContext)
    return;
  CPDF_Document* pPDFDoc = pContext->GetPDFDoc();
  if (!pPDFDoc)
    return;
  CPDFSDK_FormFillEnvironment* pFormFillEnv =
      HandleToCPDFSDKEnvironment(hHandle);
  if (!pFormFillEnv)
    return;
#endif  // PDF_ENABLE_XFA

  CFX_Matrix matrix =
      pPage->GetDisplayMatrix(start_x, start_y, size_x, size_y, rotate);
  FX_RECT clip(start_x, start_y, start_x + size_x, start_y + size_y);

  auto pDevice = pdfium::MakeUnique<CFX_DefaultRenderDevice>();
#ifdef _SKIA_SUPPORT_
  pDevice->AttachRecorder(static_cast<SkPictureRecorder*>(recorder));
#endif
  CFX_RetainPtr<CFX_DIBitmap> holder(CFXBitmapFromFPDFBitmap(bitmap));
  pDevice->Attach(holder, false, nullptr, false);
  {
    CFX_RenderDevice::StateRestorer restorer(pDevice.get());
    pDevice->SetClip_Rect(clip);

    CPDF_RenderOptions options;
    if (flags & FPDF_LCD_TEXT)
      options.m_Flags |= RENDER_CLEARTYPE;
    else
      options.m_Flags &= ~RENDER_CLEARTYPE;

    // Grayscale output
    if (flags & FPDF_GRAYSCALE)
      options.m_ColorMode = CPDF_RenderOptions::kGray;

    options.m_bDrawAnnots = flags & FPDF_ANNOT;

#ifdef PDF_ENABLE_XFA
    options.m_pOCContext =
        pdfium::MakeRetain<CPDF_OCContext>(pPDFDoc, CPDF_OCContext::View);
    if (CPDFSDK_PageView* pPageView = pFormFillEnv->GetPageView(pPage, true))
      pPageView->PageView_OnDraw(pDevice.get(), &matrix, &options, clip);
#else   // PDF_ENABLE_XFA
    options.m_pOCContext = pdfium::MakeRetain<CPDF_OCContext>(
        pPage->m_pDocument.Get(), CPDF_OCContext::View);
    if (CPDFSDK_PageView* pPageView = FormHandleToPageView(hHandle, pPage))
      pPageView->PageView_OnDraw(pDevice.get(), &matrix, &options);
#endif  // PDF_ENABLE_XFA
  }
#ifdef _SKIA_SUPPORT_PATHS_
  pDevice->Flush(true);
  holder->UnPreMultiply();
#endif
}

}  // namespace

DLLEXPORT int STDCALL FPDFPage_HasFormFieldAtPoint(FPDF_FORMHANDLE hHandle,
                                                   FPDF_PAGE page,
                                                   double page_x,
                                                   double page_y) {
  if (!hHandle)
    return -1;
  CPDF_Page* pPage = CPDFPageFromFPDFPage(page);
  if (pPage) {
    CPDF_InterForm interform(pPage->m_pDocument.Get());
    CPDF_FormControl* pFormCtrl = interform.GetControlAtPoint(
        pPage,
        CFX_PointF(static_cast<float>(page_x), static_cast<float>(page_y)),
        nullptr);
    if (!pFormCtrl)
      return -1;
    CPDF_FormField* pFormField = pFormCtrl->GetField();
    return pFormField ? pFormField->GetFieldType() : -1;
  }

#ifdef PDF_ENABLE_XFA
  CPDFXFA_Page* pXFAPage = UnderlyingFromFPDFPage(page);
  if (!pXFAPage)
    return -1;

  CXFA_FFPageView* pPageView = pXFAPage->GetXFAPageView();
  if (!pPageView)
    return -1;

  CXFA_FFDocView* pDocView = pPageView->GetDocView();
  if (!pDocView)
    return -1;

  CXFA_FFWidgetHandler* pWidgetHandler = pDocView->GetWidgetHandler();
  if (!pWidgetHandler)
    return -1;

  std::unique_ptr<IXFA_WidgetIterator> pWidgetIterator(
      pPageView->CreateWidgetIterator(XFA_TRAVERSEWAY_Form,
                                      XFA_WidgetStatus_Viewable));
  if (!pWidgetIterator)
    return -1;

  CXFA_FFWidget* pXFAAnnot = pWidgetIterator->MoveToNext();
  while (pXFAAnnot) {
    CFX_RectF rcBBox = pXFAAnnot->GetBBox(0);
    CFX_FloatRect rcWidget(rcBBox.left, rcBBox.top, rcBBox.left + rcBBox.width,
                           rcBBox.top + rcBBox.height);
    rcWidget.Inflate(1.0f, 1.0f);
    if (rcWidget.Contains(CFX_PointF(static_cast<float>(page_x),
                                     static_cast<float>(page_y)))) {
      return FPDF_FORMFIELD_XFA;
    }
    pXFAAnnot = pWidgetIterator->MoveToNext();
  }
#endif  // PDF_ENABLE_XFA
  return -1;
}

DLLEXPORT int STDCALL FPDFPage_FormFieldZOrderAtPoint(FPDF_FORMHANDLE hHandle,
                                                      FPDF_PAGE page,
                                                      double page_x,
                                                      double page_y) {
  if (!hHandle)
    return -1;
  CPDF_Page* pPage = CPDFPageFromFPDFPage(page);
  if (!pPage)
    return -1;
  CPDF_InterForm interform(pPage->m_pDocument.Get());
  int z_order = -1;
  (void)interform.GetControlAtPoint(
      pPage, CFX_PointF(static_cast<float>(page_x), static_cast<float>(page_y)),
      &z_order);
  return z_order;
}

DLLEXPORT FPDF_FORMHANDLE STDCALL
FPDFDOC_InitFormFillEnvironment(FPDF_DOCUMENT document,
                                FPDF_FORMFILLINFO* formInfo) {
#ifdef PDF_ENABLE_XFA
  const int kRequiredVersion = 2;
#else   // PDF_ENABLE_XFA
  const int kRequiredVersion = 1;
#endif  // PDF_ENABLE_XFA
  if (!formInfo || formInfo->version != kRequiredVersion)
    return nullptr;

  UnderlyingDocumentType* pDocument = UnderlyingFromFPDFDocument(document);
  if (!pDocument)
    return nullptr;

#ifdef PDF_ENABLE_XFA
  // If the CPDFXFA_Context has a FormFillEnvironment already then we've done
  // this and can just return the old Env. Otherwise, we'll end up setting a new
  // environment into the XFADocument and, that could get weird.
  if (pDocument->GetFormFillEnv())
    return pDocument->GetFormFillEnv();
#endif

  auto pFormFillEnv =
      pdfium::MakeUnique<CPDFSDK_FormFillEnvironment>(pDocument, formInfo);

#ifdef PDF_ENABLE_XFA
  pDocument->SetFormFillEnv(pFormFillEnv.get());
#endif  // PDF_ENABLE_XFA

  return pFormFillEnv.release();  // Caller takes ownership.
}

DLLEXPORT void STDCALL
FPDFDOC_ExitFormFillEnvironment(FPDF_FORMHANDLE hHandle) {
  CPDFSDK_FormFillEnvironment* pFormFillEnv =
      HandleToCPDFSDKEnvironment(hHandle);
  if (!pFormFillEnv)
    return;

#ifdef PDF_ENABLE_XFA
  // Reset the focused annotations and remove the SDK document from the
  // XFA document.
  pFormFillEnv->ClearAllFocusedAnnots();
  // If the document was closed first, it's possible the XFA document
  // is now a nullptr.
  if (pFormFillEnv->GetXFAContext())
    pFormFillEnv->GetXFAContext()->SetFormFillEnv(nullptr);
#endif  // PDF_ENABLE_XFA
  delete pFormFillEnv;
}

DLLEXPORT FPDF_BOOL STDCALL FORM_OnMouseMove(FPDF_FORMHANDLE hHandle,
                                             FPDF_PAGE page,
                                             int modifier,
                                             double page_x,
                                             double page_y) {
  CPDFSDK_PageView* pPageView = FormHandleToPageView(hHandle, page);
  if (!pPageView)
    return false;
  return pPageView->OnMouseMove(CFX_PointF(page_x, page_y), modifier);
}

DLLEXPORT FPDF_BOOL STDCALL FORM_OnLButtonDown(FPDF_FORMHANDLE hHandle,
                                               FPDF_PAGE page,
                                               int modifier,
                                               double page_x,
                                               double page_y) {
  CPDFSDK_PageView* pPageView = FormHandleToPageView(hHandle, page);
  if (!pPageView)
    return false;
  return pPageView->OnLButtonDown(CFX_PointF(page_x, page_y), modifier);
}

DLLEXPORT FPDF_BOOL STDCALL FORM_OnLButtonUp(FPDF_FORMHANDLE hHandle,
                                             FPDF_PAGE page,
                                             int modifier,
                                             double page_x,
                                             double page_y) {
  CPDFSDK_PageView* pPageView = FormHandleToPageView(hHandle, page);
  if (!pPageView)
    return false;
  return pPageView->OnLButtonUp(CFX_PointF(page_x, page_y), modifier);
}

#ifdef PDF_ENABLE_XFA
DLLEXPORT FPDF_BOOL STDCALL FORM_OnRButtonDown(FPDF_FORMHANDLE hHandle,
                                               FPDF_PAGE page,
                                               int modifier,
                                               double page_x,
                                               double page_y) {
  CPDFSDK_PageView* pPageView = FormHandleToPageView(hHandle, page);
  if (!pPageView)
    return false;
  return pPageView->OnRButtonDown(CFX_PointF(page_x, page_y), modifier);
}

DLLEXPORT FPDF_BOOL STDCALL FORM_OnRButtonUp(FPDF_FORMHANDLE hHandle,
                                             FPDF_PAGE page,
                                             int modifier,
                                             double page_x,
                                             double page_y) {
  CPDFSDK_PageView* pPageView = FormHandleToPageView(hHandle, page);
  if (!pPageView)
    return false;
  return pPageView->OnRButtonUp(CFX_PointF(page_x, page_y), modifier);
}
#endif  // PDF_ENABLE_XFA

DLLEXPORT FPDF_BOOL STDCALL FORM_OnKeyDown(FPDF_FORMHANDLE hHandle,
                                           FPDF_PAGE page,
                                           int nKeyCode,
                                           int modifier) {
  CPDFSDK_PageView* pPageView = FormHandleToPageView(hHandle, page);
  if (!pPageView)
    return false;
  return pPageView->OnKeyDown(nKeyCode, modifier);
}

DLLEXPORT FPDF_BOOL STDCALL FORM_OnKeyUp(FPDF_FORMHANDLE hHandle,
                                         FPDF_PAGE page,
                                         int nKeyCode,
                                         int modifier) {
  CPDFSDK_PageView* pPageView = FormHandleToPageView(hHandle, page);
  if (!pPageView)
    return false;
  return pPageView->OnKeyUp(nKeyCode, modifier);
}

DLLEXPORT FPDF_BOOL STDCALL FORM_OnChar(FPDF_FORMHANDLE hHandle,
                                        FPDF_PAGE page,
                                        int nChar,
                                        int modifier) {
  CPDFSDK_PageView* pPageView = FormHandleToPageView(hHandle, page);
  if (!pPageView)
    return false;
  return pPageView->OnChar(nChar, modifier);
}

DLLEXPORT unsigned long STDCALL FORM_GetSelectedText(FPDF_FORMHANDLE hHandle,
                                                     FPDF_PAGE page,
                                                     void* buffer,
                                                     unsigned long buflen) {
  CPDFSDK_PageView* pPageView = FormHandleToPageView(hHandle, page);
  if (!pPageView)
    return 0;

  CFX_WideString wide_str_form_text = pPageView->GetSelectedText();
  CFX_ByteString encoded_form_text = wide_str_form_text.UTF16LE_Encode();
  unsigned long form_text_len = encoded_form_text.GetLength();

  if (buffer && buflen >= form_text_len)
    memcpy(buffer, encoded_form_text.c_str(), form_text_len);

  return form_text_len;
}

DLLEXPORT void STDCALL FORM_ReplaceSelection(FPDF_FORMHANDLE hHandle,
                                             FPDF_PAGE page,
                                             FPDF_WIDESTRING wsText) {
  CPDFSDK_PageView* pPageView = FormHandleToPageView(hHandle, page);
  if (!pPageView)
    return;

  FX_STRSIZE len = CFX_WideString::WStringLength(wsText);
  CFX_WideString wide_str_text = CFX_WideString::FromUTF16LE(wsText, len);

  pPageView->ReplaceSelection(wide_str_text);
}

DLLEXPORT FPDF_BOOL STDCALL FORM_ForceToKillFocus(FPDF_FORMHANDLE hHandle) {
  CPDFSDK_FormFillEnvironment* pFormFillEnv =
      HandleToCPDFSDKEnvironment(hHandle);
  if (!pFormFillEnv)
    return false;
  return pFormFillEnv->KillFocusAnnot(0);
}

DLLEXPORT void STDCALL FPDF_FFLDraw(FPDF_FORMHANDLE hHandle,
                                    FPDF_BITMAP bitmap,
                                    FPDF_PAGE page,
                                    int start_x,
                                    int start_y,
                                    int size_x,
                                    int size_y,
                                    int rotate,
                                    int flags) {
  FFLCommon(hHandle, bitmap, nullptr, page, start_x, start_y, size_x, size_y,
            rotate, flags);
}

#ifdef _SKIA_SUPPORT_
DLLEXPORT void STDCALL FPDF_FFLRecord(FPDF_FORMHANDLE hHandle,
                                      FPDF_RECORDER recorder,
                                      FPDF_PAGE page,
                                      int start_x,
                                      int start_y,
                                      int size_x,
                                      int size_y,
                                      int rotate,
                                      int flags) {
  FFLCommon(hHandle, nullptr, recorder, page, start_x, start_y, size_x, size_y,
            rotate, flags);
}
#endif

#ifdef PDF_ENABLE_XFA
DLLEXPORT void STDCALL FPDF_Widget_Undo(FPDF_DOCUMENT document,
                                        FPDF_WIDGET hWidget) {
  if (!hWidget || !document)
    return;

  CPDFXFA_Context* pContext = static_cast<CPDFXFA_Context*>(document);
  if (pContext->GetDocType() != XFA_DocType::Dynamic &&
      pContext->GetDocType() != XFA_DocType::Static) {
    return;
  }

  static_cast<CXFA_FFWidget*>(hWidget)->Undo();
}

DLLEXPORT void STDCALL FPDF_Widget_Redo(FPDF_DOCUMENT document,
                                        FPDF_WIDGET hWidget) {
  if (!hWidget || !document)
    return;

  CPDFXFA_Context* pContext = static_cast<CPDFXFA_Context*>(document);
  if (pContext->GetDocType() != XFA_DocType::Dynamic &&
      pContext->GetDocType() != XFA_DocType::Static)
    return;

  static_cast<CXFA_FFWidget*>(hWidget)->Redo();
}

DLLEXPORT void STDCALL FPDF_Widget_SelectAll(FPDF_DOCUMENT document,
                                             FPDF_WIDGET hWidget) {
  if (!hWidget || !document)
    return;

  CPDFXFA_Context* pContext = static_cast<CPDFXFA_Context*>(document);
  if (pContext->GetDocType() != XFA_DocType::Dynamic &&
      pContext->GetDocType() != XFA_DocType::Static)
    return;

  static_cast<CXFA_FFWidget*>(hWidget)->SelectAll();
}

DLLEXPORT void STDCALL FPDF_Widget_Copy(FPDF_DOCUMENT document,
                                        FPDF_WIDGET hWidget,
                                        FPDF_WIDESTRING wsText,
                                        FPDF_DWORD* size) {
  if (!hWidget || !document)
    return;

  CPDFXFA_Context* pContext = static_cast<CPDFXFA_Context*>(document);
  if (pContext->GetDocType() != XFA_DocType::Dynamic &&
      pContext->GetDocType() != XFA_DocType::Static)
    return;

  CFX_WideString wsCpText;
  static_cast<CXFA_FFWidget*>(hWidget)->Copy(wsCpText);

  CFX_ByteString bsCpText = wsCpText.UTF16LE_Encode();
  uint32_t len = bsCpText.GetLength() / sizeof(unsigned short);
  if (!wsText) {
    *size = len;
    return;
  }

  uint32_t real_size = len < *size ? len : *size;
  if (real_size > 0) {
    memcpy((void*)wsText,
           bsCpText.GetBuffer(real_size * sizeof(unsigned short)),
           real_size * sizeof(unsigned short));
    bsCpText.ReleaseBuffer(real_size * sizeof(unsigned short));
  }
  *size = real_size;
}

DLLEXPORT void STDCALL FPDF_Widget_Cut(FPDF_DOCUMENT document,
                                       FPDF_WIDGET hWidget,
                                       FPDF_WIDESTRING wsText,
                                       FPDF_DWORD* size) {
  if (!hWidget || !document)
    return;

  CPDFXFA_Context* pContext = static_cast<CPDFXFA_Context*>(document);
  if (pContext->GetDocType() != XFA_DocType::Dynamic &&
      pContext->GetDocType() != XFA_DocType::Static)
    return;

  CFX_WideString wsCpText;
  static_cast<CXFA_FFWidget*>(hWidget)->Cut(wsCpText);

  CFX_ByteString bsCpText = wsCpText.UTF16LE_Encode();
  uint32_t len = bsCpText.GetLength() / sizeof(unsigned short);
  if (!wsText) {
    *size = len;
    return;
  }

  uint32_t real_size = len < *size ? len : *size;
  if (real_size > 0) {
    memcpy((void*)wsText,
           bsCpText.GetBuffer(real_size * sizeof(unsigned short)),
           real_size * sizeof(unsigned short));
    bsCpText.ReleaseBuffer(real_size * sizeof(unsigned short));
  }
  *size = real_size;
}

DLLEXPORT void STDCALL FPDF_Widget_Paste(FPDF_DOCUMENT document,
                                         FPDF_WIDGET hWidget,
                                         FPDF_WIDESTRING wsText,
                                         FPDF_DWORD size) {
  if (!hWidget || !document)
    return;

  CPDFXFA_Context* pContext = static_cast<CPDFXFA_Context*>(document);
  if (pContext->GetDocType() != XFA_DocType::Dynamic &&
      pContext->GetDocType() != XFA_DocType::Static)
    return;

  CFX_WideString wstr = CFX_WideString::FromUTF16LE(wsText, size);
  static_cast<CXFA_FFWidget*>(hWidget)->Paste(wstr);
}

DLLEXPORT void STDCALL
FPDF_Widget_ReplaceSpellCheckWord(FPDF_DOCUMENT document,
                                  FPDF_WIDGET hWidget,
                                  float x,
                                  float y,
                                  FPDF_BYTESTRING bsText) {
  if (!hWidget || !document)
    return;

  CPDFXFA_Context* pContext = static_cast<CPDFXFA_Context*>(document);
  if (pContext->GetDocType() != XFA_DocType::Dynamic &&
      pContext->GetDocType() != XFA_DocType::Static)
    return;

  CFX_PointF ptPopup;
  ptPopup.x = x;
  ptPopup.y = y;
  CFX_ByteStringC bs(bsText);
  static_cast<CXFA_FFWidget*>(hWidget)->ReplaceSpellCheckWord(ptPopup, bs);
}

DLLEXPORT void STDCALL
FPDF_Widget_GetSpellCheckWords(FPDF_DOCUMENT document,
                               FPDF_WIDGET hWidget,
                               float x,
                               float y,
                               FPDF_STRINGHANDLE* stringHandle) {
  if (!hWidget || !document)
    return;

  auto* pContext = static_cast<CPDFXFA_Context*>(document);
  if (pContext->GetDocType() != XFA_DocType::Dynamic &&
      pContext->GetDocType() != XFA_DocType::Static)
    return;

  CFX_PointF ptPopup;
  ptPopup.x = x;
  ptPopup.y = y;
  auto sSuggestWords = pdfium::MakeUnique<std::vector<CFX_ByteString>>();
  static_cast<CXFA_FFWidget*>(hWidget)->GetSuggestWords(ptPopup,
                                                        sSuggestWords.get());

  // Caller takes ownership.
  *stringHandle = ToFPDFStringHandle(sSuggestWords.release());
}

DLLEXPORT int STDCALL FPDF_StringHandleCounts(FPDF_STRINGHANDLE sHandle) {
  std::vector<CFX_ByteString>* sSuggestWords = FromFPDFStringHandle(sHandle);
  return sSuggestWords ? pdfium::CollectionSize<int>(*sSuggestWords) : -1;
}

DLLEXPORT FPDF_BOOL STDCALL
FPDF_StringHandleGetStringByIndex(FPDF_STRINGHANDLE sHandle,
                                  int index,
                                  FPDF_BYTESTRING bsText,
                                  FPDF_DWORD* size) {
  if (!sHandle || !size)
    return false;

  int count = FPDF_StringHandleCounts(sHandle);
  if (index < 0 || index >= count)
    return false;

  std::vector<CFX_ByteString>* sSuggestWords = FromFPDFStringHandle(sHandle);
  uint32_t len = (*sSuggestWords)[index].GetLength();
  if (!bsText) {
    *size = len;
    return true;
  }

  uint32_t real_size = len < *size ? len : *size;
  if (real_size > 0)
    memcpy((void*)bsText, (*sSuggestWords)[index].c_str(), real_size);
  *size = real_size;
  return true;
}

DLLEXPORT void STDCALL
FPDF_StringHandleRelease(FPDF_STRINGHANDLE stringHandle) {
  delete FromFPDFStringHandle(stringHandle);
}

DLLEXPORT FPDF_BOOL STDCALL
FPDF_StringHandleAddString(FPDF_STRINGHANDLE stringHandle,
                           FPDF_BYTESTRING bsText,
                           FPDF_DWORD size) {
  if (!stringHandle || !bsText || size == 0)
    return false;

  FromFPDFStringHandle(stringHandle)->push_back(CFX_ByteString(bsText, size));
  return true;
}
#endif  // PDF_ENABLE_XFA

DLLEXPORT void STDCALL FPDF_SetFormFieldHighlightColor(FPDF_FORMHANDLE hHandle,
                                                       int fieldType,
                                                       unsigned long color) {
  if (CPDFSDK_InterForm* pInterForm = FormHandleToInterForm(hHandle))
    pInterForm->SetHighlightColor(color, fieldType);
}

DLLEXPORT void STDCALL FPDF_SetFormFieldHighlightAlpha(FPDF_FORMHANDLE hHandle,
                                                       unsigned char alpha) {
  if (CPDFSDK_InterForm* pInterForm = FormHandleToInterForm(hHandle))
    pInterForm->SetHighlightAlpha(alpha);
}

DLLEXPORT void STDCALL FPDF_RemoveFormFieldHighlight(FPDF_FORMHANDLE hHandle) {
  if (CPDFSDK_InterForm* pInterForm = FormHandleToInterForm(hHandle))
    pInterForm->RemoveAllHighLight();
}

DLLEXPORT void STDCALL FORM_OnAfterLoadPage(FPDF_PAGE page,
                                            FPDF_FORMHANDLE hHandle) {
  if (CPDFSDK_PageView* pPageView = FormHandleToPageView(hHandle, page))
    pPageView->SetValid(true);
}

DLLEXPORT void STDCALL FORM_OnBeforeClosePage(FPDF_PAGE page,
                                              FPDF_FORMHANDLE hHandle) {
  CPDFSDK_FormFillEnvironment* pFormFillEnv =
      HandleToCPDFSDKEnvironment(hHandle);
  if (!pFormFillEnv)
    return;

  UnderlyingPageType* pPage = UnderlyingFromFPDFPage(page);
  if (!pPage)
    return;

  CPDFSDK_PageView* pPageView = pFormFillEnv->GetPageView(pPage, false);
  if (pPageView) {
    pPageView->SetValid(false);
    // RemovePageView() takes care of the delete for us.
    pFormFillEnv->RemovePageView(pPage);
  }
}

DLLEXPORT void STDCALL FORM_DoDocumentJSAction(FPDF_FORMHANDLE hHandle) {
  CPDFSDK_FormFillEnvironment* pFormFillEnv =
      HandleToCPDFSDKEnvironment(hHandle);
  if (pFormFillEnv && pFormFillEnv->IsJSInitiated())
    pFormFillEnv->ProcJavascriptFun();
}

DLLEXPORT void STDCALL FORM_DoDocumentOpenAction(FPDF_FORMHANDLE hHandle) {
  CPDFSDK_FormFillEnvironment* pFormFillEnv =
      HandleToCPDFSDKEnvironment(hHandle);
  if (pFormFillEnv && pFormFillEnv->IsJSInitiated())
    pFormFillEnv->ProcOpenAction();
}

DLLEXPORT void STDCALL FORM_DoDocumentAAction(FPDF_FORMHANDLE hHandle,
                                              int aaType) {
  CPDFSDK_FormFillEnvironment* pFormFillEnv =
      HandleToCPDFSDKEnvironment(hHandle);
  if (!pFormFillEnv)
    return;

  CPDF_Document* pDoc = pFormFillEnv->GetPDFDocument();
  CPDF_Dictionary* pDict = pDoc->GetRoot();
  if (!pDict)
    return;

  CPDF_AAction aa(pDict->GetDictFor("AA"));
  auto type = static_cast<CPDF_AAction::AActionType>(aaType);
  if (aa.ActionExist(type)) {
    CPDF_Action action = aa.GetAction(type);
    CPDFSDK_ActionHandler* pActionHandler =
        HandleToCPDFSDKEnvironment(hHandle)->GetActionHandler();
    pActionHandler->DoAction_Document(action, type, pFormFillEnv);
  }
}

DLLEXPORT void STDCALL FORM_DoPageAAction(FPDF_PAGE page,
                                          FPDF_FORMHANDLE hHandle,
                                          int aaType) {
  CPDFSDK_FormFillEnvironment* pFormFillEnv =
      HandleToCPDFSDKEnvironment(hHandle);
  if (!pFormFillEnv)
    return;

  UnderlyingPageType* pPage = UnderlyingFromFPDFPage(page);
  CPDF_Page* pPDFPage = CPDFPageFromFPDFPage(page);
  if (!pPDFPage)
    return;

  if (!pFormFillEnv->GetPageView(pPage, false))
    return;

  CPDFSDK_ActionHandler* pActionHandler = pFormFillEnv->GetActionHandler();
  CPDF_Dictionary* pPageDict = pPDFPage->m_pFormDict.Get();
  CPDF_AAction aa(pPageDict->GetDictFor("AA"));
  CPDF_AAction::AActionType type = aaType == FPDFPAGE_AACTION_OPEN
                                       ? CPDF_AAction::OpenPage
                                       : CPDF_AAction::ClosePage;
  if (aa.ActionExist(type)) {
    CPDF_Action action = aa.GetAction(type);
    pActionHandler->DoAction_Page(action, type, pFormFillEnv);
  }
}
