// Copyright 2016 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 "fpdfsdk/cpdfsdk_widget.h"

#include <memory>
#include <sstream>
#include <utility>

#include "constants/annotation_common.h"
#include "constants/appearance.h"
#include "core/fpdfapi/parser/cpdf_array.h"
#include "core/fpdfapi/parser/cpdf_dictionary.h"
#include "core/fpdfapi/parser/cpdf_document.h"
#include "core/fpdfapi/parser/cpdf_reference.h"
#include "core/fpdfapi/parser/cpdf_stream.h"
#include "core/fpdfapi/parser/cpdf_string.h"
#include "core/fpdfdoc/cpdf_bafontmap.h"
#include "core/fpdfdoc/cpdf_defaultappearance.h"
#include "core/fpdfdoc/cpdf_formcontrol.h"
#include "core/fpdfdoc/cpdf_formfield.h"
#include "core/fpdfdoc/cpdf_iconfit.h"
#include "core/fpdfdoc/cpdf_interactiveform.h"
#include "core/fxge/cfx_fillrenderoptions.h"
#include "core/fxge/cfx_graphstatedata.h"
#include "core/fxge/cfx_path.h"
#include "core/fxge/cfx_renderdevice.h"
#include "fpdfsdk/cpdfsdk_actionhandler.h"
#include "fpdfsdk/cpdfsdk_appstream.h"
#include "fpdfsdk/cpdfsdk_formfillenvironment.h"
#include "fpdfsdk/cpdfsdk_interactiveform.h"
#include "fpdfsdk/cpdfsdk_pageview.h"
#include "fpdfsdk/formfiller/cffl_fieldaction.h"
#include "fpdfsdk/pwl/cpwl_edit.h"
#include "third_party/base/check.h"
#include "third_party/base/notreached.h"

#ifdef PDF_ENABLE_XFA
#include "fpdfsdk/fpdfxfa/cpdfxfa_context.h"
#include "xfa/fxfa/cxfa_eventparam.h"
#include "xfa/fxfa/cxfa_ffdocview.h"
#include "xfa/fxfa/cxfa_ffwidget.h"
#include "xfa/fxfa/cxfa_ffwidgethandler.h"
#include "xfa/fxfa/parser/cxfa_node.h"
#endif  // PDF_ENABLE_XFA

CPDFSDK_Widget::CPDFSDK_Widget(CPDF_Annot* pAnnot,
                               CPDFSDK_PageView* pPageView,
                               CPDFSDK_InteractiveForm* pInteractiveForm)
    : CPDFSDK_BAAnnot(pAnnot, pPageView),
      m_pInteractiveForm(pInteractiveForm) {}

CPDFSDK_Widget::~CPDFSDK_Widget() = default;

#ifdef PDF_ENABLE_XFA
CXFA_FFWidget* CPDFSDK_Widget::GetMixXFAWidget() const {
  CPDF_Document::Extension* pContext =
      m_pPageView->GetFormFillEnv()->GetDocExtension();
  if (!pContext || !pContext->ContainsExtensionForegroundForm())
    return nullptr;

  CXFA_FFDocView* pDocView =
      static_cast<CPDFXFA_Context*>(pContext)->GetXFADocView();
  if (!pDocView)
    return nullptr;

  WideString sName;
  if (GetFieldType() == FormFieldType::kRadioButton) {
    sName = GetAnnotName();
    if (sName.IsEmpty())
      sName = GetName();
  } else {
    sName = GetName();
  }

  if (sName.IsEmpty())
    return nullptr;

  return pDocView->GetWidgetByName(sName, nullptr);
}

CXFA_FFWidget* CPDFSDK_Widget::GetGroupMixXFAWidget() const {
  CPDF_Document::Extension* pContext =
      m_pPageView->GetFormFillEnv()->GetDocExtension();
  if (!pContext || !pContext->ContainsExtensionForegroundForm())
    return nullptr;

  CXFA_FFDocView* pDocView =
      static_cast<CPDFXFA_Context*>(pContext)->GetXFADocView();
  if (!pDocView)
    return nullptr;

  WideString sName = GetName();
  return !sName.IsEmpty() ? pDocView->GetWidgetByName(sName, nullptr) : nullptr;
}

