// Copyright 2014 The PDFium Authors
// 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 <utility>

#include "constants/form_fields.h"
#include "core/fpdfapi/page/cpdf_annotcontext.h"
#include "core/fpdfapi/page/cpdf_occontext.h"
#include "core/fpdfapi/page/cpdf_page.h"
#include "core/fpdfapi/parser/cpdf_dictionary.h"
#include "core/fpdfapi/parser/cpdf_document.h"
#include "core/fpdfapi/parser/cpdf_stream.h"
#include "core/fpdfapi/render/cpdf_renderoptions.h"
#include "core/fpdfdoc/cpdf_formcontrol.h"
#include "core/fpdfdoc/cpdf_formfield.h"
#include "core/fpdfdoc/cpdf_interactiveform.h"
#include "core/fxge/cfx_defaultrenderdevice.h"
#include "core/fxge/dib/cfx_dibitmap.h"
#include "fpdfsdk/cpdfsdk_annot.h"
#include "fpdfsdk/cpdfsdk_formfillenvironment.h"
#include "fpdfsdk/cpdfsdk_helpers.h"
#include "fpdfsdk/cpdfsdk_interactiveform.h"
#include "fpdfsdk/cpdfsdk_pageview.h"
#include "public/fpdfview.h"

#if defined(_SKIA_SUPPORT_)
#include "third_party/skia/include/core/SkPictureRecorder.h"  // nogncheck
#endif  // defined(_SKIA_SUPPORT_)

#ifdef PDF_ENABLE_XFA
#include "fpdfsdk/fpdfxfa/cpdfxfa_context.h"
#include "fpdfsdk/fpdfxfa/cpdfxfa_page.h"

static_assert(static_cast<int>(AlertButton::kDefault) ==
                  JSPLATFORM_ALERT_BUTTON_DEFAULT,
              "Default alert button types must match");
static_assert(static_cast<int>(AlertButton::kOK) == JSPLATFORM_ALERT_BUTTON_OK,
              "OK alert button types must match");
static_assert(static_cast<int>(AlertButton::kOKCancel) ==
                  JSPLATFORM_ALERT_BUTTON_OKCANCEL,
              "OKCancel alert button types must match");
static_assert(static_cast<int>(AlertButton::kYesNo) ==
                  JSPLATFORM_ALERT_BUTTON_YESNO,
              "YesNo alert button types must match");
static_assert(static_cast<int>(AlertButton::kYesNoCancel) ==
                  JSPLATFORM_ALERT_BUTTON_YESNOCANCEL,
              "YesNoCancel alert button types must match");

static_assert(static_cast<int>(AlertIcon::kDefault) ==
                  JSPLATFORM_ALERT_ICON_DEFAULT,
              "Default alert icon types must match");
static_assert(static_cast<int>(AlertIcon::kError) ==
                  JSPLATFORM_ALERT_ICON_ERROR,
              "Error alert icon types must match");
static_assert(static_cast<int>(AlertIcon::kWarning) ==
                  JSPLATFORM_ALERT_ICON_WARNING,
              "Warning alert icon types must match");
static_assert(static_cast<int>(AlertIcon::kQuestion) ==
                  JSPLATFORM_ALERT_ICON_QUESTION,
              "Question alert icon types must match");
static_assert(static_cast<int>(AlertIcon::kStatus) ==
                  JSPLATFORM_ALERT_ICON_STATUS,
              "Status alert icon types must match");
static_assert(static_cast<int>(AlertIcon::kAsterisk) ==
                  JSPLATFORM_ALERT_ICON_ASTERISK,
              "Asterisk alert icon types must match");

static_assert(static_cast<int>(AlertReturn::kOK) == JSPLATFORM_ALERT_RETURN_OK,
              "OK alert return types must match");
static_assert(static_cast<int>(AlertReturn::kCancel) ==
                  JSPLATFORM_ALERT_RETURN_CANCEL,
              "Cancel alert return types must match");
static_assert(static_cast<int>(AlertReturn::kNo) == JSPLATFORM_ALERT_RETURN_NO,
              "No alert return types must match");