CXFA_FFWidgetHandler* CPDFSDK_Widget::GetXFAWidgetHandler() const {
  CPDF_Document::Extension* pContext =
      m_pPageView->GetFormFillEnv()->GetDocExtension();
  if (!pContext || !pContext->ContainsExtensionForegroundForm())
    return nullptr;

  CXFA_FFDocView* pDocView =
      static_cast<CPDFXFA_Context*>(pContext)->GetXFADocView();
  return pDocView ? pDocView->GetWidgetHandler() : nullptr;
}

static XFA_EVENTTYPE GetXFAEventType(PDFSDK_XFAAActionType eXFAAAT) {
  XFA_EVENTTYPE eEventType = XFA_EVENT_Unknown;

  switch (eXFAAAT) {
    case PDFSDK_XFA_Click:
      eEventType = XFA_EVENT_Click;
      break;
    case PDFSDK_XFA_Full:
      eEventType = XFA_EVENT_Full;
      break;
    case PDFSDK_XFA_PreOpen:
      eEventType = XFA_EVENT_PreOpen;
      break;
    case PDFSDK_XFA_PostOpen:
      eEventType = XFA_EVENT_PostOpen;
      break;
  }

  return eEventType;
}

static XFA_EVENTTYPE GetXFAEventType(CPDF_AAction::AActionType eAAT,
                                     bool bWillCommit) {
  XFA_EVENTTYPE eEventType = XFA_EVENT_Unknown;

  switch (eAAT) {
    case CPDF_AAction::kCursorEnter:
      eEventType = XFA_EVENT_MouseEnter;
      break;
    case CPDF_AAction::kCursorExit:
      eEventType = XFA_EVENT_MouseExit;
      break;
    case CPDF_AAction::kButtonDown:
      eEventType = XFA_EVENT_MouseDown;
      break;
    case CPDF_AAction::kButtonUp:
      eEventType = XFA_EVENT_MouseUp;
      break;
    case CPDF_AAction::kGetFocus:
      eEventType = XFA_EVENT_Enter;
      break;
    case CPDF_AAction::kLoseFocus:
      eEventType = XFA_EVENT_Exit;
      break;
    case CPDF_AAction::kPageOpen:
    case CPDF_AAction::kPageClose:
    case CPDF_AAction::kPageVisible:
    case CPDF_AAction::kPageInvisible:
      break;
    case CPDF_AAction::kKeyStroke:
      if (!bWillCommit)
        eEventType = XFA_EVENT_Change;
      break;
    case CPDF_AAction::kValidate:
      eEventType = XFA_EVENT_Validate;
      break;
    case CPDF_AAction::kOpenPage:
    case CPDF_AAction::kClosePage:
    case CPDF_AAction::kFormat:
    case CPDF_AAction::kCalculate:
    case CPDF_AAction::kCloseDocument:
    case CPDF_AAction::kSaveDocument:
    case CPDF_AAction::kDocumentSaved:
    case CPDF_AAction::kPrintDocument:
    case CPDF_AAction::kDocumentPrinted:
      break;
    case CPDF_AAction::kDocumentOpen:
    case CPDF_AAction::kNumberOfActions:
      NOTREACHED();
      break;
  }

  return eEventType;
}

bool CPDFSDK_Widget::HasXFAAAction(PDFSDK_XFAAActionType eXFAAAT) const {
  CXFA_FFWidget* pWidget = GetMixXFAWidget();
  if (!pWidget)
    return false;

  CXFA_FFWidgetHandler* pXFAWidgetHandler = GetXFAWidgetHandler();
  if (!pXFAWidgetHandler)
    return false;

  XFA_EVENTTYPE eEventType = GetXFAEventType(eXFAAAT);
  if ((eEventType == XFA_EVENT_Click || eEventType == XFA_EVENT_Change) &&
      GetFieldType() == FormFieldType::kRadioButton) {
    CXFA_FFWidget* hGroupWidget = GetGroupMixXFAWidget();
    if (hGroupWidget &&
        hGroupWidget->HasEventUnderHandler(eEventType, pXFAWidgetHandler)) {
      return true;
    }
  }

  return pWidget->HasEventUnderHandler(eEventType, pXFAWidgetHandler);
}