static_assert(static_cast<int>(AlertReturn::kYes) ==
                  JSPLATFORM_ALERT_RETURN_YES,
              "Yes alert return types must match");

static_assert(static_cast<int>(FormType::kNone) == FORMTYPE_NONE,
              "None form types must match");
static_assert(static_cast<int>(FormType::kAcroForm) == FORMTYPE_ACRO_FORM,
              "AcroForm form types must match");
static_assert(static_cast<int>(FormType::kXFAFull) == FORMTYPE_XFA_FULL,
              "XFA full form types must match");
static_assert(static_cast<int>(FormType::kXFAForeground) ==
                  FORMTYPE_XFA_FOREGROUND,
              "XFA foreground form types must match");
#endif  // PDF_ENABLE_XFA

static_assert(static_cast<int>(FormFieldType::kUnknown) ==
                  FPDF_FORMFIELD_UNKNOWN,
              "Unknown form field types must match");
static_assert(static_cast<int>(FormFieldType::kPushButton) ==
                  FPDF_FORMFIELD_PUSHBUTTON,
              "PushButton form field types must match");
static_assert(static_cast<int>(FormFieldType::kCheckBox) ==
                  FPDF_FORMFIELD_CHECKBOX,
              "CheckBox form field types must match");
static_assert(static_cast<int>(FormFieldType::kRadioButton) ==
                  FPDF_FORMFIELD_RADIOBUTTON,
              "RadioButton form field types must match");
static_assert(static_cast<int>(FormFieldType::kComboBox) ==
                  FPDF_FORMFIELD_COMBOBOX,
              "ComboBox form field types must match");
static_assert(static_cast<int>(FormFieldType::kListBox) ==
                  FPDF_FORMFIELD_LISTBOX,
              "ListBox form field types must match");
static_assert(static_cast<int>(FormFieldType::kTextField) ==
                  FPDF_FORMFIELD_TEXTFIELD,
              "TextField form field types must match");
static_assert(static_cast<int>(FormFieldType::kSignature) ==
                  FPDF_FORMFIELD_SIGNATURE,
              "Signature form field types must match");
#ifdef PDF_ENABLE_XFA
static_assert(static_cast<int>(FormFieldType::kXFA) == FPDF_FORMFIELD_XFA,
              "XFA form field types must match");
static_assert(static_cast<int>(FormFieldType::kXFA_CheckBox) ==
                  FPDF_FORMFIELD_XFA_CHECKBOX,
              "XFA CheckBox form field types must match");
static_assert(static_cast<int>(FormFieldType::kXFA_ComboBox) ==
                  FPDF_FORMFIELD_XFA_COMBOBOX,
              "XFA ComboBox form field types must match");
static_assert(static_cast<int>(FormFieldType::kXFA_ImageField) ==
                  FPDF_FORMFIELD_XFA_IMAGEFIELD,
              "XFA ImageField form field types must match");
static_assert(static_cast<int>(FormFieldType::kXFA_ListBox) ==
                  FPDF_FORMFIELD_XFA_LISTBOX,
              "XFA ListBox form field types must match");
static_assert(static_cast<int>(FormFieldType::kXFA_PushButton) ==
                  FPDF_FORMFIELD_XFA_PUSHBUTTON,
              "XFA PushButton form field types must match");
static_assert(static_cast<int>(FormFieldType::kXFA_Signature) ==
                  FPDF_FORMFIELD_XFA_SIGNATURE,
              "XFA Signature form field types must match");
static_assert(static_cast<int>(FormFieldType::kXFA_TextField) ==
                  FPDF_FORMFIELD_XFA_TEXTFIELD,
              "XFA TextField form field types must match");
#endif  // PDF_ENABLE_XFA
static_assert(kFormFieldTypeCount == FPDF_FORMFIELD_COUNT,
              "Number of form field types must match");

static_assert(static_cast<int>(CPDF_AAction::kCloseDocument) ==
                  FPDFDOC_AACTION_WC,
              "CloseDocument action must match");
static_assert(static_cast<int>(CPDF_AAction::kSaveDocument) ==
                  FPDFDOC_AACTION_WS,
              "SaveDocument action must match");