bool CPDFSDK_Widget::OnXFAAAction(PDFSDK_XFAAActionType eXFAAAT,
                                  CFFL_FieldAction* data,
                                  const CPDFSDK_PageView* pPageView) {
  auto* pContext = static_cast<CPDFXFA_Context*>(
      m_pPageView->GetFormFillEnv()->GetDocExtension());
  if (!pContext)
    return false;

  CXFA_FFWidget* pWidget = GetMixXFAWidget();
  if (!pWidget)
    return false;

  XFA_EVENTTYPE eEventType = GetXFAEventType(eXFAAAT);
  if (eEventType == XFA_EVENT_Unknown)
    return false;

  CXFA_FFWidgetHandler* pXFAWidgetHandler = GetXFAWidgetHandler();
  if (!pXFAWidgetHandler)
    return false;

  CXFA_EventParam param;
  param.m_eType = eEventType;
  param.m_wsChange = data->sChange;
  param.m_iCommitKey = 0;
  param.m_bShift = data->bShift;
  param.m_iSelStart = data->nSelStart;
  param.m_iSelEnd = data->nSelEnd;
  param.m_wsFullText = data->sValue;
  param.m_bKeyDown = data->bKeyDown;
  param.m_bModifier = data->bModifier;
  param.m_wsPrevText = data->sValue;
  if ((eEventType == XFA_EVENT_Click || eEventType == XFA_EVENT_Change) &&
      GetFieldType() == FormFieldType::kRadioButton) {
    CXFA_FFWidget* hGroupWidget = GetGroupMixXFAWidget();
    if (hGroupWidget &&
        !hGroupWidget->ProcessEventUnderHandler(&param, pXFAWidgetHandler)) {
      return false;
    }
  }

  bool ret = pWidget->ProcessEventUnderHandler(&param, pXFAWidgetHandler);
  CXFA_FFDocView* pDocView = pContext->GetXFADocView();
  if (pDocView)
    pDocView->UpdateDocView();

  return ret;
}

void CPDFSDK_Widget::Synchronize(bool bSynchronizeElse) {
  CXFA_FFWidget* hWidget = GetMixXFAWidget();
  if (!hWidget)
    return;

  CXFA_Node* node = hWidget->GetNode();
  if (!node->IsWidgetReady())
    return;

  CPDF_FormField* pFormField = GetFormField();
  switch (GetFieldType()) {
    case FormFieldType::kCheckBox:
    case FormFieldType::kRadioButton: {
      CPDF_FormControl* pFormCtrl = GetFormControl();
      XFA_CheckState eCheckState =
          pFormCtrl->IsChecked() ? XFA_CheckState::kOn : XFA_CheckState::kOff;
      node->SetCheckState(eCheckState);
      break;
    }
    case FormFieldType::kTextField:
      node->SetValue(XFA_ValuePicture::kEdit, pFormField->GetValue());
      break;
    case FormFieldType::kComboBox:
    case FormFieldType::kListBox: {
      node->ClearAllSelections();
      for (int i = 0; i < pFormField->CountSelectedItems(); ++i) {
        int nIndex = pFormField->GetSelectedIndex(i);
        if (nIndex > -1 && nIndex < node->CountChoiceListItems(false))
          node->SetItemState(nIndex, true, false, false, true);
      }
      if (GetFieldType() == FormFieldType::kComboBox)
        node->SetValue(XFA_ValuePicture::kEdit, pFormField->GetValue());
      break;
    }
    default:
      break;
  }

  if (bSynchronizeElse) {
    auto* context = static_cast<CPDFXFA_Context*>(
        m_pPageView->GetFormFillEnv()->GetDocExtension());
    context->GetXFADocView()->ProcessValueChanged(node);
  }
}