static_assert(static_cast<int>(CPDF_AAction::kDocumentSaved) ==
                  FPDFDOC_AACTION_DS,
              "DocumentSaved action must match");
static_assert(static_cast<int>(CPDF_AAction::kPrintDocument) ==
                  FPDFDOC_AACTION_WP,
              "PrintDocument action must match");
static_assert(static_cast<int>(CPDF_AAction::kDocumentPrinted) ==
                  FPDFDOC_AACTION_DP,
              "DocumentPrinted action must match");

namespace {

CPDFSDK_PageView* FormHandleToPageView(FPDF_FORMHANDLE hHandle,
                                       FPDF_PAGE fpdf_page) {
  IPDF_Page* pPage = IPDFPageFromFPDFPage(fpdf_page);
  if (!pPage)
    return nullptr;

  CPDFSDK_FormFillEnvironment* pFormFillEnv =
      CPDFSDKFormFillEnvironmentFromFPDFFormHandle(hHandle);
  return pFormFillEnv ? pFormFillEnv->GetOrCreatePageView(pPage) : nullptr;
}

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

  IPDF_Page* pPage = IPDFPageFromFPDFPage(fpdf_page);
  if (!pPage)
    return;

  CPDF_Document* pPDFDoc = pPage->GetDocument();
  CPDFSDK_PageView* pPageView = FormHandleToPageView(hHandle, fpdf_page);

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

  auto pDevice = std::make_unique<CFX_DefaultRenderDevice>();
#if defined(_SKIA_SUPPORT_)
  if (CFX_DefaultRenderDevice::SkiaIsDefaultRenderer() && recorder) {
    pDevice->AttachCanvas(
        static_cast<SkPictureRecorder*>(recorder)->getRecordingCanvas());
  }
#endif

  RetainPtr<CFX_DIBitmap> holder(CFXDIBitmapFromFPDFBitmap(bitmap));
  pDevice->AttachWithRgbByteOrder(holder, !!(flags & FPDF_REVERSE_BYTE_ORDER));
  {
    CFX_RenderDevice::StateRestorer restorer(pDevice.get());
    pDevice->SetClip_Rect(rect);

    CPDF_RenderOptions options;
    options.GetOptions().bClearType = !!(flags & FPDF_LCD_TEXT);

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

    options.SetDrawAnnots(flags & FPDF_ANNOT);
    options.SetOCContext(
        pdfium::MakeRetain<CPDF_OCContext>(pPDFDoc, CPDF_OCContext::kView));

    if (pPageView)
      pPageView->PageView_OnDraw(pDevice.get(), matrix, &options, rect);
  }
}

// Returns true if formfill version is correctly set. See |version| in
// FPDF_FORMFILLINFO for details regarding correct version.
bool CheckFormfillVersion(FPDF_FORMFILLINFO* formInfo) {
  if (!formInfo || formInfo->version < 1 || formInfo->version > 2)
    return false;

#ifdef PDF_ENABLE_XFA
  if (formInfo->version != 2)
    return false;
#endif  // PDF_ENABLE_XFA

  return true;
}

}  // namespace

FPDF_EXPORT int FPDF_CALLCONV
FPDFPage_HasFormFieldAtPoint(FPDF_FORMHANDLE hHandle,
                             FPDF_PAGE page,
                             double page_x,
                             double page_y) {
  const CPDF_Page* pPage = CPDFPageFromFPDFPage(page);
  if (pPage) {
    CPDFSDK_InteractiveForm* pForm = FormHandleToInteractiveForm(hHandle);
    if (!pForm)
      return -1;

    const CPDF_InteractiveForm* pPDFForm = pForm->GetInteractiveForm();
    const CPDF_FormControl* pFormCtrl = pPDFForm->GetControlAtPoint(
        pPage,
        CFX_PointF(static_cast<float>(page_x), static_cast<float>(page_y)),
        nullptr);
    if (!pFormCtrl)
      return -1;
    const CPDF_FormField* pFormField = pFormCtrl->GetField();
    return pFormField ? static_cast<int>(pFormField->GetFieldType()) : -1;
  }

#ifdef PDF_ENABLE_XFA
  const CPDFXFA_Page* pXFAPage = ToXFAPage(IPDFPageFromFPDFPage(page));
  if (pXFAPage) {
    return pXFAPage->HasFormFieldAtPoint(
        CFX_PointF(static_cast<float>(page_x), static_cast<float>(page_y)));
  }
#endif  // PDF_ENABLE_XFA

  return -1;
}

FPDF_EXPORT int FPDF_CALLCONV
FPDFPage_FormFieldZOrderAtPoint(FPDF_FORMHANDLE hHandle,
                                FPDF_PAGE page,
                                double page_x,
                                double page_y) {
  CPDFSDK_InteractiveForm* pForm = FormHandleToInteractiveForm(hHandle);
  if (!pForm)
    return -1;

  CPDF_Page* pPage = CPDFPageFromFPDFPage(page);
  if (!pPage)
    return -1;

  CPDF_InteractiveForm* pPDFForm = pForm->GetInteractiveForm();
  int z_order = -1;
  pPDFForm->GetControlAtPoint(
      pPage, CFX_PointF(static_cast<float>(page_x), static_cast<float>(page_y)),
      &z_order);
  return z_order;
}

FPDF_EXPORT FPDF_FORMHANDLE FPDF_CALLCONV
FPDFDOC_InitFormFillEnvironment(FPDF_DOCUMENT document,
                                FPDF_FORMFILLINFO* formInfo) {
  if (!CheckFormfillVersion(formInfo))
    return nullptr;

  auto* pDocument = CPDFDocumentFromFPDFDocument(document);
  if (!pDocument)
    return nullptr;

#ifdef PDF_ENABLE_XFA
  CPDFXFA_Context* pContext = nullptr;
  if (!formInfo->xfa_disabled) {
    if (!pDocument->GetExtension()) {
      pDocument->SetExtension(std::make_unique<CPDFXFA_Context>(pDocument));
    }

    // 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.
    pContext = static_cast<CPDFXFA_Context*>(pDocument->GetExtension());
    if (pContext->GetFormFillEnv()) {
      return FPDFFormHandleFromCPDFSDKFormFillEnvironment(
          pContext->GetFormFillEnv());
    }
  }
#endif  // PDF_ENABLE_XFA

  auto pFormFillEnv =
      std::make_unique<CPDFSDK_FormFillEnvironment>(pDocument, formInfo);

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

  ReportUnsupportedXFA(pDocument);

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

FPDF_EXPORT void FPDF_CALLCONV
FPDFDOC_ExitFormFillEnvironment(FPDF_FORMHANDLE hHandle) {
  if (!hHandle)
    return;

  // Take back ownership of the form fill environment. This is the inverse of
  // FPDFDOC_InitFormFillEnvironment() above.
  std::unique_ptr<CPDFSDK_FormFillEnvironment> pFormFillEnv(
      CPDFSDKFormFillEnvironmentFromFPDFFormHandle(hHandle));

#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.
  auto* pContext =
      static_cast<CPDFXFA_Context*>(pFormFillEnv->GetDocExtension());
  if (pContext)
    pContext->SetFormFillEnv(nullptr);
#endif  // PDF_ENABLE_XFA
}

FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV FORM_OnMouseMove(FPDF_FORMHANDLE hHandle,
                                                     FPDF_PAGE page,
                                                     int modifier,
                                                     double page_x,
                                                     double page_y) {
  CPDFSDK_PageView* pPageView = FormHandleToPageView(hHandle, page);
  return pPageView &&
         pPageView->OnMouseMove(
             Mask<FWL_EVENTFLAG>::FromUnderlyingUnchecked(modifier),
             CFX_PointF(page_x, page_y));
}

FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV
FORM_OnMouseWheel(FPDF_FORMHANDLE hHandle,
                  FPDF_PAGE page,
                  int modifier,
                  const FS_POINTF* page_coord,
                  int delta_x,
                  int delta_y) {
  if (!page_coord)
    return false;

  CPDFSDK_PageView* pPageView = FormHandleToPageView(hHandle, page);
  return pPageView &&
         pPageView->OnMouseWheel(
             Mask<FWL_EVENTFLAG>::FromUnderlyingUnchecked(modifier),
             CFXPointFFromFSPointF(*page_coord), CFX_Vector(delta_x, delta_y));
}

FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV FORM_OnFocus(FPDF_FORMHANDLE hHandle,
                                                 FPDF_PAGE page,
                                                 int modifier,
                                                 double page_x,
                                                 double page_y) {
  CPDFSDK_PageView* pPageView = FormHandleToPageView(hHandle, page);
  return pPageView &&
         pPageView->OnFocus(
             Mask<FWL_EVENTFLAG>::FromUnderlyingUnchecked(modifier),
             CFX_PointF(page_x, page_y));
}

FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV FORM_OnLButtonDown(FPDF_FORMHANDLE hHandle,
                                                       FPDF_PAGE page,
                                                       int modifier,
                                                       double page_x,
                                                       double page_y) {
#ifdef PDF_ENABLE_CLICK_LOGGING
  fprintf(stderr, "mousedown,left,%d,%d\n", static_cast<int>(round(page_x)),
          static_cast<int>(round(page_y)));
#endif  // PDF_ENABLE_CLICK_LOGGING
  CPDFSDK_PageView* pPageView = FormHandleToPageView(hHandle, page);
  return pPageView &&
         pPageView->OnLButtonDown(
             Mask<FWL_EVENTFLAG>::FromUnderlyingUnchecked(modifier),
             CFX_PointF(page_x, page_y));
}

FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV FORM_OnLButtonUp(FPDF_FORMHANDLE hHandle,
                                                     FPDF_PAGE page,
                                                     int modifier,
                                                     double page_x,
                                                     double page_y) {
#ifdef PDF_ENABLE_CLICK_LOGGING
  fprintf(stderr, "mouseup,left,%d,%d\n", static_cast<int>(round(page_x)),
          static_cast<int>(round(page_y)));
#endif  // PDF_ENABLE_CLICK_LOGGING
  CPDFSDK_PageView* pPageView = FormHandleToPageView(hHandle, page);
  return pPageView &&
         pPageView->OnLButtonUp(
             Mask<FWL_EVENTFLAG>::FromUnderlyingUnchecked(modifier),
             CFX_PointF(page_x, page_y));
}

FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV
FORM_OnLButtonDoubleClick(FPDF_FORMHANDLE hHandle,
                          FPDF_PAGE page,
                          int modifier,
                          double page_x,
                          double page_y) {
#ifdef PDF_ENABLE_CLICK_LOGGING
  fprintf(stderr, "mousedown,doubleleft,%d,%d\n",
          static_cast<int>(round(page_x)), static_cast<int>(round(page_y)));
#endif  // PDF_ENABLE_CLICK_LOGGING
  CPDFSDK_PageView* pPageView = FormHandleToPageView(hHandle, page);
  return pPageView &&
         pPageView->OnLButtonDblClk(
             Mask<FWL_EVENTFLAG>::FromUnderlyingUnchecked(modifier),
             CFX_PointF(page_x, page_y));
}

FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV FORM_OnRButtonDown(FPDF_FORMHANDLE hHandle,
                                                       FPDF_PAGE page,
                                                       int modifier,
                                                       double page_x,
                                                       double page_y) {
#ifdef PDF_ENABLE_CLICK_LOGGING
  fprintf(stderr, "mousedown,right,%d,%d\n", static_cast<int>(round(page_x)),
          static_cast<int>(round(page_y)));
#endif  // PDF_ENABLE_CLICK_LOGGING
  CPDFSDK_PageView* pPageView = FormHandleToPageView(hHandle, page);
  return pPageView &&
         pPageView->OnRButtonDown(
             Mask<FWL_EVENTFLAG>::FromUnderlyingUnchecked(modifier),
             CFX_PointF(page_x, page_y));
}

FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV FORM_OnRButtonUp(FPDF_FORMHANDLE hHandle,
                                                     FPDF_PAGE page,
                                                     int modifier,
                                                     double page_x,
                                                     double page_y) {
#ifdef PDF_ENABLE_CLICK_LOGGING
  fprintf(stderr, "mouseup,right,%d,%d\n", static_cast<int>(round(page_x)),
          static_cast<int>(round(page_y)));
#endif  // PDF_ENABLE_CLICK_LOGGING
  CPDFSDK_PageView* pPageView = FormHandleToPageView(hHandle, page);
  return pPageView &&
         pPageView->OnRButtonUp(
             Mask<FWL_EVENTFLAG>::FromUnderlyingUnchecked(modifier),
             CFX_PointF(page_x, page_y));
}

FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV FORM_OnKeyDown(FPDF_FORMHANDLE hHandle,
                                                   FPDF_PAGE page,
                                                   int nKeyCode,
                                                   int modifier) {
  CPDFSDK_PageView* pPageView = FormHandleToPageView(hHandle, page);
  return pPageView &&
         pPageView->OnKeyDown(
             static_cast<FWL_VKEYCODE>(nKeyCode),
             Mask<FWL_EVENTFLAG>::FromUnderlyingUnchecked(modifier));
}

FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV FORM_OnKeyUp(FPDF_FORMHANDLE hHandle,
                                                 FPDF_PAGE page,
                                                 int nKeyCode,
                                                 int modifier) {
  return false;
}

FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV FORM_OnChar(FPDF_FORMHANDLE hHandle,
                                                FPDF_PAGE page,
                                                int nChar,
                                                int modifier) {
  CPDFSDK_PageView* pPageView = FormHandleToPageView(hHandle, page);
  return pPageView &&
         pPageView->OnChar(
             nChar, Mask<FWL_EVENTFLAG>::FromUnderlyingUnchecked(modifier));
}

FPDF_EXPORT unsigned long FPDF_CALLCONV
FORM_GetFocusedText(FPDF_FORMHANDLE hHandle,
                    FPDF_PAGE page,
                    void* buffer,
                    unsigned long buflen) {
  CPDFSDK_PageView* pPageView = FormHandleToPageView(hHandle, page);
  if (!pPageView)
    return 0;

  return Utf16EncodeMaybeCopyAndReturnLength(pPageView->GetFocusedFormText(),
                                             buffer, buflen);
}

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

  return Utf16EncodeMaybeCopyAndReturnLength(pPageView->GetSelectedText(),
                                             buffer, buflen);
}