bool CPDFSDK_Widget::HandleXFAAAction(
    CPDF_AAction::AActionType type,
    CFFL_FieldAction* data,
    CPDFSDK_FormFillEnvironment* pFormFillEnv) {
  auto* pContext =
      static_cast<CPDFXFA_Context*>(pFormFillEnv->GetDocExtension());
  if (!pContext)
    return false;

  CXFA_FFWidget* hWidget = GetMixXFAWidget();
  if (!hWidget)
    return false;

  XFA_EVENTTYPE eEventType = GetXFAEventType(type, data->bWillCommit);
  if (eEventType == XFA_EVENT_Unknown)
    return false;

  CXFA_FFWidgetHandler* pXFAWidgetHandler = GetXFAWidgetHandler();
  if (!pXFAWidgetHandler)
    return false;

  CXFA_EventParam param;
  param.m_eType = eEventType;
  param.m_wsChange = data->sChange;
  param.m_iCommitKey = 0;
  param.m_bShift = data->bShift;
  param.m_iSelStart = data->nSelStart;
  param.m_iSelEnd = data->nSelEnd;
  param.m_wsFullText = data->sValue;
  param.m_bKeyDown = data->bKeyDown;
  param.m_bModifier = data->bModifier;
  param.m_wsPrevText = data->sValue;
  bool ret = hWidget->ProcessEventUnderHandler(&param, pXFAWidgetHandler);
  CXFA_FFDocView* pDocView = pContext->GetXFADocView();
  if (pDocView)
    pDocView->UpdateDocView();

  return ret;
}
#endif  // PDF_ENABLE_XFA

bool CPDFSDK_Widget::IsWidgetAppearanceValid(CPDF_Annot::AppearanceMode mode) {
  const CPDF_Dictionary* pAP =
      GetAnnotDict()->GetDictFor(pdfium::annotation::kAP);
  if (!pAP)
    return false;

  // Choose the right sub-ap
  const char* ap_entry = "N";
  if (mode == CPDF_Annot::AppearanceMode::kDown)
    ap_entry = "D";
  else if (mode == CPDF_Annot::AppearanceMode::kRollover)
    ap_entry = "R";
  if (!pAP->KeyExist(ap_entry))
    ap_entry = "N";

  // Get the AP stream or subdirectory
  const CPDF_Object* pSub = pAP->GetDirectObjectFor(ap_entry);
  if (!pSub)
    return false;

  FormFieldType fieldType = GetFieldType();
  switch (fieldType) {
    case FormFieldType::kPushButton:
    case FormFieldType::kComboBox:
    case FormFieldType::kListBox:
    case FormFieldType::kTextField:
    case FormFieldType::kSignature:
      return pSub->IsStream();
    case FormFieldType::kCheckBox:
    case FormFieldType::kRadioButton:
      if (const CPDF_Dictionary* pSubDict = pSub->AsDictionary()) {
        return !!pSubDict->GetStreamFor(GetAppState());
      }
      return false;
    default:
      return true;
  }
}

FormFieldType CPDFSDK_Widget::GetFieldType() const {
  CPDF_FormField* pField = GetFormField();
  return pField ? pField->GetFieldType() : FormFieldType::kUnknown;
}

bool CPDFSDK_Widget::IsAppearanceValid() {
#ifdef PDF_ENABLE_XFA
  CPDF_Document::Extension* pContext =
      m_pPageView->GetFormFillEnv()->GetDocExtension();
  if (pContext && pContext->ContainsExtensionFullForm())
    return true;
#endif  // PDF_ENABLE_XFA
  return CPDFSDK_BAAnnot::IsAppearanceValid();
}

int CPDFSDK_Widget::GetLayoutOrder() const {
  return 2;
}

int CPDFSDK_Widget::GetFieldFlags() const {
  return GetFormField()->GetFieldFlags();
}

bool CPDFSDK_Widget::IsSignatureWidget() const {
  return GetFieldType() == FormFieldType::kSignature;
}

CPDF_FormField* CPDFSDK_Widget::GetFormField() const {
  CPDF_FormControl* pControl = GetFormControl();
  return pControl ? pControl->GetField() : nullptr;
}

CPDF_FormControl* CPDFSDK_Widget::GetFormControl() const {
  CPDF_InteractiveForm* pPDFInteractiveForm =
      m_pInteractiveForm->GetInteractiveForm();
  return pPDFInteractiveForm->GetControlByDict(GetAnnotDict());
}