FPDF_EXPORT void FPDF_CALLCONV
FORM_ReplaceAndKeepSelection(FPDF_FORMHANDLE hHandle,
                             FPDF_PAGE page,
                             FPDF_WIDESTRING wsText) {
  CPDFSDK_PageView* pPageView = FormHandleToPageView(hHandle, page);
  if (!pPageView)
    return;

  pPageView->ReplaceAndKeepSelection(WideStringFromFPDFWideString(wsText));
}

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

  pPageView->ReplaceSelection(WideStringFromFPDFWideString(wsText));
}

FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV FORM_SelectAllText(FPDF_FORMHANDLE hHandle,
                                                       FPDF_PAGE page) {
  CPDFSDK_PageView* pPageView = FormHandleToPageView(hHandle, page);
  return pPageView && pPageView->SelectAllText();
}

FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV FORM_CanUndo(FPDF_FORMHANDLE hHandle,
                                                 FPDF_PAGE page) {
  CPDFSDK_PageView* pPageView = FormHandleToPageView(hHandle, page);
  if (!pPageView)
    return false;
  return pPageView->CanUndo();
}

FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV FORM_CanRedo(FPDF_FORMHANDLE hHandle,
                                                 FPDF_PAGE page) {
  CPDFSDK_PageView* pPageView = FormHandleToPageView(hHandle, page);
  if (!pPageView)
    return false;
  return pPageView->CanRedo();
}

FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV FORM_Undo(FPDF_FORMHANDLE hHandle,
                                              FPDF_PAGE page) {
  CPDFSDK_PageView* pPageView = FormHandleToPageView(hHandle, page);
  if (!pPageView)
    return false;
  return pPageView->Undo();
}

FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV FORM_Redo(FPDF_FORMHANDLE hHandle,
                                              FPDF_PAGE page) {
  CPDFSDK_PageView* pPageView = FormHandleToPageView(hHandle, page);
  if (!pPageView)
    return false;
  return pPageView->Redo();
}

FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV
FORM_ForceToKillFocus(FPDF_FORMHANDLE hHandle) {
  CPDFSDK_FormFillEnvironment* pFormFillEnv =
      CPDFSDKFormFillEnvironmentFromFPDFFormHandle(hHandle);
  if (!pFormFillEnv)
    return false;
  return pFormFillEnv->KillFocusAnnot({});
}

FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV
FORM_GetFocusedAnnot(FPDF_FORMHANDLE handle,
                     int* page_index,
                     FPDF_ANNOTATION* annot) {
  if (!page_index || !annot)
    return false;

  CPDFSDK_FormFillEnvironment* form_fill_env =
      CPDFSDKFormFillEnvironmentFromFPDFFormHandle(handle);
  if (!form_fill_env)
    return false;

  // Set |page_index| and |annot| to default values. This is returned when there
  // is no focused annotation.
  *page_index = -1;
  *annot = nullptr;

  CPDFSDK_Annot* cpdfsdk_annot = form_fill_env->GetFocusAnnot();
  if (!cpdfsdk_annot)
    return true;

  // TODO(crbug.com/pdfium/1482): Handle XFA case.
  if (cpdfsdk_annot->AsXFAWidget())
    return true;

  CPDFSDK_PageView* page_view = cpdfsdk_annot->GetPageView();
  if (!page_view->IsValid())
    return true;

  IPDF_Page* page = cpdfsdk_annot->GetPage();
  if (!page)
    return true;

  RetainPtr<CPDF_Dictionary> annot_dict =
      cpdfsdk_annot->GetPDFAnnot()->GetMutableAnnotDict();
  auto annot_context =
      std::make_unique<CPDF_AnnotContext>(std::move(annot_dict), page);

  *page_index = page_view->GetPageIndex();
  // Caller takes ownership.
  *annot = FPDFAnnotationFromCPDFAnnotContext(annot_context.release());
  return true;
}

FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV
FORM_SetFocusedAnnot(FPDF_FORMHANDLE handle, FPDF_ANNOTATION annot) {
  CPDFSDK_FormFillEnvironment* form_fill_env =
      CPDFSDKFormFillEnvironmentFromFPDFFormHandle(handle);
  if (!form_fill_env)
    return false;

  CPDF_AnnotContext* annot_context = CPDFAnnotContextFromFPDFAnnotation(annot);
  if (!annot_context)
    return false;

  CPDFSDK_PageView* page_view =
      form_fill_env->GetOrCreatePageView(annot_context->GetPage());
  if (!page_view->IsValid())
    return false;

  RetainPtr<CPDF_Dictionary> annot_dict = annot_context->GetMutableAnnotDict();
  ObservedPtr<CPDFSDK_Annot> cpdfsdk_annot(
      page_view->GetAnnotByDict(annot_dict.Get()));
  if (!cpdfsdk_annot)
    return false;

  return form_fill_env->SetFocusAnnot(cpdfsdk_annot);
}

FPDF_EXPORT void FPDF_CALLCONV 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);
}

#if defined(_SKIA_SUPPORT_)
FPDF_EXPORT void FPDF_CALLCONV 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

FPDF_EXPORT void FPDF_CALLCONV
FPDF_SetFormFieldHighlightColor(FPDF_FORMHANDLE hHandle,
                                int fieldType,
                                unsigned long color) {
  CPDFSDK_InteractiveForm* pForm = FormHandleToInteractiveForm(hHandle);
  if (!pForm)
    return;

  absl::optional<FormFieldType> cast_input =
      CPDF_FormField::IntToFormFieldType(fieldType);
  if (!cast_input.has_value())
    return;

  if (cast_input.value() == FormFieldType::kUnknown) {
    pForm->SetAllHighlightColors(static_cast<FX_COLORREF>(color));
  } else {
    pForm->SetHighlightColor(static_cast<FX_COLORREF>(color),
                             cast_input.value());
  }
}

FPDF_EXPORT void FPDF_CALLCONV
FPDF_SetFormFieldHighlightAlpha(FPDF_FORMHANDLE hHandle, unsigned char alpha) {
  if (CPDFSDK_InteractiveForm* pForm = FormHandleToInteractiveForm(hHandle))
    pForm->SetHighlightAlpha(alpha);
}