int CPDFSDK_Widget::GetRotate() const {
  CPDF_FormControl* pCtrl = GetFormControl();
  return pCtrl->GetRotation() % 360;
}

#ifdef PDF_ENABLE_XFA
WideString CPDFSDK_Widget::GetName() const {
  return GetFormField()->GetFullName();
}
#endif  // PDF_ENABLE_XFA

Optional<FX_COLORREF> CPDFSDK_Widget::GetFillColor() const {
  CFX_Color::TypeAndARGB type_argb_pair =
      GetFormControl()->GetColorARGB(pdfium::appearance::kBG);

  if (type_argb_pair.color_type == CFX_Color::Type::kTransparent)
    return pdfium::nullopt;

  return ArgbToColorRef(type_argb_pair.argb);
}

Optional<FX_COLORREF> CPDFSDK_Widget::GetBorderColor() const {
  CFX_Color::TypeAndARGB type_argb_pair =
      GetFormControl()->GetColorARGB(pdfium::appearance::kBC);
  if (type_argb_pair.color_type == CFX_Color::Type::kTransparent)
    return pdfium::nullopt;

  return ArgbToColorRef(type_argb_pair.argb);
}

Optional<FX_COLORREF> CPDFSDK_Widget::GetTextColor() const {
  CPDF_DefaultAppearance da = GetFormControl()->GetDefaultAppearance();
  Optional<CFX_Color::TypeAndARGB> maybe_type_argb_pair = da.GetColorARGB();

  if (!maybe_type_argb_pair.has_value())
    return pdfium::nullopt;

  if (maybe_type_argb_pair.value().color_type == CFX_Color::Type::kTransparent)
    return pdfium::nullopt;

  return ArgbToColorRef(maybe_type_argb_pair.value().argb);
}

float CPDFSDK_Widget::GetFontSize() const {
  CPDF_FormControl* pFormCtrl = GetFormControl();
  CPDF_DefaultAppearance pDa = pFormCtrl->GetDefaultAppearance();
  float fFontSize;
  pDa.GetFont(&fFontSize);
  return fFontSize;
}

int CPDFSDK_Widget::GetSelectedIndex(int nIndex) const {
#ifdef PDF_ENABLE_XFA
  if (CXFA_FFWidget* hWidget = GetMixXFAWidget()) {
    CXFA_Node* node = hWidget->GetNode();
    if (node->IsWidgetReady()) {
      if (nIndex < node->CountSelectedItems())
        return node->GetSelectedItem(nIndex);
    }
  }
#endif  // PDF_ENABLE_XFA
  CPDF_FormField* pFormField = GetFormField();
  return pFormField->GetSelectedIndex(nIndex);
}

WideString CPDFSDK_Widget::GetValue() const {
#ifdef PDF_ENABLE_XFA
  if (CXFA_FFWidget* hWidget = GetMixXFAWidget()) {
    CXFA_Node* node = hWidget->GetNode();
    if (node->IsWidgetReady())
      return node->GetValue(XFA_ValuePicture::kDisplay);
  }
#endif  // PDF_ENABLE_XFA
  CPDF_FormField* pFormField = GetFormField();
  return pFormField->GetValue();
}

WideString CPDFSDK_Widget::GetExportValue() const {
  CPDF_FormControl* pFormCtrl = GetFormControl();
  return pFormCtrl->GetExportValue();
}

WideString CPDFSDK_Widget::GetOptionLabel(int nIndex) const {
  CPDF_FormField* pFormField = GetFormField();
  return pFormField->GetOptionLabel(nIndex);
}

int CPDFSDK_Widget::CountOptions() const {
  CPDF_FormField* pFormField = GetFormField();
  return pFormField->CountOptions();
}

bool CPDFSDK_Widget::IsOptionSelected(int nIndex) const {
#ifdef PDF_ENABLE_XFA
  if (CXFA_FFWidget* hWidget = GetMixXFAWidget()) {
    CXFA_Node* node = hWidget->GetNode();
    if (node->IsWidgetReady()) {
      if (nIndex > -1 && nIndex < node->CountChoiceListItems(false))
        return node->GetItemState(nIndex);

      return false;
    }
  }
#endif  // PDF_ENABLE_XFA
  CPDF_FormField* pFormField = GetFormField();
  return pFormField->IsItemSelected(nIndex);
}

int CPDFSDK_Widget::GetTopVisibleIndex() const {
  CPDF_FormField* pFormField = GetFormField();
  return pFormField->GetTopVisibleIndex();
}

bool CPDFSDK_Widget::IsChecked() const {
#ifdef PDF_ENABLE_XFA
  if (CXFA_FFWidget* hWidget = GetMixXFAWidget()) {
    CXFA_Node* node = hWidget->GetNode();
    if (node->IsWidgetReady())
      return node->GetCheckState() == XFA_CheckState::kOn;
  }
#endif  // PDF_ENABLE_XFA
  CPDF_FormControl* pFormCtrl = GetFormControl();
  return pFormCtrl->IsChecked();
}

int CPDFSDK_Widget::GetAlignment() const {
  CPDF_FormControl* pFormCtrl = GetFormControl();
  return pFormCtrl->GetControlAlignment();
}

int CPDFSDK_Widget::GetMaxLen() const {
  CPDF_FormField* pFormField = GetFormField();
  return pFormField->GetMaxLen();
}

void CPDFSDK_Widget::SetCheck(bool bChecked) {
  CPDF_FormControl* pFormCtrl = GetFormControl();
  CPDF_FormField* pFormField = pFormCtrl->GetField();
  pFormField->CheckControl(pFormField->GetControlIndex(pFormCtrl), bChecked,
                           NotificationOption::kDoNotNotify);
#ifdef PDF_ENABLE_XFA
  if (!IsWidgetAppearanceValid(CPDF_Annot::AppearanceMode::kNormal))
    ResetXFAAppearance(CPDFSDK_Widget::kValueChanged);
  Synchronize(true);
#endif  // PDF_ENABLE_XFA
}

void CPDFSDK_Widget::SetValue(const WideString& sValue) {
  CPDF_FormField* pFormField = GetFormField();
  pFormField->SetValue(sValue, NotificationOption::kDoNotNotify);
#ifdef PDF_ENABLE_XFA
  Synchronize(true);
#endif  // PDF_ENABLE_XFA
}

void CPDFSDK_Widget::SetOptionSelection(int index) {
  CPDF_FormField* pFormField = GetFormField();
  pFormField->SetItemSelection(index, NotificationOption::kDoNotNotify);
#ifdef PDF_ENABLE_XFA
  Synchronize(true);
#endif  // PDF_ENABLE_XFA
}

void CPDFSDK_Widget::ClearSelection() {
  CPDF_FormField* pFormField = GetFormField();
  pFormField->ClearSelection(NotificationOption::kDoNotNotify);
#ifdef PDF_ENABLE_XFA
  Synchronize(true);
#endif  // PDF_ENABLE_XFA
}

void CPDFSDK_Widget::SetTopVisibleIndex(int index) {}

void CPDFSDK_Widget::SetAppModified() {
  m_bAppModified = true;
}

void CPDFSDK_Widget::ClearAppModified() {
  m_bAppModified = false;
}

bool CPDFSDK_Widget::IsAppModified() const {
  return m_bAppModified;
}

#ifdef PDF_ENABLE_XFA
void CPDFSDK_Widget::ResetXFAAppearance(ValueChanged bValueChanged) {
  switch (GetFieldType()) {
    case FormFieldType::kTextField:
    case FormFieldType::kComboBox: {
      ResetAppearance(OnFormat(), kValueChanged);
      break;
    }
    default:
      ResetAppearance(pdfium::nullopt, kValueUnchanged);
      break;
  }
}
#endif  // PDF_ENABLE_XFA