FPDF_EXPORT void FPDF_CALLCONV
FPDF_RemoveFormFieldHighlight(FPDF_FORMHANDLE hHandle) {
  if (CPDFSDK_InteractiveForm* pForm = FormHandleToInteractiveForm(hHandle))
    pForm->RemoveAllHighLights();
}

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

FPDF_EXPORT void FPDF_CALLCONV FORM_OnBeforeClosePage(FPDF_PAGE page,
                                                      FPDF_FORMHANDLE hHandle) {
  CPDFSDK_FormFillEnvironment* pFormFillEnv =
      CPDFSDKFormFillEnvironmentFromFPDFFormHandle(hHandle);
  if (!pFormFillEnv)
    return;

  IPDF_Page* pPage = IPDFPageFromFPDFPage(page);
  if (!pPage)
    return;

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

FPDF_EXPORT void FPDF_CALLCONV
FORM_DoDocumentJSAction(FPDF_FORMHANDLE hHandle) {
  CPDFSDK_FormFillEnvironment* pFormFillEnv =
      CPDFSDKFormFillEnvironmentFromFPDFFormHandle(hHandle);
  if (pFormFillEnv && pFormFillEnv->IsJSPlatformPresent())
    pFormFillEnv->ProcJavascriptAction();
}

FPDF_EXPORT void FPDF_CALLCONV
FORM_DoDocumentOpenAction(FPDF_FORMHANDLE hHandle) {
  CPDFSDK_FormFillEnvironment* pFormFillEnv =
      CPDFSDKFormFillEnvironmentFromFPDFFormHandle(hHandle);
  if (pFormFillEnv)
    pFormFillEnv->ProcOpenAction();
}

FPDF_EXPORT void FPDF_CALLCONV FORM_DoDocumentAAction(FPDF_FORMHANDLE hHandle,
                                                      int aaType) {
  CPDFSDK_FormFillEnvironment* pFormFillEnv =
      CPDFSDKFormFillEnvironmentFromFPDFFormHandle(hHandle);
  if (!pFormFillEnv)
    return;

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

  CPDF_AAction aa(pDict->GetDictFor(pdfium::form_fields::kAA));
  auto type = static_cast<CPDF_AAction::AActionType>(aaType);
  if (aa.ActionExist(type))
    pFormFillEnv->DoActionDocument(aa.GetAction(type), type);
}

FPDF_EXPORT void FPDF_CALLCONV FORM_DoPageAAction(FPDF_PAGE page,
                                                  FPDF_FORMHANDLE hHandle,
                                                  int aaType) {
  CPDFSDK_FormFillEnvironment* pFormFillEnv =
      CPDFSDKFormFillEnvironmentFromFPDFFormHandle(hHandle);
  if (!pFormFillEnv)
    return;

  IPDF_Page* pPage = IPDFPageFromFPDFPage(page);
  CPDF_Page* pPDFPage = CPDFPageFromFPDFPage(page);
  if (!pPDFPage)
    return;

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

  CPDF_AAction aa(pPDFPage->GetDict()->GetDictFor(pdfium::form_fields::kAA));
  CPDF_AAction::AActionType type = aaType == FPDFPAGE_AACTION_OPEN
                                       ? CPDF_AAction::kOpenPage
                                       : CPDF_AAction::kClosePage;
  if (aa.ActionExist(type))
    pFormFillEnv->DoActionPage(aa.GetAction(type), type);
}

FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV
FORM_SetIndexSelected(FPDF_FORMHANDLE hHandle,
                      FPDF_PAGE page,
                      int index,
                      FPDF_BOOL selected) {
  CPDFSDK_PageView* pPageView = FormHandleToPageView(hHandle, page);
  return pPageView && pPageView->SetIndexSelected(index, selected);
}

FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV
FORM_IsIndexSelected(FPDF_FORMHANDLE hHandle, FPDF_PAGE page, int index) {
  CPDFSDK_PageView* pPageView = FormHandleToPageView(hHandle, page);
  return pPageView && pPageView->IsIndexSelected(index);
}