void CPDFSDK_Widget::ResetAppearance(Optional<WideString> sValue,
                                     ValueChanged bValueChanged) {
  SetAppModified();

  m_nAppearanceAge++;
  if (bValueChanged == kValueChanged)
    m_nValueAge++;

  CPDFSDK_AppStream appStream(this, GetAPDict());
  switch (GetFieldType()) {
    case FormFieldType::kPushButton:
      appStream.SetAsPushButton();
      break;
    case FormFieldType::kCheckBox:
      appStream.SetAsCheckBox();
      break;
    case FormFieldType::kRadioButton:
      appStream.SetAsRadioButton();
      break;
    case FormFieldType::kComboBox:
      appStream.SetAsComboBox(sValue);
      break;
    case FormFieldType::kListBox:
      appStream.SetAsListBox();
      break;
    case FormFieldType::kTextField:
      appStream.SetAsTextField(sValue);
      break;
    default:
      break;
  }

  m_pAnnot->ClearCachedAP();
}

Optional<WideString> CPDFSDK_Widget::OnFormat() {
  CPDF_FormField* pFormField = GetFormField();
  DCHECK(pFormField);
  return m_pInteractiveForm->OnFormat(pFormField);
}

void CPDFSDK_Widget::ResetFieldAppearance() {
  CPDF_FormField* pFormField = GetFormField();
  DCHECK(pFormField);
  m_pInteractiveForm->ResetFieldAppearance(pFormField, pdfium::nullopt);
}

void CPDFSDK_Widget::DrawAppearance(CFX_RenderDevice* pDevice,
                                    const CFX_Matrix& mtUser2Device,
                                    CPDF_Annot::AppearanceMode mode,
                                    const CPDF_RenderOptions* pOptions) {
  FormFieldType fieldType = GetFieldType();

  if ((fieldType == FormFieldType::kCheckBox ||
       fieldType == FormFieldType::kRadioButton) &&
      mode == CPDF_Annot::AppearanceMode::kNormal &&
      !IsWidgetAppearanceValid(CPDF_Annot::AppearanceMode::kNormal)) {
    CFX_GraphStateData gsd;
    gsd.m_LineWidth = 0.0f;

    CFX_Path path;
    path.AppendFloatRect(GetRect());
    pDevice->DrawPath(&path, &mtUser2Device, &gsd, 0, 0xFFAAAAAA,
                      CFX_FillRenderOptions::EvenOddOptions());
  } else {
    CPDFSDK_BAAnnot::DrawAppearance(pDevice, mtUser2Device, mode, pOptions);
  }
}

void CPDFSDK_Widget::UpdateField() {
  CPDF_FormField* pFormField = GetFormField();
  DCHECK(pFormField);
  m_pInteractiveForm->UpdateField(pFormField);
}

void CPDFSDK_Widget::DrawShadow(CFX_RenderDevice* pDevice,
                                CPDFSDK_PageView* pPageView) {
  FormFieldType fieldType = GetFieldType();
  if (!m_pInteractiveForm->IsNeedHighLight(fieldType))
    return;

  CFX_Matrix page2device = pPageView->GetCurrentMatrix();
  CFX_FloatRect rcDevice = GetRect();
  CFX_PointF tmp =
      page2device.Transform(CFX_PointF(rcDevice.left, rcDevice.bottom));
  rcDevice.left = tmp.x;
  rcDevice.bottom = tmp.y;

  tmp = page2device.Transform(CFX_PointF(rcDevice.right, rcDevice.top));
  rcDevice.right = tmp.x;
  rcDevice.top = tmp.y;
  rcDevice.Normalize();

  pDevice->FillRect(
      rcDevice.ToFxRect(),
      AlphaAndColorRefToArgb(
          static_cast<int>(m_pInteractiveForm->GetHighlightAlpha()),
          m_pInteractiveForm->GetHighlightColor(fieldType)));
}

CFX_FloatRect CPDFSDK_Widget::GetClientRect() const {
  CFX_FloatRect rcWindow = GetRotatedRect();
  float fBorderWidth = GetBorderWidth();
  switch (GetBorderStyle()) {
    case BorderStyle::kBeveled:
    case BorderStyle::kInset:
      fBorderWidth *= 2.0f;
      break;
    default:
      break;
  }
  return rcWindow.GetDeflated(fBorderWidth, fBorderWidth);
}

CFX_FloatRect CPDFSDK_Widget::GetRotatedRect() const {
  CFX_FloatRect rectAnnot = GetRect();
  float fWidth = rectAnnot.Width();
  float fHeight = rectAnnot.Height();

  CPDF_FormControl* pControl = GetFormControl();
  CFX_FloatRect rcPWLWindow;
  switch (abs(pControl->GetRotation() % 360)) {
    case 0:
    case 180:
    default:
      rcPWLWindow = CFX_FloatRect(0, 0, fWidth, fHeight);
      break;
    case 90:
    case 270:
      rcPWLWindow = CFX_FloatRect(0, 0, fHeight, fWidth);
      break;
  }

  return rcPWLWindow;
}

CFX_Matrix CPDFSDK_Widget::GetMatrix() const {
  CFX_Matrix mt;
  CPDF_FormControl* pControl = GetFormControl();
  CFX_FloatRect rcAnnot = GetRect();
  float fWidth = rcAnnot.Width();
  float fHeight = rcAnnot.Height();

  switch (abs(pControl->GetRotation() % 360)) {
    default:
    case 0:
      break;
    case 90:
      mt = CFX_Matrix(0, 1, -1, 0, fWidth, 0);
      break;
    case 180:
      mt = CFX_Matrix(-1, 0, 0, -1, fWidth, fHeight);
      break;
    case 270:
      mt = CFX_Matrix(0, -1, 1, 0, 0, fHeight);
      break;
  }

  return mt;
}

CFX_Color CPDFSDK_Widget::GetTextPWLColor() const {
  CPDF_FormControl* pFormCtrl = GetFormControl();
  Optional<CFX_Color> crText = pFormCtrl->GetDefaultAppearance().GetColor();
  return crText.value_or(CFX_Color(CFX_Color::Type::kGray, 0));
}

CFX_Color CPDFSDK_Widget::GetBorderPWLColor() const {
  CPDF_FormControl* pFormCtrl = GetFormControl();
  return pFormCtrl->GetOriginalBorderColor();
}

CFX_Color CPDFSDK_Widget::GetFillPWLColor() const {
  CPDF_FormControl* pFormCtrl = GetFormControl();
  return pFormCtrl->GetOriginalBackgroundColor();
}

bool CPDFSDK_Widget::OnAAction(CPDF_AAction::AActionType type,
                               CFFL_FieldAction* data,
                               const CPDFSDK_PageView* pPageView) {
  CPDFSDK_FormFillEnvironment* pFormFillEnv = pPageView->GetFormFillEnv();

#ifdef PDF_ENABLE_XFA
  if (HandleXFAAAction(type, data, pFormFillEnv))
    return true;
#endif  // PDF_ENABLE_XFA

  CPDF_Action action = GetAAction(type);
  if (action.GetType() != CPDF_Action::Type::kUnknown) {
    pFormFillEnv->GetActionHandler()->DoAction_Field(action, type, pFormFillEnv,
                                                     GetFormField(), data);
  }
  return false;
}

CPDF_Action CPDFSDK_Widget::GetAAction(CPDF_AAction::AActionType eAAT) {
  switch (eAAT) {
    case CPDF_AAction::kCursorEnter:
    case CPDF_AAction::kCursorExit:
    case CPDF_AAction::kButtonDown:
    case CPDF_AAction::kButtonUp:
    case CPDF_AAction::kGetFocus:
    case CPDF_AAction::kLoseFocus:
    case CPDF_AAction::kPageOpen:
    case CPDF_AAction::kPageClose:
    case CPDF_AAction::kPageVisible:
    case CPDF_AAction::kPageInvisible:
      return CPDFSDK_BAAnnot::GetAAction(eAAT);

    case CPDF_AAction::kKeyStroke:
    case CPDF_AAction::kFormat:
    case CPDF_AAction::kValidate:
    case CPDF_AAction::kCalculate: {
      CPDF_FormField* pField = GetFormField();
      if (pField->GetAdditionalAction().GetDict())
        return pField->GetAdditionalAction().GetAction(eAAT);
      return CPDFSDK_BAAnnot::GetAAction(eAAT);
    }
    default:
      break;
  }

  return CPDF_Action(nullptr);
}
