// 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 "fpdfsdk/javascript/Field.h"

#include <algorithm>
#include <memory>
#include <string>
#include <vector>

#include "core/fpdfapi/font/cpdf_font.h"
#include "core/fpdfapi/page/cpdf_page.h"
#include "core/fpdfapi/parser/cpdf_document.h"
#include "core/fpdfdoc/cpdf_interform.h"
#include "fpdfsdk/cpdfsdk_formfillenvironment.h"
#include "fpdfsdk/cpdfsdk_interform.h"
#include "fpdfsdk/cpdfsdk_pageview.h"
#include "fpdfsdk/cpdfsdk_widget.h"
#include "fpdfsdk/javascript/Document.h"
#include "fpdfsdk/javascript/Icon.h"
#include "fpdfsdk/javascript/JS_Define.h"
#include "fpdfsdk/javascript/JS_Object.h"
#include "fpdfsdk/javascript/JS_Value.h"
#include "fpdfsdk/javascript/PublicMethods.h"
#include "fpdfsdk/javascript/cjs_event_context.h"
#include "fpdfsdk/javascript/cjs_eventhandler.h"
#include "fpdfsdk/javascript/cjs_runtime.h"
#include "fpdfsdk/javascript/color.h"

namespace {

bool SetWidgetDisplayStatus(CPDFSDK_Widget* pWidget, int value) {
  if (!pWidget)
    return false;

  uint32_t dwFlag = pWidget->GetFlags();
  switch (value) {
    case 0:
      dwFlag &= ~ANNOTFLAG_INVISIBLE;
      dwFlag &= ~ANNOTFLAG_HIDDEN;
      dwFlag &= ~ANNOTFLAG_NOVIEW;
      dwFlag |= ANNOTFLAG_PRINT;
      break;
    case 1:
      dwFlag &= ~ANNOTFLAG_INVISIBLE;
      dwFlag &= ~ANNOTFLAG_NOVIEW;
      dwFlag |= (ANNOTFLAG_HIDDEN | ANNOTFLAG_PRINT);
      break;
    case 2:
      dwFlag &= ~ANNOTFLAG_INVISIBLE;
      dwFlag &= ~ANNOTFLAG_PRINT;
      dwFlag &= ~ANNOTFLAG_HIDDEN;
      dwFlag &= ~ANNOTFLAG_NOVIEW;
      break;
    case 3:
      dwFlag |= ANNOTFLAG_NOVIEW;
      dwFlag |= ANNOTFLAG_PRINT;
      dwFlag &= ~ANNOTFLAG_HIDDEN;
      break;
  }

  if (dwFlag != pWidget->GetFlags()) {
    pWidget->SetFlags(dwFlag);
    return true;
  }

  return false;
}

}  // namespace

JSPropertySpec CJS_Field::PropertySpecs[] = {
    {"alignment", get_alignment_static, set_alignment_static},
    {"borderStyle", get_border_style_static, set_border_style_static},
    {"buttonAlignX", get_button_align_x_static, set_button_align_x_static},
    {"buttonAlignY", get_button_align_y_static, set_button_align_y_static},
    {"buttonFitBounds", get_button_fit_bounds_static,
     set_button_fit_bounds_static},
    {"buttonPosition", get_button_position_static, set_button_position_static},
    {"buttonScaleHow", get_button_scale_how_static,
     set_button_scale_how_static},
    {"buttonScaleWhen", get_button_scale_when_static,
     set_button_scale_when_static},
    {"calcOrderIndex", get_calc_order_index_static,
     set_calc_order_index_static},
    {"charLimit", get_char_limit_static, set_char_limit_static},
    {"comb", get_comb_static, set_comb_static},
    {"commitOnSelChange", get_commit_on_sel_change_static,
     set_commit_on_sel_change_static},
    {"currentValueIndices", get_current_value_indices_static,
     set_current_value_indices_static},
    {"defaultStyle", get_default_style_static, set_default_style_static},
    {"defaultValue", get_default_value_static, set_default_value_static},
    {"doNotScroll", get_do_not_scroll_static, set_do_not_scroll_static},
    {"doNotSpellCheck", get_do_not_spell_check_static,
     set_do_not_spell_check_static},
    {"delay", get_delay_static, set_delay_static},
    {"display", get_display_static, set_display_static},
    {"doc", get_doc_static, set_doc_static},
    {"editable", get_editable_static, set_editable_static},
    {"exportValues", get_export_values_static, set_export_values_static},
    {"hidden", get_hidden_static, set_hidden_static},
    {"fileSelect", get_file_select_static, set_file_select_static},
    {"fillColor", get_fill_color_static, set_fill_color_static},
    {"lineWidth", get_line_width_static, set_line_width_static},
    {"highlight", get_highlight_static, set_highlight_static},
    {"multiline", get_multiline_static, set_multiline_static},
    {"multipleSelection", get_multiple_selection_static,
     set_multiple_selection_static},
    {"name", get_name_static, set_name_static},
    {"numItems", get_num_items_static, set_num_items_static},
    {"page", get_page_static, set_page_static},
    {"password", get_password_static, set_password_static},
    {"print", get_print_static, set_print_static},
    {"radiosInUnison", get_radios_in_unison_static,
     set_radios_in_unison_static},
    {"readonly", get_readonly_static, set_readonly_static},
    {"rect", get_rect_static, set_rect_static},
    {"required", get_required_static, set_required_static},
    {"richText", get_rich_text_static, set_rich_text_static},
    {"richValue", get_rich_value_static, set_rich_value_static},
    {"rotation", get_rotation_static, set_rotation_static},
    {"strokeColor", get_stroke_color_static, set_stroke_color_static},
    {"style", get_style_static, set_style_static},
    {"submitName", get_submit_name_static, set_submit_name_static},
    {"textColor", get_text_color_static, set_text_color_static},
    {"textFont", get_text_font_static, set_text_font_static},
    {"textSize", get_text_size_static, set_text_size_static},
    {"type", get_type_static, set_type_static},
    {"userName", get_user_name_static, set_user_name_static},
    {"value", get_value_static, set_value_static},
    {"valueAsString", get_value_as_string_static, set_value_as_string_static},
    {"source", get_source_static, set_source_static},
    {0, 0, 0}};

JSMethodSpec CJS_Field::MethodSpecs[] = {
    {"browseForFileToSubmit", browseForFileToSubmit_static},
    {"buttonGetCaption", buttonGetCaption_static},
    {"buttonGetIcon", buttonGetIcon_static},
    {"buttonImportIcon", buttonImportIcon_static},
    {"buttonSetCaption", buttonSetCaption_static},
    {"buttonSetIcon", buttonSetIcon_static},
    {"checkThisBox", checkThisBox_static},
    {"clearItems", clearItems_static},
    {"defaultIsChecked", defaultIsChecked_static},
    {"deleteItemAt", deleteItemAt_static},
    {"getArray", getArray_static},
    {"getItemAt", getItemAt_static},
    {"getLock", getLock_static},
    {"insertItemAt", insertItemAt_static},
    {"isBoxChecked", isBoxChecked_static},
    {"isDefaultChecked", isDefaultChecked_static},
    {"setAction", setAction_static},
    {"setFocus", setFocus_static},
    {"setItems", setItems_static},
    {"setLock", setLock_static},
    {"signatureGetModifications", signatureGetModifications_static},
    {"signatureGetSeedValue", signatureGetSeedValue_static},
    {"signatureInfo", signatureInfo_static},
    {"signatureSetSeedValue", signatureSetSeedValue_static},
    {"signatureSign", signatureSign_static},
    {"signatureValidate", signatureValidate_static},
    {0, 0}};

int CJS_Field::g_nObjDefnID = -1;

void CJS_Field::DefineJSObjects(CFXJS_Engine* pEngine, FXJSOBJTYPE eObjType) {
  g_nObjDefnID =
      pEngine->DefineObj("Field", eObjType, JSConstructor<CJS_Field, Field>,
                         JSDestructor<CJS_Field>);
  DefineProps(pEngine, g_nObjDefnID, PropertySpecs);
  DefineMethods(pEngine, g_nObjDefnID, MethodSpecs);
}

CJS_DelayData::CJS_DelayData(FIELD_PROP prop, int idx, const WideString& name)
    : eProp(prop), nControlIndex(idx), sFieldName(name) {}

CJS_DelayData::~CJS_DelayData() {}

void CJS_Field::InitInstance(IJS_Runtime* pIRuntime) {}

Field::Field(CJS_Object* pJSObject)
    : CJS_EmbedObj(pJSObject),
      m_pJSDoc(nullptr),
      m_pFormFillEnv(nullptr),
      m_nFormControlIndex(-1),
      m_bCanSet(false),
      m_bDelay(false) {}

Field::~Field() {}

// note: iControlNo = -1, means not a widget.
void Field::ParseFieldName(const std::wstring& strFieldNameParsed,
                           std::wstring& strFieldName,
                           int& iControlNo) {
  int iStart = strFieldNameParsed.find_last_of(L'.');
  if (iStart == -1) {
    strFieldName = strFieldNameParsed;
    iControlNo = -1;
    return;
  }
  std::wstring suffixal = strFieldNameParsed.substr(iStart + 1);
  iControlNo = FXSYS_wtoi(suffixal.c_str());
  if (iControlNo == 0) {
    int iSpaceStart;
    while ((iSpaceStart = suffixal.find_last_of(L" ")) != -1) {
      suffixal.erase(iSpaceStart, 1);
    }

    if (suffixal.compare(L"0") != 0) {
      strFieldName = strFieldNameParsed;
      iControlNo = -1;
      return;
    }
  }
  strFieldName = strFieldNameParsed.substr(0, iStart);
}

bool Field::AttachField(Document* pDocument, const WideString& csFieldName) {
  m_pJSDoc = pDocument;
  m_pFormFillEnv.Reset(pDocument->GetFormFillEnv());
  m_bCanSet = m_pFormFillEnv->GetPermissions(FPDFPERM_FILL_FORM) ||
              m_pFormFillEnv->GetPermissions(FPDFPERM_ANNOT_FORM) ||
              m_pFormFillEnv->GetPermissions(FPDFPERM_MODIFY);

  CPDFSDK_InterForm* pRDInterForm = m_pFormFillEnv->GetInterForm();
  CPDF_InterForm* pInterForm = pRDInterForm->GetInterForm();
  WideString swFieldNameTemp = csFieldName;
  swFieldNameTemp.Replace(L"..", L".");

  if (pInterForm->CountFields(swFieldNameTemp) <= 0) {
    std::wstring strFieldName;
    int iControlNo = -1;
    ParseFieldName(swFieldNameTemp.c_str(), strFieldName, iControlNo);
    if (iControlNo == -1)
      return false;

    m_FieldName = strFieldName.c_str();
    m_nFormControlIndex = iControlNo;
    return true;
  }

  m_FieldName = swFieldNameTemp;
  m_nFormControlIndex = -1;

  return true;
}

std::vector<CPDF_FormField*> Field::GetFormFields(
    CPDFSDK_FormFillEnvironment* pFormFillEnv,
    const WideString& csFieldName) {
  std::vector<CPDF_FormField*> fields;
  CPDFSDK_InterForm* pReaderInterForm = pFormFillEnv->GetInterForm();
  CPDF_InterForm* pInterForm = pReaderInterForm->GetInterForm();
  for (int i = 0, sz = pInterForm->CountFields(csFieldName); i < sz; ++i) {
    if (CPDF_FormField* pFormField = pInterForm->GetField(i, csFieldName))
      fields.push_back(pFormField);
  }
  return fields;
}

std::vector<CPDF_FormField*> Field::GetFormFields(
    const WideString& csFieldName) const {
  return Field::GetFormFields(m_pFormFillEnv.Get(), csFieldName);
}

void Field::UpdateFormField(CPDFSDK_FormFillEnvironment* pFormFillEnv,
                            CPDF_FormField* pFormField,
                            bool bChangeMark,
                            bool bResetAP,
                            bool bRefresh) {
  CPDFSDK_InterForm* pInterForm = pFormFillEnv->GetInterForm();

  if (bResetAP) {
    std::vector<CPDFSDK_Annot::ObservedPtr> widgets;
    pInterForm->GetWidgets(pFormField, &widgets);

    int nFieldType = pFormField->GetFieldType();
    if (nFieldType == FIELDTYPE_COMBOBOX || nFieldType == FIELDTYPE_TEXTFIELD) {
      for (auto& pObserved : widgets) {
        if (pObserved) {
          bool bFormatted = false;
          WideString sValue = static_cast<CPDFSDK_Widget*>(pObserved.Get())
                                  ->OnFormat(bFormatted);
          if (pObserved) {  // Not redundant, may be clobbered by OnFormat.
            static_cast<CPDFSDK_Widget*>(pObserved.Get())
                ->ResetAppearance(bFormatted ? &sValue : nullptr, false);
          }
        }
      }
    } else {
      for (auto& pObserved : widgets) {
        if (pObserved) {
          static_cast<CPDFSDK_Widget*>(pObserved.Get())
              ->ResetAppearance(nullptr, false);
        }
      }
    }
  }

  if (bRefresh) {
    // Refresh the widget list. The calls in |bResetAP| may have caused widgets
    // to be removed from the list. We need to call |GetWidgets| again to be
    // sure none of the widgets have been deleted.
    std::vector<CPDFSDK_Annot::ObservedPtr> widgets;
    pInterForm->GetWidgets(pFormField, &widgets);

    // TODO(dsinclair): Determine if all widgets share the same
    // CPDFSDK_InterForm. If that's the case, we can move the code to
    // |GetFormFillEnv| out of the loop.
    for (auto& pObserved : widgets) {
      if (pObserved) {
        CPDFSDK_Widget* pWidget = static_cast<CPDFSDK_Widget*>(pObserved.Get());
        pWidget->GetInterForm()->GetFormFillEnv()->UpdateAllViews(nullptr,
                                                                  pWidget);
      }
    }
  }

  if (bChangeMark)
    pFormFillEnv->SetChangeMark();
}

void Field::UpdateFormControl(CPDFSDK_FormFillEnvironment* pFormFillEnv,
                              CPDF_FormControl* pFormControl,
                              bool bChangeMark,
                              bool bResetAP,
                              bool bRefresh) {
  ASSERT(pFormControl);

  CPDFSDK_InterForm* pForm = pFormFillEnv->GetInterForm();
  CPDFSDK_Widget* pWidget = pForm->GetWidget(pFormControl);

  if (pWidget) {
    CPDFSDK_Widget::ObservedPtr observed_widget(pWidget);
    if (bResetAP) {
      int nFieldType = pWidget->GetFieldType();
      if (nFieldType == FIELDTYPE_COMBOBOX ||
          nFieldType == FIELDTYPE_TEXTFIELD) {
        bool bFormatted = false;
        WideString sValue = pWidget->OnFormat(bFormatted);
        if (!observed_widget)
          return;
        pWidget->ResetAppearance(bFormatted ? &sValue : nullptr, false);
      } else {
        pWidget->ResetAppearance(nullptr, false);
      }
      if (!observed_widget)
        return;
    }

    if (bRefresh) {
      CPDFSDK_InterForm* pInterForm = pWidget->GetInterForm();
      pInterForm->GetFormFillEnv()->UpdateAllViews(nullptr, pWidget);
    }
  }

  if (bChangeMark)
    pFormFillEnv->SetChangeMark();
}

CPDFSDK_Widget* Field::GetWidget(CPDFSDK_FormFillEnvironment* pFormFillEnv,
                                 CPDF_FormControl* pFormControl) {
  CPDFSDK_InterForm* pInterForm =
      static_cast<CPDFSDK_InterForm*>(pFormFillEnv->GetInterForm());
  return pInterForm ? pInterForm->GetWidget(pFormControl) : nullptr;
}

bool Field::ValueIsOccur(CPDF_FormField* pFormField, WideString csOptLabel) {
  for (int i = 0, sz = pFormField->CountOptions(); i < sz; i++) {
    if (csOptLabel.Compare(pFormField->GetOptionLabel(i)) == 0)
      return true;
  }

  return false;
}

CPDF_FormControl* Field::GetSmartFieldControl(CPDF_FormField* pFormField) {
  if (!pFormField->CountControls() ||
      m_nFormControlIndex >= pFormField->CountControls())
    return nullptr;
  if (m_nFormControlIndex < 0)
    return pFormField->GetControl(0);
  return pFormField->GetControl(m_nFormControlIndex);
}

CJS_Return Field::get_alignment(CJS_Runtime* pRuntime) {
  ASSERT(m_pFormFillEnv);

  std::vector<CPDF_FormField*> FieldArray = GetFormFields(m_FieldName);
  if (FieldArray.empty())
    return CJS_Return(false);

  CPDF_FormField* pFormField = FieldArray[0];
  if (pFormField->GetFieldType() != FIELDTYPE_TEXTFIELD)
    return CJS_Return(false);

  CPDF_FormControl* pFormControl = GetSmartFieldControl(pFormField);
  if (!pFormControl)
    return CJS_Return(false);

  switch (pFormControl->GetControlAlignment()) {
    case 0:
      return CJS_Return(pRuntime->NewString(L"left"));
    case 1:
      return CJS_Return(pRuntime->NewString(L"center"));
    case 2:
      return CJS_Return(pRuntime->NewString(L"right"));
  }
  return CJS_Return(pRuntime->NewString(L""));
}

CJS_Return Field::set_alignment(CJS_Runtime* pRuntime,
                                v8::Local<v8::Value> vp) {
  ASSERT(m_pFormFillEnv);
  return CJS_Return(m_bCanSet);
}

CJS_Return Field::get_border_style(CJS_Runtime* pRuntime) {
  ASSERT(m_pFormFillEnv);

  std::vector<CPDF_FormField*> FieldArray = GetFormFields(m_FieldName);
  if (FieldArray.empty())
    return CJS_Return(false);

  CPDF_FormField* pFormField = FieldArray[0];
  if (!pFormField)
    return CJS_Return(false);

  CPDFSDK_Widget* pWidget =
      GetWidget(m_pFormFillEnv.Get(), GetSmartFieldControl(pFormField));
  if (!pWidget)
    return CJS_Return(false);

  switch (pWidget->GetBorderStyle()) {
    case BorderStyle::SOLID:
      return CJS_Return(pRuntime->NewString(L"solid"));
    case BorderStyle::DASH:
      return CJS_Return(pRuntime->NewString(L"dashed"));
    case BorderStyle::BEVELED:
      return CJS_Return(pRuntime->NewString(L"beveled"));
    case BorderStyle::INSET:
      return CJS_Return(pRuntime->NewString(L"inset"));
    case BorderStyle::UNDERLINE:
      return CJS_Return(pRuntime->NewString(L"underline"));
  }
  return CJS_Return(pRuntime->NewString(L""));
}

CJS_Return Field::set_border_style(CJS_Runtime* pRuntime,
                                   v8::Local<v8::Value> vp) {
  ASSERT(m_pFormFillEnv);

  if (!m_bCanSet)
    return CJS_Return(false);

  ByteString byte_str = ByteString::FromUnicode(pRuntime->ToWideString(vp));
  if (m_bDelay) {
    AddDelay_String(FP_BORDERSTYLE, byte_str);
  } else {
    Field::SetBorderStyle(m_pFormFillEnv.Get(), m_FieldName,
                          m_nFormControlIndex, byte_str);
  }
  return CJS_Return(true);
}

void Field::SetBorderStyle(CPDFSDK_FormFillEnvironment* pFormFillEnv,
                           const WideString& swFieldName,
                           int nControlIndex,
                           const ByteString& string) {
  ASSERT(pFormFillEnv);

  BorderStyle nBorderStyle = BorderStyle::SOLID;
  if (string == "solid")
    nBorderStyle = BorderStyle::SOLID;
  else if (string == "beveled")
    nBorderStyle = BorderStyle::BEVELED;
  else if (string == "dashed")
    nBorderStyle = BorderStyle::DASH;
  else if (string == "inset")
    nBorderStyle = BorderStyle::INSET;
  else if (string == "underline")
    nBorderStyle = BorderStyle::UNDERLINE;
  else
    return;

  std::vector<CPDF_FormField*> FieldArray =
      GetFormFields(pFormFillEnv, swFieldName);
  for (CPDF_FormField* pFormField : FieldArray) {
    if (nControlIndex < 0) {
      bool bSet = false;
      for (int i = 0, sz = pFormField->CountControls(); i < sz; ++i) {
        if (CPDFSDK_Widget* pWidget =
                GetWidget(pFormFillEnv, pFormField->GetControl(i))) {
          if (pWidget->GetBorderStyle() != nBorderStyle) {
            pWidget->SetBorderStyle(nBorderStyle);
            bSet = true;
          }
        }
      }
      if (bSet)
        UpdateFormField(pFormFillEnv, pFormField, true, true, true);
    } else {
      if (nControlIndex >= pFormField->CountControls())
        return;
      if (CPDF_FormControl* pFormControl =
              pFormField->GetControl(nControlIndex)) {
        if (CPDFSDK_Widget* pWidget = GetWidget(pFormFillEnv, pFormControl)) {
          if (pWidget->GetBorderStyle() != nBorderStyle) {
            pWidget->SetBorderStyle(nBorderStyle);
            UpdateFormControl(pFormFillEnv, pFormControl, true, true, true);
          }
        }
      }
    }
  }
}

CJS_Return Field::get_button_align_x(CJS_Runtime* pRuntime) {
  ASSERT(m_pFormFillEnv);

  std::vector<CPDF_FormField*> FieldArray = GetFormFields(m_FieldName);
  if (FieldArray.empty())
    return CJS_Return(false);

  CPDF_FormField* pFormField = FieldArray[0];
  if (pFormField->GetFieldType() != FIELDTYPE_PUSHBUTTON)
    return CJS_Return(false);

  CPDF_FormControl* pFormControl = GetSmartFieldControl(pFormField);
  if (!pFormControl)
    return CJS_Return(false);

  CPDF_IconFit IconFit = pFormControl->GetIconFit();

  float fLeft;
  float fBottom;
  IconFit.GetIconPosition(fLeft, fBottom);

  return CJS_Return(pRuntime->NewNumber(static_cast<int32_t>(fLeft)));
}

CJS_Return Field::set_button_align_x(CJS_Runtime* pRuntime,
                                     v8::Local<v8::Value> vp) {
  ASSERT(m_pFormFillEnv);
  return CJS_Return(m_bCanSet);
}

CJS_Return Field::get_button_align_y(CJS_Runtime* pRuntime) {
  ASSERT(m_pFormFillEnv);

  std::vector<CPDF_FormField*> FieldArray = GetFormFields(m_FieldName);
  if (FieldArray.empty())
    return CJS_Return(false);

  CPDF_FormField* pFormField = FieldArray[0];
  if (pFormField->GetFieldType() != FIELDTYPE_PUSHBUTTON)
    return CJS_Return(false);

  CPDF_FormControl* pFormControl = GetSmartFieldControl(pFormField);
  if (!pFormControl)
    return CJS_Return(false);

  CPDF_IconFit IconFit = pFormControl->GetIconFit();

  float fLeft;
  float fBottom;
  IconFit.GetIconPosition(fLeft, fBottom);

  return CJS_Return(pRuntime->NewNumber(static_cast<int32_t>(fBottom)));
}

CJS_Return Field::set_button_align_y(CJS_Runtime* pRuntime,
                                     v8::Local<v8::Value> vp) {
  ASSERT(m_pFormFillEnv);
  return CJS_Return(m_bCanSet);
}

CJS_Return Field::get_button_fit_bounds(CJS_Runtime* pRuntime) {
  ASSERT(m_pFormFillEnv);

  std::vector<CPDF_FormField*> FieldArray = GetFormFields(m_FieldName);
  if (FieldArray.empty())
    return CJS_Return(false);

  CPDF_FormField* pFormField = FieldArray[0];
  if (pFormField->GetFieldType() != FIELDTYPE_PUSHBUTTON)
    return CJS_Return(false);

  CPDF_FormControl* pFormControl = GetSmartFieldControl(pFormField);
  if (!pFormControl)
    return CJS_Return(false);

  return CJS_Return(
      pRuntime->NewBoolean(pFormControl->GetIconFit().GetFittingBounds()));
}

CJS_Return Field::set_button_fit_bounds(CJS_Runtime* pRuntime,
                                        v8::Local<v8::Value> vp) {
  ASSERT(m_pFormFillEnv);
  return CJS_Return(m_bCanSet);
}

CJS_Return Field::get_button_position(CJS_Runtime* pRuntime) {
  ASSERT(m_pFormFillEnv);

  std::vector<CPDF_FormField*> FieldArray = GetFormFields(m_FieldName);
  if (FieldArray.empty())
    return CJS_Return(false);

  CPDF_FormField* pFormField = FieldArray[0];
  if (pFormField->GetFieldType() != FIELDTYPE_PUSHBUTTON)
    return CJS_Return(false);

  CPDF_FormControl* pFormControl = GetSmartFieldControl(pFormField);
  if (!pFormControl)
    return CJS_Return(false);

  return CJS_Return(pRuntime->NewNumber(pFormControl->GetTextPosition()));
}

CJS_Return Field::set_button_position(CJS_Runtime* pRuntime,
                                      v8::Local<v8::Value> vp) {
  ASSERT(m_pFormFillEnv);
  return CJS_Return(m_bCanSet);
}

CJS_Return Field::get_button_scale_how(CJS_Runtime* pRuntime) {
  ASSERT(m_pFormFillEnv);

  std::vector<CPDF_FormField*> FieldArray = GetFormFields(m_FieldName);
  if (FieldArray.empty())
    return CJS_Return(false);

  CPDF_FormField* pFormField = FieldArray[0];
  if (pFormField->GetFieldType() != FIELDTYPE_PUSHBUTTON)
    return CJS_Return(false);

  CPDF_FormControl* pFormControl = GetSmartFieldControl(pFormField);
  if (!pFormControl)
    return CJS_Return(false);

  return CJS_Return(pRuntime->NewBoolean(
      pFormControl->GetIconFit().IsProportionalScale() ? 0 : 1));
}

CJS_Return Field::set_button_scale_how(CJS_Runtime* pRuntime,
                                       v8::Local<v8::Value> vp) {
  ASSERT(m_pFormFillEnv);
  return CJS_Return(m_bCanSet);
}

CJS_Return Field::get_button_scale_when(CJS_Runtime* pRuntime) {
  ASSERT(m_pFormFillEnv);

  std::vector<CPDF_FormField*> FieldArray = GetFormFields(m_FieldName);
  if (FieldArray.empty())
    return CJS_Return(false);

  CPDF_FormField* pFormField = FieldArray[0];
  if (pFormField->GetFieldType() != FIELDTYPE_PUSHBUTTON)
    return CJS_Return(false);

  CPDF_FormControl* pFormControl = GetSmartFieldControl(pFormField);
  if (!pFormControl)
    return CJS_Return(false);

  CPDF_IconFit IconFit = pFormControl->GetIconFit();
  int ScaleM = IconFit.GetScaleMethod();
  switch (ScaleM) {
    case CPDF_IconFit::Always:
      return CJS_Return(
          pRuntime->NewNumber(static_cast<int32_t>(CPDF_IconFit::Always)));
    case CPDF_IconFit::Bigger:
      return CJS_Return(
          pRuntime->NewNumber(static_cast<int32_t>(CPDF_IconFit::Bigger)));
    case CPDF_IconFit::Never:
      return CJS_Return(
          pRuntime->NewNumber(static_cast<int32_t>(CPDF_IconFit::Never)));
    case CPDF_IconFit::Smaller:
      return CJS_Return(
          pRuntime->NewNumber(static_cast<int32_t>(CPDF_IconFit::Smaller)));
  }
  return CJS_Return(true);
}

CJS_Return Field::set_button_scale_when(CJS_Runtime* pRuntime,
                                        v8::Local<v8::Value> vp) {
  ASSERT(m_pFormFillEnv);
  return CJS_Return(m_bCanSet);
}

CJS_Return Field::get_calc_order_index(CJS_Runtime* pRuntime) {
  ASSERT(m_pFormFillEnv);

  std::vector<CPDF_FormField*> FieldArray = GetFormFields(m_FieldName);
  if (FieldArray.empty())
    return CJS_Return(false);

  CPDF_FormField* pFormField = FieldArray[0];
  if (pFormField->GetFieldType() != FIELDTYPE_COMBOBOX &&
      pFormField->GetFieldType() != FIELDTYPE_TEXTFIELD) {
    return CJS_Return(false);
  }

  CPDFSDK_InterForm* pRDInterForm = m_pFormFillEnv->GetInterForm();
  CPDF_InterForm* pInterForm = pRDInterForm->GetInterForm();
  return CJS_Return(pRuntime->NewNumber(static_cast<int32_t>(
      pInterForm->FindFieldInCalculationOrder(pFormField))));
}

CJS_Return Field::set_calc_order_index(CJS_Runtime* pRuntime,
                                       v8::Local<v8::Value> vp) {
  ASSERT(m_pFormFillEnv);
  return CJS_Return(m_bCanSet);
}

CJS_Return Field::get_char_limit(CJS_Runtime* pRuntime) {
  ASSERT(m_pFormFillEnv);

  std::vector<CPDF_FormField*> FieldArray = GetFormFields(m_FieldName);
  if (FieldArray.empty())
    return CJS_Return(false);

  CPDF_FormField* pFormField = FieldArray[0];
  if (pFormField->GetFieldType() != FIELDTYPE_TEXTFIELD)
    return CJS_Return(false);
  return CJS_Return(
      pRuntime->NewNumber(static_cast<int32_t>(pFormField->GetMaxLen())));
}

CJS_Return Field::set_char_limit(CJS_Runtime* pRuntime,
                                 v8::Local<v8::Value> vp) {
  ASSERT(m_pFormFillEnv);
  return CJS_Return(m_bCanSet);
}

CJS_Return Field::get_comb(CJS_Runtime* pRuntime) {
  ASSERT(m_pFormFillEnv);

  std::vector<CPDF_FormField*> FieldArray = GetFormFields(m_FieldName);
  if (FieldArray.empty())
    return CJS_Return(false);

  CPDF_FormField* pFormField = FieldArray[0];
  if (pFormField->GetFieldType() != FIELDTYPE_TEXTFIELD)
    return CJS_Return(false);

  return CJS_Return(
      pRuntime->NewBoolean(!!(pFormField->GetFieldFlags() & FIELDFLAG_COMB)));
}

CJS_Return Field::set_comb(CJS_Runtime* pRuntime, v8::Local<v8::Value> vp) {
  ASSERT(m_pFormFillEnv);
  return CJS_Return(m_bCanSet);
}

CJS_Return Field::get_commit_on_sel_change(CJS_Runtime* pRuntime) {
  ASSERT(m_pFormFillEnv);

  std::vector<CPDF_FormField*> FieldArray = GetFormFields(m_FieldName);
  if (FieldArray.empty())
    return CJS_Return(false);

  CPDF_FormField* pFormField = FieldArray[0];
  if (pFormField->GetFieldType() != FIELDTYPE_COMBOBOX &&
      pFormField->GetFieldType() != FIELDTYPE_LISTBOX) {
    return CJS_Return(false);
  }

  return CJS_Return(pRuntime->NewBoolean(
      !!(pFormField->GetFieldFlags() & FIELDFLAG_COMMITONSELCHANGE)));
}

CJS_Return Field::set_commit_on_sel_change(CJS_Runtime* pRuntime,
                                           v8::Local<v8::Value> vp) {
  ASSERT(m_pFormFillEnv);
  return CJS_Return(m_bCanSet);
}

CJS_Return Field::get_current_value_indices(CJS_Runtime* pRuntime) {
  std::vector<CPDF_FormField*> FieldArray = GetFormFields(m_FieldName);
  if (FieldArray.empty())
    return CJS_Return(false);

  CPDF_FormField* pFormField = FieldArray[0];
  if (pFormField->GetFieldType() != FIELDTYPE_COMBOBOX &&
      pFormField->GetFieldType() != FIELDTYPE_LISTBOX) {
    return CJS_Return(false);
  }

  int count = pFormField->CountSelectedItems();
  if (count <= 0)
    return CJS_Return(pRuntime->NewNumber(-1));
  if (count == 1)
    return CJS_Return(pRuntime->NewNumber(pFormField->GetSelectedIndex(0)));

  v8::Local<v8::Array> SelArray = pRuntime->NewArray();
  for (int i = 0; i < count; i++) {
    pRuntime->PutArrayElement(
        SelArray, i, pRuntime->NewNumber(pFormField->GetSelectedIndex(i)));
  }
  if (SelArray.IsEmpty())
    return CJS_Return(pRuntime->NewArray());
  return CJS_Return(SelArray);
}

CJS_Return Field::set_current_value_indices(CJS_Runtime* pRuntime,
                                            v8::Local<v8::Value> vp) {
  if (!m_bCanSet)
    return CJS_Return(false);

  std::vector<uint32_t> array;
  if (vp->IsNumber()) {
    array.push_back(pRuntime->ToInt32(vp));
  } else if (!vp.IsEmpty() && vp->IsArray()) {
    v8::Local<v8::Array> SelArray = pRuntime->ToArray(vp);
    for (size_t i = 0; i < pRuntime->GetArrayLength(SelArray); i++) {
      array.push_back(
          pRuntime->ToInt32(pRuntime->GetArrayElement(SelArray, i)));
    }
  }

  if (m_bDelay) {
    AddDelay_WordArray(FP_CURRENTVALUEINDICES, array);
  } else {
    Field::SetCurrentValueIndices(m_pFormFillEnv.Get(), m_FieldName,
                                  m_nFormControlIndex, array);
  }
  return CJS_Return(true);
}

void Field::SetCurrentValueIndices(CPDFSDK_FormFillEnvironment* pFormFillEnv,
                                   const WideString& swFieldName,
                                   int nControlIndex,
                                   const std::vector<uint32_t>& array) {
  ASSERT(pFormFillEnv);
  std::vector<CPDF_FormField*> FieldArray =
      GetFormFields(pFormFillEnv, swFieldName);

  for (CPDF_FormField* pFormField : FieldArray) {
    int nFieldType = pFormField->GetFieldType();
    if (nFieldType == FIELDTYPE_COMBOBOX || nFieldType == FIELDTYPE_LISTBOX) {
      uint32_t dwFieldFlags = pFormField->GetFieldFlags();
      pFormField->ClearSelection(true);
      for (size_t i = 0; i < array.size(); ++i) {
        if (i != 0 && !(dwFieldFlags & (1 << 21)))
          break;
        if (array[i] < static_cast<uint32_t>(pFormField->CountOptions()) &&
            !pFormField->IsItemSelected(array[i])) {
          pFormField->SetItemSelection(array[i], true);
        }
      }
      UpdateFormField(pFormFillEnv, pFormField, true, true, true);
    }
  }
}

CJS_Return Field::get_default_style(CJS_Runtime* pRuntime) {
  return CJS_Return(false);
}

CJS_Return Field::set_default_style(CJS_Runtime* pRuntime,
                                    v8::Local<v8::Value> vp) {
  return CJS_Return(false);
}

CJS_Return Field::get_default_value(CJS_Runtime* pRuntime) {
  ASSERT(m_pFormFillEnv);

  std::vector<CPDF_FormField*> FieldArray = GetFormFields(m_FieldName);
  if (FieldArray.empty())
    return CJS_Return(false);

  CPDF_FormField* pFormField = FieldArray[0];
  if (pFormField->GetFieldType() == FIELDTYPE_PUSHBUTTON ||
      pFormField->GetFieldType() == FIELDTYPE_SIGNATURE) {
    return CJS_Return(false);
  }

  return CJS_Return(pRuntime->NewString(pFormField->GetDefaultValue().c_str()));
}

CJS_Return Field::set_default_value(CJS_Runtime* pRuntime,
                                    v8::Local<v8::Value> vp) {
  ASSERT(m_pFormFillEnv);
  return CJS_Return(m_bCanSet);
}

CJS_Return Field::get_do_not_scroll(CJS_Runtime* pRuntime) {
  ASSERT(m_pFormFillEnv);

  std::vector<CPDF_FormField*> FieldArray = GetFormFields(m_FieldName);
  if (FieldArray.empty())
    return CJS_Return(false);

  CPDF_FormField* pFormField = FieldArray[0];
  if (pFormField->GetFieldType() != FIELDTYPE_TEXTFIELD)
    return CJS_Return(false);

  return CJS_Return(pRuntime->NewBoolean(
      !!(pFormField->GetFieldFlags() & FIELDFLAG_DONOTSCROLL)));
}

CJS_Return Field::set_do_not_scroll(CJS_Runtime* pRuntime,
                                    v8::Local<v8::Value> vp) {
  ASSERT(m_pFormFillEnv);
  return CJS_Return(m_bCanSet);
}

CJS_Return Field::get_do_not_spell_check(CJS_Runtime* pRuntime) {
  ASSERT(m_pFormFillEnv);

  std::vector<CPDF_FormField*> FieldArray = GetFormFields(m_FieldName);
  if (FieldArray.empty())
    return CJS_Return(false);

  CPDF_FormField* pFormField = FieldArray[0];
  if (pFormField->GetFieldType() != FIELDTYPE_TEXTFIELD &&
      pFormField->GetFieldType() != FIELDTYPE_COMBOBOX) {
    return CJS_Return(false);
  }

  return CJS_Return(pRuntime->NewBoolean(
      !!(pFormField->GetFieldFlags() & FIELDFLAG_DONOTSPELLCHECK)));
}

CJS_Return Field::set_do_not_spell_check(CJS_Runtime* pRuntime,
                                         v8::Local<v8::Value> vp) {
  ASSERT(m_pFormFillEnv);
  return CJS_Return(m_bCanSet);
}

void Field::SetDelay(bool bDelay) {
  m_bDelay = bDelay;

  if (m_bDelay)
    return;
  if (m_pJSDoc)
    m_pJSDoc->DoFieldDelay(m_FieldName, m_nFormControlIndex);
}

CJS_Return Field::get_delay(CJS_Runtime* pRuntime) {
  return CJS_Return(pRuntime->NewBoolean(m_bDelay));
}

CJS_Return Field::set_delay(CJS_Runtime* pRuntime, v8::Local<v8::Value> vp) {
  if (!m_bCanSet)
    return CJS_Return(false);

  SetDelay(pRuntime->ToBoolean(vp));
  return CJS_Return(true);
}

CJS_Return Field::get_display(CJS_Runtime* pRuntime) {
  std::vector<CPDF_FormField*> FieldArray = GetFormFields(m_FieldName);
  if (FieldArray.empty())
    return CJS_Return(false);

  CPDF_FormField* pFormField = FieldArray[0];
  ASSERT(pFormField);

  CPDFSDK_InterForm* pInterForm = m_pFormFillEnv->GetInterForm();
  CPDFSDK_Widget* pWidget =
      pInterForm->GetWidget(GetSmartFieldControl(pFormField));
  if (!pWidget)
    return CJS_Return(false);

  uint32_t dwFlag = pWidget->GetFlags();
  if (ANNOTFLAG_INVISIBLE & dwFlag || ANNOTFLAG_HIDDEN & dwFlag)
    return CJS_Return(pRuntime->NewNumber(1));

  if (ANNOTFLAG_PRINT & dwFlag) {
    if (ANNOTFLAG_NOVIEW & dwFlag)
      return CJS_Return(pRuntime->NewNumber(3));
    return CJS_Return(pRuntime->NewNumber(0));
  }
  return CJS_Return(pRuntime->NewNumber(2));
}

CJS_Return Field::set_display(CJS_Runtime* pRuntime, v8::Local<v8::Value> vp) {
  if (!m_bCanSet)
    return CJS_Return(false);

  if (m_bDelay) {
    AddDelay_Int(FP_DISPLAY, pRuntime->ToInt32(vp));
  } else {
    Field::SetDisplay(m_pFormFillEnv.Get(), m_FieldName, m_nFormControlIndex,
                      pRuntime->ToInt32(vp));
  }
  return CJS_Return(true);
}

void Field::SetDisplay(CPDFSDK_FormFillEnvironment* pFormFillEnv,
                       const WideString& swFieldName,
                       int nControlIndex,
                       int number) {
  CPDFSDK_InterForm* pInterForm = pFormFillEnv->GetInterForm();
  std::vector<CPDF_FormField*> FieldArray =
      GetFormFields(pFormFillEnv, swFieldName);
  for (CPDF_FormField* pFormField : FieldArray) {
    if (nControlIndex < 0) {
      bool bAnySet = false;
      for (int i = 0, sz = pFormField->CountControls(); i < sz; ++i) {
        CPDF_FormControl* pFormControl = pFormField->GetControl(i);
        ASSERT(pFormControl);

        CPDFSDK_Widget* pWidget = pInterForm->GetWidget(pFormControl);
        if (SetWidgetDisplayStatus(pWidget, number))
          bAnySet = true;
      }

      if (bAnySet)
        UpdateFormField(pFormFillEnv, pFormField, true, false, true);
    } else {
      if (nControlIndex >= pFormField->CountControls())
        return;

      CPDF_FormControl* pFormControl = pFormField->GetControl(nControlIndex);
      if (!pFormControl)
        return;

      CPDFSDK_Widget* pWidget = pInterForm->GetWidget(pFormControl);
      if (SetWidgetDisplayStatus(pWidget, number))
        UpdateFormControl(pFormFillEnv, pFormControl, true, false, true);
    }
  }
}

CJS_Return Field::get_doc(CJS_Runtime* pRuntime) {
  return CJS_Return(m_pJSDoc->GetCJSDoc()->ToV8Object());
}

CJS_Return Field::set_doc(CJS_Runtime* pRuntime, v8::Local<v8::Value> vp) {
  return CJS_Return(false);
}

CJS_Return Field::get_editable(CJS_Runtime* pRuntime) {
  std::vector<CPDF_FormField*> FieldArray = GetFormFields(m_FieldName);
  if (FieldArray.empty())
    return CJS_Return(false);

  CPDF_FormField* pFormField = FieldArray[0];
  if (pFormField->GetFieldType() != FIELDTYPE_COMBOBOX)
    return CJS_Return(false);

  return CJS_Return(
      pRuntime->NewBoolean(!!(pFormField->GetFieldFlags() & FIELDFLAG_EDIT)));
}

CJS_Return Field::set_editable(CJS_Runtime* pRuntime, v8::Local<v8::Value> vp) {
  return CJS_Return(m_bCanSet);
}

CJS_Return Field::get_export_values(CJS_Runtime* pRuntime) {
  std::vector<CPDF_FormField*> FieldArray = GetFormFields(m_FieldName);
  if (FieldArray.empty())
    return CJS_Return(false);

  CPDF_FormField* pFormField = FieldArray[0];
  if (pFormField->GetFieldType() != FIELDTYPE_CHECKBOX &&
      pFormField->GetFieldType() != FIELDTYPE_RADIOBUTTON) {
    return CJS_Return(false);
  }

  v8::Local<v8::Array> ExportValuesArray = pRuntime->NewArray();
  if (m_nFormControlIndex < 0) {
    for (int i = 0, sz = pFormField->CountControls(); i < sz; i++) {
      CPDF_FormControl* pFormControl = pFormField->GetControl(i);
      pRuntime->PutArrayElement(
          ExportValuesArray, i,
          pRuntime->NewString(pFormControl->GetExportValue().c_str()));
    }
  } else {
    if (m_nFormControlIndex >= pFormField->CountControls())
      return CJS_Return(false);

    CPDF_FormControl* pFormControl =
        pFormField->GetControl(m_nFormControlIndex);
    if (!pFormControl)
      return CJS_Return(false);

    pRuntime->PutArrayElement(
        ExportValuesArray, 0,
        pRuntime->NewString(pFormControl->GetExportValue().c_str()));
  }
  return CJS_Return(ExportValuesArray);
}

CJS_Return Field::set_export_values(CJS_Runtime* pRuntime,
                                    v8::Local<v8::Value> vp) {
  std::vector<CPDF_FormField*> FieldArray = GetFormFields(m_FieldName);
  if (FieldArray.empty())
    return CJS_Return(false);

  CPDF_FormField* pFormField = FieldArray[0];
  if (pFormField->GetFieldType() != FIELDTYPE_CHECKBOX &&
      pFormField->GetFieldType() != FIELDTYPE_RADIOBUTTON) {
    return CJS_Return(false);
  }

  return CJS_Return(m_bCanSet && !vp.IsEmpty() && vp->IsArray());
}

CJS_Return Field::get_file_select(CJS_Runtime* pRuntime) {
  std::vector<CPDF_FormField*> FieldArray = GetFormFields(m_FieldName);
  if (FieldArray.empty())
    return CJS_Return(false);

  CPDF_FormField* pFormField = FieldArray[0];
  if (pFormField->GetFieldType() != FIELDTYPE_TEXTFIELD)
    return CJS_Return(false);

  return CJS_Return(pRuntime->NewBoolean(
      !!(pFormField->GetFieldFlags() & FIELDFLAG_FILESELECT)));
}

CJS_Return Field::set_file_select(CJS_Runtime* pRuntime,
                                  v8::Local<v8::Value> vp) {
  std::vector<CPDF_FormField*> FieldArray = GetFormFields(m_FieldName);
  if (FieldArray.empty())
    return CJS_Return(false);

  CPDF_FormField* pFormField = FieldArray[0];
  if (pFormField->GetFieldType() != FIELDTYPE_TEXTFIELD)
    return CJS_Return(false);
  return CJS_Return(m_bCanSet);
}

CJS_Return Field::get_fill_color(CJS_Runtime* pRuntime) {
  std::vector<CPDF_FormField*> FieldArray = GetFormFields(m_FieldName);
  if (FieldArray.empty())
    return CJS_Return(false);

  CPDF_FormField* pFormField = FieldArray[0];
  ASSERT(pFormField);
  CPDF_FormControl* pFormControl = GetSmartFieldControl(pFormField);
  if (!pFormControl)
    return CJS_Return(false);

  int iColorType;
  pFormControl->GetBackgroundColor(iColorType);

  CFX_Color color;
  if (iColorType == CFX_Color::kTransparent) {
    color = CFX_Color(CFX_Color::kTransparent);
  } else if (iColorType == CFX_Color::kGray) {
    color = CFX_Color(CFX_Color::kGray,
                      pFormControl->GetOriginalBackgroundColor(0));
  } else if (iColorType == CFX_Color::kRGB) {
    color =
        CFX_Color(CFX_Color::kRGB, pFormControl->GetOriginalBackgroundColor(0),
                  pFormControl->GetOriginalBackgroundColor(1),
                  pFormControl->GetOriginalBackgroundColor(2));
  } else if (iColorType == CFX_Color::kCMYK) {
    color =
        CFX_Color(CFX_Color::kCMYK, pFormControl->GetOriginalBackgroundColor(0),
                  pFormControl->GetOriginalBackgroundColor(1),
                  pFormControl->GetOriginalBackgroundColor(2),
                  pFormControl->GetOriginalBackgroundColor(3));
  } else {
    return CJS_Return(false);
  }

  v8::Local<v8::Value> array = color::ConvertPWLColorToArray(pRuntime, color);
  if (array.IsEmpty())
    return CJS_Return(pRuntime->NewArray());
  return CJS_Return(array);
}

CJS_Return Field::set_fill_color(CJS_Runtime* pRuntime,
                                 v8::Local<v8::Value> vp) {
  std::vector<CPDF_FormField*> FieldArray = GetFormFields(m_FieldName);
  if (FieldArray.empty())
    return CJS_Return(false);
  if (!m_bCanSet)
    return CJS_Return(false);
  if (vp.IsEmpty() || !vp->IsArray())
    return CJS_Return(false);
  return CJS_Return(true);
}

CJS_Return Field::get_hidden(CJS_Runtime* pRuntime) {
  std::vector<CPDF_FormField*> FieldArray = GetFormFields(m_FieldName);
  if (FieldArray.empty())
    return CJS_Return(false);

  CPDF_FormField* pFormField = FieldArray[0];
  ASSERT(pFormField);

  CPDFSDK_InterForm* pInterForm = m_pFormFillEnv->GetInterForm();
  CPDFSDK_Widget* pWidget =
      pInterForm->GetWidget(GetSmartFieldControl(pFormField));
  if (!pWidget)
    return CJS_Return(false);

  uint32_t dwFlags = pWidget->GetFlags();
  return CJS_Return(pRuntime->NewBoolean(ANNOTFLAG_INVISIBLE & dwFlags ||
                                         ANNOTFLAG_HIDDEN & dwFlags));
}

CJS_Return Field::set_hidden(CJS_Runtime* pRuntime, v8::Local<v8::Value> vp) {
  if (!m_bCanSet)
    return CJS_Return(false);

  if (m_bDelay) {
    AddDelay_Bool(FP_HIDDEN, pRuntime->ToBoolean(vp));
  } else {
    Field::SetHidden(m_pFormFillEnv.Get(), m_FieldName, m_nFormControlIndex,
                     pRuntime->ToBoolean(vp));
  }
  return CJS_Return(true);
}

void Field::SetHidden(CPDFSDK_FormFillEnvironment* pFormFillEnv,
                      const WideString& swFieldName,
                      int nControlIndex,
                      bool b) {
  int display = b ? 1 /*Hidden*/ : 0 /*Visible*/;
  SetDisplay(pFormFillEnv, swFieldName, nControlIndex, display);
}

CJS_Return Field::get_highlight(CJS_Runtime* pRuntime) {
  ASSERT(m_pFormFillEnv);

  std::vector<CPDF_FormField*> FieldArray = GetFormFields(m_FieldName);
  if (FieldArray.empty())
    return CJS_Return(false);

  CPDF_FormField* pFormField = FieldArray[0];
  if (pFormField->GetFieldType() != FIELDTYPE_PUSHBUTTON)
    return CJS_Return(false);

  CPDF_FormControl* pFormControl = GetSmartFieldControl(pFormField);
  if (!pFormControl)
    return CJS_Return(false);

  int eHM = pFormControl->GetHighlightingMode();
  switch (eHM) {
    case CPDF_FormControl::None:
      return CJS_Return(pRuntime->NewString(L"none"));
    case CPDF_FormControl::Push:
      return CJS_Return(pRuntime->NewString(L"push"));
    case CPDF_FormControl::Invert:
      return CJS_Return(pRuntime->NewString(L"invert"));
    case CPDF_FormControl::Outline:
      return CJS_Return(pRuntime->NewString(L"outline"));
    case CPDF_FormControl::Toggle:
      return CJS_Return(pRuntime->NewString(L"toggle"));
  }
  return CJS_Return(true);
}

CJS_Return Field::set_highlight(CJS_Runtime* pRuntime,
                                v8::Local<v8::Value> vp) {
  ASSERT(m_pFormFillEnv);
  return CJS_Return(m_bCanSet);
}

CJS_Return Field::get_line_width(CJS_Runtime* pRuntime) {
  std::vector<CPDF_FormField*> FieldArray = GetFormFields(m_FieldName);
  if (FieldArray.empty())
    return CJS_Return(false);

  CPDF_FormField* pFormField = FieldArray[0];
  ASSERT(pFormField);

  CPDF_FormControl* pFormControl = GetSmartFieldControl(pFormField);
  if (!pFormControl)
    return CJS_Return(false);

  CPDFSDK_InterForm* pInterForm = m_pFormFillEnv->GetInterForm();
  if (!pFormField->CountControls())
    return CJS_Return(false);

  CPDFSDK_Widget* pWidget = pInterForm->GetWidget(pFormField->GetControl(0));
  if (!pWidget)
    return CJS_Return(false);

  return CJS_Return(pRuntime->NewNumber(pWidget->GetBorderWidth()));
}

CJS_Return Field::set_line_width(CJS_Runtime* pRuntime,
                                 v8::Local<v8::Value> vp) {
  if (!m_bCanSet)
    return CJS_Return(false);

  if (m_bDelay) {
    AddDelay_Int(FP_LINEWIDTH, pRuntime->ToInt32(vp));
  } else {
    Field::SetLineWidth(m_pFormFillEnv.Get(), m_FieldName, m_nFormControlIndex,
                        pRuntime->ToInt32(vp));
  }
  return CJS_Return(true);
}

void Field::SetLineWidth(CPDFSDK_FormFillEnvironment* pFormFillEnv,
                         const WideString& swFieldName,
                         int nControlIndex,
                         int number) {
  CPDFSDK_InterForm* pInterForm = pFormFillEnv->GetInterForm();
  std::vector<CPDF_FormField*> FieldArray =
      GetFormFields(pFormFillEnv, swFieldName);
  for (CPDF_FormField* pFormField : FieldArray) {
    if (nControlIndex < 0) {
      bool bSet = false;
      for (int i = 0, sz = pFormField->CountControls(); i < sz; ++i) {
        CPDF_FormControl* pFormControl = pFormField->GetControl(i);
        ASSERT(pFormControl);

        if (CPDFSDK_Widget* pWidget = pInterForm->GetWidget(pFormControl)) {
          if (number != pWidget->GetBorderWidth()) {
            pWidget->SetBorderWidth(number);
            bSet = true;
          }
        }
      }
      if (bSet)
        UpdateFormField(pFormFillEnv, pFormField, true, true, true);
    } else {
      if (nControlIndex >= pFormField->CountControls())
        return;
      if (CPDF_FormControl* pFormControl =
              pFormField->GetControl(nControlIndex)) {
        if (CPDFSDK_Widget* pWidget = pInterForm->GetWidget(pFormControl)) {
          if (number != pWidget->GetBorderWidth()) {
            pWidget->SetBorderWidth(number);
            UpdateFormControl(pFormFillEnv, pFormControl, true, true, true);
          }
        }
      }
    }
  }
}

CJS_Return Field::get_multiline(CJS_Runtime* pRuntime) {
  ASSERT(m_pFormFillEnv);

  std::vector<CPDF_FormField*> FieldArray = GetFormFields(m_FieldName);
  if (FieldArray.empty())
    return CJS_Return(false);

  CPDF_FormField* pFormField = FieldArray[0];
  if (pFormField->GetFieldType() != FIELDTYPE_TEXTFIELD)
    return CJS_Return(false);

  return CJS_Return(pRuntime->NewBoolean(
      !!(pFormField->GetFieldFlags() & FIELDFLAG_MULTILINE)));
}

CJS_Return Field::set_multiline(CJS_Runtime* pRuntime,
                                v8::Local<v8::Value> vp) {
  ASSERT(m_pFormFillEnv);
  return CJS_Return(m_bCanSet);
}

CJS_Return Field::get_multiple_selection(CJS_Runtime* pRuntime) {
  ASSERT(m_pFormFillEnv);
  std::vector<CPDF_FormField*> FieldArray = GetFormFields(m_FieldName);
  if (FieldArray.empty())
    return CJS_Return(false);

  CPDF_FormField* pFormField = FieldArray[0];
  if (pFormField->GetFieldType() != FIELDTYPE_LISTBOX)
    return CJS_Return(false);

  return CJS_Return(pRuntime->NewBoolean(
      !!(pFormField->GetFieldFlags() & FIELDFLAG_MULTISELECT)));
}

CJS_Return Field::set_multiple_selection(CJS_Runtime* pRuntime,
                                         v8::Local<v8::Value> vp) {
  ASSERT(m_pFormFillEnv);
  return CJS_Return(m_bCanSet);
}

CJS_Return Field::get_name(CJS_Runtime* pRuntime) {
  std::vector<CPDF_FormField*> FieldArray = GetFormFields(m_FieldName);
  if (FieldArray.empty())
    return CJS_Return(false);

  return CJS_Return(pRuntime->NewString(m_FieldName.c_str()));
}

CJS_Return Field::set_name(CJS_Runtime* pRuntime, v8::Local<v8::Value> vp) {
  return CJS_Return(false);
}

CJS_Return Field::get_num_items(CJS_Runtime* pRuntime) {
  std::vector<CPDF_FormField*> FieldArray = GetFormFields(m_FieldName);
  if (FieldArray.empty())
    return CJS_Return(false);

  CPDF_FormField* pFormField = FieldArray[0];
  if (pFormField->GetFieldType() != FIELDTYPE_COMBOBOX &&
      pFormField->GetFieldType() != FIELDTYPE_LISTBOX) {
    return CJS_Return(false);
  }

  return CJS_Return(pRuntime->NewNumber(pFormField->CountOptions()));
}

CJS_Return Field::set_num_items(CJS_Runtime* pRuntime,
                                v8::Local<v8::Value> vp) {
  return CJS_Return(false);
}

CJS_Return Field::get_page(CJS_Runtime* pRuntime) {
  std::vector<CPDF_FormField*> FieldArray = GetFormFields(m_FieldName);
  if (FieldArray.empty())
    return CJS_Return(false);

  CPDF_FormField* pFormField = FieldArray[0];
  if (!pFormField)
    return CJS_Return(false);

  std::vector<CPDFSDK_Annot::ObservedPtr> widgets;
  m_pFormFillEnv->GetInterForm()->GetWidgets(pFormField, &widgets);
  if (widgets.empty())
    return CJS_Return(pRuntime->NewNumber(-1));

  v8::Local<v8::Array> PageArray = pRuntime->NewArray();
  int i = 0;
  for (const auto& pObserved : widgets) {
    if (!pObserved)
      return CJS_Return(JSGetStringFromID(IDS_STRING_JSBADOBJECT));

    auto* pWidget = static_cast<CPDFSDK_Widget*>(pObserved.Get());
    CPDFSDK_PageView* pPageView = pWidget->GetPageView();
    if (!pPageView)
      return CJS_Return(false);

    pRuntime->PutArrayElement(
        PageArray, i,
        pRuntime->NewNumber(static_cast<int32_t>(pPageView->GetPageIndex())));
    ++i;
  }
  return CJS_Return(PageArray);
}

CJS_Return Field::set_page(CJS_Runtime* pRuntime, v8::Local<v8::Value> vp) {
  return CJS_Return(JSGetStringFromID(IDS_STRING_JSREADONLY));
}

CJS_Return Field::get_password(CJS_Runtime* pRuntime) {
  ASSERT(m_pFormFillEnv);

  std::vector<CPDF_FormField*> FieldArray = GetFormFields(m_FieldName);
  if (FieldArray.empty())
    return CJS_Return(false);

  CPDF_FormField* pFormField = FieldArray[0];
  if (pFormField->GetFieldType() != FIELDTYPE_TEXTFIELD)
    return CJS_Return(false);

  return CJS_Return(pRuntime->NewBoolean(
      !!(pFormField->GetFieldFlags() & FIELDFLAG_PASSWORD)));
}

CJS_Return Field::set_password(CJS_Runtime* pRuntime, v8::Local<v8::Value> vp) {
  ASSERT(m_pFormFillEnv);
  return CJS_Return(m_bCanSet);
}

CJS_Return Field::get_print(CJS_Runtime* pRuntime) {
  CPDFSDK_InterForm* pInterForm = m_pFormFillEnv->GetInterForm();
  std::vector<CPDF_FormField*> FieldArray = GetFormFields(m_FieldName);
  if (FieldArray.empty())
    return CJS_Return(false);

  CPDF_FormField* pFormField = FieldArray[0];
  CPDFSDK_Widget* pWidget =
      pInterForm->GetWidget(GetSmartFieldControl(pFormField));
  if (!pWidget)
    return CJS_Return(false);

  return CJS_Return(
      pRuntime->NewBoolean(!!(pWidget->GetFlags() & ANNOTFLAG_PRINT)));
}

CJS_Return Field::set_print(CJS_Runtime* pRuntime, v8::Local<v8::Value> vp) {
  CPDFSDK_InterForm* pInterForm = m_pFormFillEnv->GetInterForm();
  std::vector<CPDF_FormField*> FieldArray = GetFormFields(m_FieldName);
  if (FieldArray.empty())
    return CJS_Return(false);

  if (!m_bCanSet)
    return CJS_Return(false);

  for (CPDF_FormField* pFormField : FieldArray) {
    if (m_nFormControlIndex < 0) {
      bool bSet = false;
      for (int i = 0, sz = pFormField->CountControls(); i < sz; ++i) {
        if (CPDFSDK_Widget* pWidget =
                pInterForm->GetWidget(pFormField->GetControl(i))) {
          uint32_t dwFlags = pWidget->GetFlags();
          if (pRuntime->ToBoolean(vp))
            dwFlags |= ANNOTFLAG_PRINT;
          else
            dwFlags &= ~ANNOTFLAG_PRINT;

          if (dwFlags != pWidget->GetFlags()) {
            pWidget->SetFlags(dwFlags);
            bSet = true;
          }
        }
      }

      if (bSet)
        UpdateFormField(m_pFormFillEnv.Get(), pFormField, true, false, true);

      continue;
    }

    if (m_nFormControlIndex >= pFormField->CountControls())
      return CJS_Return(false);

    if (CPDF_FormControl* pFormControl =
            pFormField->GetControl(m_nFormControlIndex)) {
      if (CPDFSDK_Widget* pWidget = pInterForm->GetWidget(pFormControl)) {
        uint32_t dwFlags = pWidget->GetFlags();
        if (pRuntime->ToBoolean(vp))
          dwFlags |= ANNOTFLAG_PRINT;
        else
          dwFlags &= ~ANNOTFLAG_PRINT;

        if (dwFlags != pWidget->GetFlags()) {
          pWidget->SetFlags(dwFlags);
          UpdateFormControl(m_pFormFillEnv.Get(),
                            pFormField->GetControl(m_nFormControlIndex), true,
                            false, true);
        }
      }
    }
  }
  return CJS_Return(true);
}

CJS_Return Field::get_radios_in_unison(CJS_Runtime* pRuntime) {
  std::vector<CPDF_FormField*> FieldArray = GetFormFields(m_FieldName);
  if (FieldArray.empty())
    return CJS_Return(false);

  CPDF_FormField* pFormField = FieldArray[0];
  if (pFormField->GetFieldType() != FIELDTYPE_RADIOBUTTON)
    return CJS_Return(false);

  return CJS_Return(pRuntime->NewBoolean(
      !!(pFormField->GetFieldFlags() & FIELDFLAG_RADIOSINUNISON)));
}

CJS_Return Field::set_radios_in_unison(CJS_Runtime* pRuntime,
                                       v8::Local<v8::Value> vp) {
  std::vector<CPDF_FormField*> FieldArray = GetFormFields(m_FieldName);
  if (FieldArray.empty())
    return CJS_Return(false);
  return CJS_Return(m_bCanSet);
}

CJS_Return Field::get_readonly(CJS_Runtime* pRuntime) {
  std::vector<CPDF_FormField*> FieldArray = GetFormFields(m_FieldName);
  if (FieldArray.empty())
    return CJS_Return(false);

  return CJS_Return(pRuntime->NewBoolean(
      !!(FieldArray[0]->GetFieldFlags() & FIELDFLAG_READONLY)));
}

CJS_Return Field::set_readonly(CJS_Runtime* pRuntime, v8::Local<v8::Value> vp) {
  std::vector<CPDF_FormField*> FieldArray = GetFormFields(m_FieldName);
  if (FieldArray.empty())
    return CJS_Return(false);
  return CJS_Return(m_bCanSet);
}

CJS_Return Field::get_rect(CJS_Runtime* pRuntime) {
  std::vector<CPDF_FormField*> FieldArray = GetFormFields(m_FieldName);
  if (FieldArray.empty())
    return CJS_Return(false);

  CPDF_FormField* pFormField = FieldArray[0];
  CPDFSDK_InterForm* pInterForm = m_pFormFillEnv->GetInterForm();
  CPDFSDK_Widget* pWidget =
      pInterForm->GetWidget(GetSmartFieldControl(pFormField));
  if (!pWidget)
    return CJS_Return(false);

  CFX_FloatRect crRect = pWidget->GetRect();
  v8::Local<v8::Array> rcArray = pRuntime->NewArray();
  pRuntime->PutArrayElement(
      rcArray, 0, pRuntime->NewNumber(static_cast<int32_t>(crRect.left)));
  pRuntime->PutArrayElement(
      rcArray, 1, pRuntime->NewNumber(static_cast<int32_t>(crRect.top)));
  pRuntime->PutArrayElement(
      rcArray, 2, pRuntime->NewNumber(static_cast<int32_t>(crRect.right)));
  pRuntime->PutArrayElement(
      rcArray, 3, pRuntime->NewNumber(static_cast<int32_t>(crRect.bottom)));

  return CJS_Return(rcArray);
}

CJS_Return Field::set_rect(CJS_Runtime* pRuntime, v8::Local<v8::Value> vp) {
  if (!m_bCanSet)
    return CJS_Return(false);
  if (vp.IsEmpty() || !vp->IsArray())
    return CJS_Return(false);

  v8::Local<v8::Array> rcArray = pRuntime->ToArray(vp);
  if (pRuntime->GetArrayLength(rcArray) < 4)
    return CJS_Return(false);

  float pArray[4];
  pArray[0] = static_cast<float>(
      pRuntime->ToInt32(pRuntime->GetArrayElement(rcArray, 0)));
  pArray[1] = static_cast<float>(
      pRuntime->ToInt32(pRuntime->GetArrayElement(rcArray, 1)));
  pArray[2] = static_cast<float>(
      pRuntime->ToInt32(pRuntime->GetArrayElement(rcArray, 2)));
  pArray[3] = static_cast<float>(
      pRuntime->ToInt32(pRuntime->GetArrayElement(rcArray, 3)));

  CFX_FloatRect crRect(pArray);
  if (m_bDelay) {
    AddDelay_Rect(FP_RECT, crRect);
  } else {
    Field::SetRect(m_pFormFillEnv.Get(), m_FieldName, m_nFormControlIndex,
                   crRect);
  }
  return CJS_Return(true);
}

void Field::SetRect(CPDFSDK_FormFillEnvironment* pFormFillEnv,
                    const WideString& swFieldName,
                    int nControlIndex,
                    const CFX_FloatRect& rect) {
  CPDFSDK_InterForm* pInterForm = pFormFillEnv->GetInterForm();
  std::vector<CPDF_FormField*> FieldArray =
      GetFormFields(pFormFillEnv, swFieldName);
  for (CPDF_FormField* pFormField : FieldArray) {
    if (nControlIndex < 0) {
      bool bSet = false;
      for (int i = 0, sz = pFormField->CountControls(); i < sz; ++i) {
        CPDF_FormControl* pFormControl = pFormField->GetControl(i);
        ASSERT(pFormControl);

        if (CPDFSDK_Widget* pWidget = pInterForm->GetWidget(pFormControl)) {
          CFX_FloatRect crRect = rect;

          CPDF_Page* pPDFPage = pWidget->GetPDFPage();
          crRect.Intersect(pPDFPage->GetPageBBox());

          if (!crRect.IsEmpty()) {
            CFX_FloatRect rcOld = pWidget->GetRect();
            if (crRect.left != rcOld.left || crRect.right != rcOld.right ||
                crRect.top != rcOld.top || crRect.bottom != rcOld.bottom) {
              pWidget->SetRect(crRect);
              bSet = true;
            }
          }
        }
      }

      if (bSet)
        UpdateFormField(pFormFillEnv, pFormField, true, true, true);

      continue;
    }

    if (nControlIndex >= pFormField->CountControls())
      return;
    if (CPDF_FormControl* pFormControl =
            pFormField->GetControl(nControlIndex)) {
      if (CPDFSDK_Widget* pWidget = pInterForm->GetWidget(pFormControl)) {
        CFX_FloatRect crRect = rect;

        CPDF_Page* pPDFPage = pWidget->GetPDFPage();
        crRect.Intersect(pPDFPage->GetPageBBox());

        if (!crRect.IsEmpty()) {
          CFX_FloatRect rcOld = pWidget->GetRect();
          if (crRect.left != rcOld.left || crRect.right != rcOld.right ||
              crRect.top != rcOld.top || crRect.bottom != rcOld.bottom) {
            pWidget->SetRect(crRect);
            UpdateFormControl(pFormFillEnv, pFormControl, true, true, true);
          }
        }
      }
    }
  }
}

CJS_Return Field::get_required(CJS_Runtime* pRuntime) {
  std::vector<CPDF_FormField*> FieldArray = GetFormFields(m_FieldName);
  if (FieldArray.empty())
    return CJS_Return(false);

  CPDF_FormField* pFormField = FieldArray[0];
  if (pFormField->GetFieldType() == FIELDTYPE_PUSHBUTTON)
    return CJS_Return(false);

  return CJS_Return(pRuntime->NewBoolean(
      !!(pFormField->GetFieldFlags() & FIELDFLAG_REQUIRED)));
}

CJS_Return Field::set_required(CJS_Runtime* pRuntime, v8::Local<v8::Value> vp) {
  std::vector<CPDF_FormField*> FieldArray = GetFormFields(m_FieldName);
  if (FieldArray.empty())
    return CJS_Return(false);
  return CJS_Return(m_bCanSet);
}

CJS_Return Field::get_rich_text(CJS_Runtime* pRuntime) {
  ASSERT(m_pFormFillEnv);

  std::vector<CPDF_FormField*> FieldArray = GetFormFields(m_FieldName);
  if (FieldArray.empty())
    return CJS_Return(false);

  CPDF_FormField* pFormField = FieldArray[0];
  if (pFormField->GetFieldType() != FIELDTYPE_TEXTFIELD)
    return CJS_Return(false);

  return CJS_Return(pRuntime->NewBoolean(
      !!(pFormField->GetFieldFlags() & FIELDFLAG_RICHTEXT)));
}

CJS_Return Field::set_rich_text(CJS_Runtime* pRuntime,
                                v8::Local<v8::Value> vp) {
  ASSERT(m_pFormFillEnv);
  return CJS_Return(m_bCanSet);
}

CJS_Return Field::get_rich_value(CJS_Runtime* pRuntime) {
  return CJS_Return(true);
}

CJS_Return Field::set_rich_value(CJS_Runtime* pRuntime,
                                 v8::Local<v8::Value> vp) {
  return CJS_Return(true);
}

CJS_Return Field::get_rotation(CJS_Runtime* pRuntime) {
  ASSERT(m_pFormFillEnv);

  std::vector<CPDF_FormField*> FieldArray = GetFormFields(m_FieldName);
  if (FieldArray.empty())
    return CJS_Return(false);

  CPDF_FormField* pFormField = FieldArray[0];
  CPDF_FormControl* pFormControl = GetSmartFieldControl(pFormField);
  if (!pFormControl)
    return CJS_Return(false);

  return CJS_Return(pRuntime->NewNumber(pFormControl->GetRotation()));
}

CJS_Return Field::set_rotation(CJS_Runtime* pRuntime, v8::Local<v8::Value> vp) {
  ASSERT(m_pFormFillEnv);
  return CJS_Return(m_bCanSet);
}

CJS_Return Field::get_stroke_color(CJS_Runtime* pRuntime) {
  std::vector<CPDF_FormField*> FieldArray = GetFormFields(m_FieldName);
  if (FieldArray.empty())
    return CJS_Return(false);

  CPDF_FormField* pFormField = FieldArray[0];
  CPDF_FormControl* pFormControl = GetSmartFieldControl(pFormField);
  if (!pFormControl)
    return CJS_Return(false);

  int iColorType;
  pFormControl->GetBorderColor(iColorType);

  CFX_Color color;
  if (iColorType == CFX_Color::kTransparent) {
    color = CFX_Color(CFX_Color::kTransparent);
  } else if (iColorType == CFX_Color::kGray) {
    color =
        CFX_Color(CFX_Color::kGray, pFormControl->GetOriginalBorderColor(0));
  } else if (iColorType == CFX_Color::kRGB) {
    color = CFX_Color(CFX_Color::kRGB, pFormControl->GetOriginalBorderColor(0),
                      pFormControl->GetOriginalBorderColor(1),
                      pFormControl->GetOriginalBorderColor(2));
  } else if (iColorType == CFX_Color::kCMYK) {
    color = CFX_Color(CFX_Color::kCMYK, pFormControl->GetOriginalBorderColor(0),
                      pFormControl->GetOriginalBorderColor(1),
                      pFormControl->GetOriginalBorderColor(2),
                      pFormControl->GetOriginalBorderColor(3));
  } else {
    return CJS_Return(false);
  }

  v8::Local<v8::Value> array = color::ConvertPWLColorToArray(pRuntime, color);
  if (array.IsEmpty())
    return CJS_Return(pRuntime->NewArray());
  return CJS_Return(array);
}

CJS_Return Field::set_stroke_color(CJS_Runtime* pRuntime,
                                   v8::Local<v8::Value> vp) {
  if (!m_bCanSet)
    return CJS_Return(false);
  if (vp.IsEmpty() || !vp->IsArray())
    return CJS_Return(false);
  return CJS_Return(true);
}

CJS_Return Field::get_style(CJS_Runtime* pRuntime) {
  ASSERT(m_pFormFillEnv);

  std::vector<CPDF_FormField*> FieldArray = GetFormFields(m_FieldName);
  if (FieldArray.empty())
    return CJS_Return(false);

  CPDF_FormField* pFormField = FieldArray[0];
  if (pFormField->GetFieldType() != FIELDTYPE_RADIOBUTTON &&
      pFormField->GetFieldType() != FIELDTYPE_CHECKBOX) {
    return CJS_Return(false);
  }

  CPDF_FormControl* pFormControl = GetSmartFieldControl(pFormField);
  if (!pFormControl)
    return CJS_Return(false);

  WideString csWCaption = pFormControl->GetNormalCaption();
  ByteString csBCaption;

  switch (csWCaption[0]) {
    case L'l':
      csBCaption = "circle";
      break;
    case L'8':
      csBCaption = "cross";
      break;
    case L'u':
      csBCaption = "diamond";
      break;
    case L'n':
      csBCaption = "square";
      break;
    case L'H':
      csBCaption = "star";
      break;
    default:  // L'4'
      csBCaption = "check";
      break;
  }
  return CJS_Return(
      pRuntime->NewString(WideString::FromLocal(csBCaption.c_str()).c_str()));
}

CJS_Return Field::set_style(CJS_Runtime* pRuntime, v8::Local<v8::Value> vp) {
  ASSERT(m_pFormFillEnv);
  return CJS_Return(m_bCanSet);
}

CJS_Return Field::get_submit_name(CJS_Runtime* pRuntime) {
  return CJS_Return(true);
}

CJS_Return Field::set_submit_name(CJS_Runtime* pRuntime,
                                  v8::Local<v8::Value> vp) {
  return CJS_Return(true);
}

CJS_Return Field::get_text_color(CJS_Runtime* pRuntime) {
  std::vector<CPDF_FormField*> FieldArray = GetFormFields(m_FieldName);
  if (FieldArray.empty())
    return CJS_Return(false);

  CPDF_FormField* pFormField = FieldArray[0];
  CPDF_FormControl* pFormControl = GetSmartFieldControl(pFormField);
  if (!pFormControl)
    return CJS_Return(false);

  int iColorType;
  FX_ARGB color;
  CPDF_DefaultAppearance FieldAppearance = pFormControl->GetDefaultAppearance();
  FieldAppearance.GetColor(color, iColorType);

  int32_t a;
  int32_t r;
  int32_t g;
  int32_t b;
  std::tie(a, r, g, b) = ArgbDecode(color);

  CFX_Color crRet =
      CFX_Color(CFX_Color::kRGB, r / 255.0f, g / 255.0f, b / 255.0f);

  if (iColorType == CFX_Color::kTransparent)
    crRet = CFX_Color(CFX_Color::kTransparent);

  v8::Local<v8::Value> array = color::ConvertPWLColorToArray(pRuntime, crRet);
  if (array.IsEmpty())
    return CJS_Return(pRuntime->NewArray());
  return CJS_Return(array);
}

CJS_Return Field::set_text_color(CJS_Runtime* pRuntime,
                                 v8::Local<v8::Value> vp) {
  if (!m_bCanSet)
    return CJS_Return(false);
  if (vp.IsEmpty() || !vp->IsArray())
    return CJS_Return(false);
  return CJS_Return(true);
}

CJS_Return Field::get_text_font(CJS_Runtime* pRuntime) {
  ASSERT(m_pFormFillEnv);

  std::vector<CPDF_FormField*> FieldArray = GetFormFields(m_FieldName);
  if (FieldArray.empty())
    return CJS_Return(false);

  CPDF_FormField* pFormField = FieldArray[0];
  ASSERT(pFormField);
  CPDF_FormControl* pFormControl = GetSmartFieldControl(pFormField);
  if (!pFormControl)
    return CJS_Return(false);

  int nFieldType = pFormField->GetFieldType();
  if (nFieldType != FIELDTYPE_PUSHBUTTON && nFieldType != FIELDTYPE_COMBOBOX &&
      nFieldType != FIELDTYPE_LISTBOX && nFieldType != FIELDTYPE_TEXTFIELD) {
    return CJS_Return(false);
  }

  CPDF_Font* pFont = pFormControl->GetDefaultControlFont();
  if (!pFont)
    return CJS_Return(false);

  return CJS_Return(pRuntime->NewString(
      WideString::FromLocal(pFont->GetBaseFont().c_str()).c_str()));
}

CJS_Return Field::set_text_font(CJS_Runtime* pRuntime,
                                v8::Local<v8::Value> vp) {
  ASSERT(m_pFormFillEnv);

  if (!m_bCanSet)
    return CJS_Return(false);
  return CJS_Return(
      !ByteString::FromUnicode(pRuntime->ToWideString(vp)).IsEmpty());
}

CJS_Return Field::get_text_size(CJS_Runtime* pRuntime) {
  ASSERT(m_pFormFillEnv);

  std::vector<CPDF_FormField*> FieldArray = GetFormFields(m_FieldName);
  if (FieldArray.empty())
    return CJS_Return(false);

  CPDF_FormField* pFormField = FieldArray[0];
  ASSERT(pFormField);
  CPDF_FormControl* pFormControl = GetSmartFieldControl(pFormField);
  if (!pFormControl)
    return CJS_Return(false);

  float fFontSize;
  CPDF_DefaultAppearance FieldAppearance = pFormControl->GetDefaultAppearance();
  FieldAppearance.GetFont(&fFontSize);
  return CJS_Return(pRuntime->NewNumber(static_cast<int>(fFontSize)));
}

CJS_Return Field::set_text_size(CJS_Runtime* pRuntime,
                                v8::Local<v8::Value> vp) {
  ASSERT(m_pFormFillEnv);
  return CJS_Return(m_bCanSet);
}

CJS_Return Field::get_type(CJS_Runtime* pRuntime) {
  std::vector<CPDF_FormField*> FieldArray = GetFormFields(m_FieldName);
  if (FieldArray.empty())
    return CJS_Return(false);

  CPDF_FormField* pFormField = FieldArray[0];
  switch (pFormField->GetFieldType()) {
    case FIELDTYPE_UNKNOWN:
      return CJS_Return(pRuntime->NewString(L"unknown"));
    case FIELDTYPE_PUSHBUTTON:
      return CJS_Return(pRuntime->NewString(L"button"));
    case FIELDTYPE_CHECKBOX:
      return CJS_Return(pRuntime->NewString(L"checkbox"));
    case FIELDTYPE_RADIOBUTTON:
      return CJS_Return(pRuntime->NewString(L"radiobutton"));
    case FIELDTYPE_COMBOBOX:
      return CJS_Return(pRuntime->NewString(L"combobox"));
    case FIELDTYPE_LISTBOX:
      return CJS_Return(pRuntime->NewString(L"listbox"));
    case FIELDTYPE_TEXTFIELD:
      return CJS_Return(pRuntime->NewString(L"text"));
    case FIELDTYPE_SIGNATURE:
      return CJS_Return(pRuntime->NewString(L"signature"));
  }
  return CJS_Return(pRuntime->NewString(L"unknown"));
}

CJS_Return Field::set_type(CJS_Runtime* pRuntime, v8::Local<v8::Value> vp) {
  return CJS_Return(false);
}

CJS_Return Field::get_user_name(CJS_Runtime* pRuntime) {
  ASSERT(m_pFormFillEnv);

  std::vector<CPDF_FormField*> FieldArray = GetFormFields(m_FieldName);
  if (FieldArray.empty())
    return CJS_Return(false);

  return CJS_Return(
      pRuntime->NewString(FieldArray[0]->GetAlternateName().c_str()));
}

CJS_Return Field::set_user_name(CJS_Runtime* pRuntime,
                                v8::Local<v8::Value> vp) {
  ASSERT(m_pFormFillEnv);
  return CJS_Return(m_bCanSet);
}

CJS_Return Field::get_value(CJS_Runtime* pRuntime) {
  std::vector<CPDF_FormField*> FieldArray = GetFormFields(m_FieldName);
  if (FieldArray.empty())
    return CJS_Return(false);

  v8::Local<v8::Value> ret;

  CPDF_FormField* pFormField = FieldArray[0];
  switch (pFormField->GetFieldType()) {
    case FIELDTYPE_PUSHBUTTON:
      return CJS_Return(false);
    case FIELDTYPE_COMBOBOX:
    case FIELDTYPE_TEXTFIELD:
      ret = pRuntime->NewString(pFormField->GetValue().c_str());
      break;
    case FIELDTYPE_LISTBOX: {
      if (pFormField->CountSelectedItems() > 1) {
        v8::Local<v8::Array> ValueArray = pRuntime->NewArray();
        v8::Local<v8::Value> ElementValue;
        int iIndex;
        for (int i = 0, sz = pFormField->CountSelectedItems(); i < sz; i++) {
          iIndex = pFormField->GetSelectedIndex(i);
          ElementValue =
              pRuntime->NewString(pFormField->GetOptionValue(iIndex).c_str());
          if (wcslen(pRuntime->ToWideString(ElementValue).c_str()) == 0) {
            ElementValue =
                pRuntime->NewString(pFormField->GetOptionLabel(iIndex).c_str());
          }
          pRuntime->PutArrayElement(ValueArray, i, ElementValue);
        }
        ret = ValueArray;
      } else {
        ret = pRuntime->NewString(pFormField->GetValue().c_str());
      }
      break;
    }
    case FIELDTYPE_CHECKBOX:
    case FIELDTYPE_RADIOBUTTON: {
      bool bFind = false;
      for (int i = 0, sz = pFormField->CountControls(); i < sz; i++) {
        if (pFormField->GetControl(i)->IsChecked()) {
          ret = pRuntime->NewString(
              pFormField->GetControl(i)->GetExportValue().c_str());
          bFind = true;
          break;
        }
      }
      if (!bFind)
        ret = pRuntime->NewString(L"Off");

      break;
    }
    default:
      ret = pRuntime->NewString(pFormField->GetValue().c_str());
      break;
  }
  return CJS_Return(pRuntime->MaybeCoerceToNumber(ret));
}

CJS_Return Field::set_value(CJS_Runtime* pRuntime, v8::Local<v8::Value> vp) {
  if (!m_bCanSet)
    return CJS_Return(false);

  std::vector<WideString> strArray;
  if (!vp.IsEmpty() && vp->IsArray()) {
    v8::Local<v8::Array> ValueArray = pRuntime->ToArray(vp);
    for (size_t i = 0; i < pRuntime->GetArrayLength(ValueArray); i++) {
      strArray.push_back(
          pRuntime->ToWideString(pRuntime->GetArrayElement(ValueArray, i)));
    }
  } else {
    strArray.push_back(pRuntime->ToWideString(vp));
  }

  if (m_bDelay) {
    AddDelay_WideStringArray(FP_VALUE, strArray);
  } else {
    Field::SetValue(m_pFormFillEnv.Get(), m_FieldName, m_nFormControlIndex,
                    strArray);
  }
  return CJS_Return(true);
}

void Field::SetValue(CPDFSDK_FormFillEnvironment* pFormFillEnv,
                     const WideString& swFieldName,
                     int nControlIndex,
                     const std::vector<WideString>& strArray) {
  ASSERT(pFormFillEnv);
  if (strArray.empty())
    return;

  std::vector<CPDF_FormField*> FieldArray =
      GetFormFields(pFormFillEnv, swFieldName);

  for (CPDF_FormField* pFormField : FieldArray) {
    if (pFormField->GetFullName().Compare(swFieldName) != 0)
      continue;

    switch (pFormField->GetFieldType()) {
      case FIELDTYPE_TEXTFIELD:
      case FIELDTYPE_COMBOBOX:
        if (pFormField->GetValue() != strArray[0]) {
          pFormField->SetValue(strArray[0], true);
          UpdateFormField(pFormFillEnv, pFormField, true, false, true);
        }
        break;
      case FIELDTYPE_CHECKBOX:
      case FIELDTYPE_RADIOBUTTON:
        if (pFormField->GetValue() != strArray[0]) {
          pFormField->SetValue(strArray[0], true);
          UpdateFormField(pFormFillEnv, pFormField, true, false, true);
        }
        break;
      case FIELDTYPE_LISTBOX: {
        bool bModified = false;
        for (const auto& str : strArray) {
          if (!pFormField->IsItemSelected(pFormField->FindOption(str))) {
            bModified = true;
            break;
          }
        }
        if (bModified) {
          pFormField->ClearSelection(true);
          for (const auto& str : strArray) {
            int index = pFormField->FindOption(str);
            if (!pFormField->IsItemSelected(index))
              pFormField->SetItemSelection(index, true, true);
          }
          UpdateFormField(pFormFillEnv, pFormField, true, false, true);
        }
        break;
      }
      default:
        break;
    }
  }
}

CJS_Return Field::get_value_as_string(CJS_Runtime* pRuntime) {
  std::vector<CPDF_FormField*> FieldArray = GetFormFields(m_FieldName);
  if (FieldArray.empty())
    return CJS_Return(false);

  CPDF_FormField* pFormField = FieldArray[0];
  if (pFormField->GetFieldType() == FIELDTYPE_PUSHBUTTON)
    return CJS_Return(false);

  if (pFormField->GetFieldType() == FIELDTYPE_CHECKBOX) {
    if (!pFormField->CountControls())
      return CJS_Return(false);
    return CJS_Return(pRuntime->NewString(
        pFormField->GetControl(0)->IsChecked() ? L"Yes" : L"Off"));
  }

  if (pFormField->GetFieldType() == FIELDTYPE_RADIOBUTTON &&
      !(pFormField->GetFieldFlags() & FIELDFLAG_RADIOSINUNISON)) {
    for (int i = 0, sz = pFormField->CountControls(); i < sz; i++) {
      if (pFormField->GetControl(i)->IsChecked()) {
        return CJS_Return(pRuntime->NewString(
            pFormField->GetControl(i)->GetExportValue().c_str()));
      }
    }
    return CJS_Return(pRuntime->NewString(L"Off"));
  }

  if (pFormField->GetFieldType() == FIELDTYPE_LISTBOX &&
      (pFormField->CountSelectedItems() > 1)) {
    return CJS_Return(pRuntime->NewString(L""));
  }
  return CJS_Return(pRuntime->NewString(pFormField->GetValue().c_str()));
}

CJS_Return Field::set_value_as_string(CJS_Runtime* pRuntime,
                                      v8::Local<v8::Value> vp) {
  return CJS_Return(false);
}

CJS_Return Field::browseForFileToSubmit(
    CJS_Runtime* pRuntime,
    const std::vector<v8::Local<v8::Value>>& params) {
  std::vector<CPDF_FormField*> FieldArray = GetFormFields(m_FieldName);
  if (FieldArray.empty())
    return CJS_Return(false);

  CPDF_FormField* pFormField = FieldArray[0];
  if ((pFormField->GetFieldFlags() & FIELDFLAG_FILESELECT) &&
      (pFormField->GetFieldType() == FIELDTYPE_TEXTFIELD)) {
    WideString wsFileName = m_pFormFillEnv->JS_fieldBrowse();
    if (!wsFileName.IsEmpty()) {
      pFormField->SetValue(wsFileName);
      UpdateFormField(m_pFormFillEnv.Get(), pFormField, true, true, true);
    }
    return CJS_Return(true);
  }
  return CJS_Return(false);
}

CJS_Return Field::buttonGetCaption(
    CJS_Runtime* pRuntime,
    const std::vector<v8::Local<v8::Value>>& params) {
  int nface = 0;
  int iSize = params.size();
  if (iSize >= 1)
    nface = pRuntime->ToInt32(params[0]);

  std::vector<CPDF_FormField*> FieldArray = GetFormFields(m_FieldName);
  if (FieldArray.empty())
    return CJS_Return(false);

  CPDF_FormField* pFormField = FieldArray[0];
  if (pFormField->GetFieldType() != FIELDTYPE_PUSHBUTTON)
    return CJS_Return(false);

  CPDF_FormControl* pFormControl = GetSmartFieldControl(pFormField);
  if (!pFormControl)
    return CJS_Return(false);

  if (nface == 0) {
    return CJS_Return(
        pRuntime->NewString(pFormControl->GetNormalCaption().c_str()));
  } else if (nface == 1) {
    return CJS_Return(
        pRuntime->NewString(pFormControl->GetDownCaption().c_str()));
  } else if (nface == 2) {
    return CJS_Return(
        pRuntime->NewString(pFormControl->GetRolloverCaption().c_str()));
  }
  return CJS_Return(false);
}

CJS_Return Field::buttonGetIcon(
    CJS_Runtime* pRuntime,
    const std::vector<v8::Local<v8::Value>>& params) {
  if (params.size() >= 1) {
    int nFace = pRuntime->ToInt32(params[0]);
    if (nFace < 0 || nFace > 2)
      return CJS_Return(false);
  }

  std::vector<CPDF_FormField*> FieldArray = GetFormFields(m_FieldName);
  if (FieldArray.empty())
    return CJS_Return(false);

  CPDF_FormField* pFormField = FieldArray[0];
  if (pFormField->GetFieldType() != FIELDTYPE_PUSHBUTTON)
    return CJS_Return(false);

  CPDF_FormControl* pFormControl = GetSmartFieldControl(pFormField);
  if (!pFormControl)
    return CJS_Return(false);

  v8::Local<v8::Object> pObj =
      pRuntime->NewFxDynamicObj(CJS_Icon::g_nObjDefnID);
  if (pObj.IsEmpty())
    return CJS_Return(false);

  CJS_Icon* pJS_Icon = static_cast<CJS_Icon*>(pRuntime->GetObjectPrivate(pObj));
  if (!pJS_Icon)
    return CJS_Return(false);
  return CJS_Return(pJS_Icon->ToV8Object());
}

CJS_Return Field::buttonImportIcon(
    CJS_Runtime* pRuntime,
    const std::vector<v8::Local<v8::Value>>& params) {
  return CJS_Return(true);
}

CJS_Return Field::buttonSetCaption(
    CJS_Runtime* pRuntime,
    const std::vector<v8::Local<v8::Value>>& params) {
  return CJS_Return(false);
}

CJS_Return Field::buttonSetIcon(
    CJS_Runtime* pRuntime,
    const std::vector<v8::Local<v8::Value>>& params) {
  return CJS_Return(false);
}

CJS_Return Field::checkThisBox(
    CJS_Runtime* pRuntime,
    const std::vector<v8::Local<v8::Value>>& params) {
  int iSize = params.size();
  if (iSize < 1)
    return CJS_Return(false);

  if (!m_bCanSet)
    return CJS_Return(false);

  int nWidget = pRuntime->ToInt32(params[0]);
  bool bCheckit = true;
  if (iSize >= 2)
    bCheckit = pRuntime->ToBoolean(params[1]);

  std::vector<CPDF_FormField*> FieldArray = GetFormFields(m_FieldName);
  if (FieldArray.empty())
    return CJS_Return(false);

  CPDF_FormField* pFormField = FieldArray[0];
  if (pFormField->GetFieldType() != FIELDTYPE_CHECKBOX &&
      pFormField->GetFieldType() != FIELDTYPE_RADIOBUTTON) {
    return CJS_Return(false);
  }
  if (nWidget < 0 || nWidget >= pFormField->CountControls())
    return CJS_Return(false);
  // TODO(weili): Check whether anything special needed for radio button,
  // otherwise merge these branches.
  if (pFormField->GetFieldType() == FIELDTYPE_RADIOBUTTON)
    pFormField->CheckControl(nWidget, bCheckit, true);
  else
    pFormField->CheckControl(nWidget, bCheckit, true);

  UpdateFormField(m_pFormFillEnv.Get(), pFormField, true, true, true);
  return CJS_Return(true);
}

CJS_Return Field::clearItems(CJS_Runtime* pRuntime,
                             const std::vector<v8::Local<v8::Value>>& params) {
  return CJS_Return(true);
}

CJS_Return Field::defaultIsChecked(
    CJS_Runtime* pRuntime,
    const std::vector<v8::Local<v8::Value>>& params) {
  if (!m_bCanSet)
    return CJS_Return(false);

  int iSize = params.size();
  if (iSize < 1)
    return CJS_Return(false);

  int nWidget = pRuntime->ToInt32(params[0]);
  std::vector<CPDF_FormField*> FieldArray = GetFormFields(m_FieldName);
  if (FieldArray.empty())
    return CJS_Return(false);

  CPDF_FormField* pFormField = FieldArray[0];
  if (nWidget < 0 || nWidget >= pFormField->CountControls())
    return CJS_Return(false);

  return CJS_Return(pRuntime->NewBoolean(
      pFormField->GetFieldType() == FIELDTYPE_CHECKBOX ||
      pFormField->GetFieldType() == FIELDTYPE_RADIOBUTTON));
}

CJS_Return Field::deleteItemAt(
    CJS_Runtime* pRuntime,
    const std::vector<v8::Local<v8::Value>>& params) {
  return CJS_Return(true);
}

CJS_Return Field::getArray(CJS_Runtime* pRuntime,
                           const std::vector<v8::Local<v8::Value>>& params) {
  std::vector<CPDF_FormField*> FieldArray = GetFormFields(m_FieldName);
  if (FieldArray.empty())
    return CJS_Return(false);

  std::vector<std::unique_ptr<WideString>> swSort;
  for (CPDF_FormField* pFormField : FieldArray) {
    swSort.push_back(
        std::unique_ptr<WideString>(new WideString(pFormField->GetFullName())));
  }

  std::sort(swSort.begin(), swSort.end(),
            [](const std::unique_ptr<WideString>& p1,
               const std::unique_ptr<WideString>& p2) { return *p1 < *p2; });

  v8::Local<v8::Array> FormFieldArray = pRuntime->NewArray();
  int j = 0;
  for (const auto& pStr : swSort) {
    v8::Local<v8::Object> pObj =
        pRuntime->NewFxDynamicObj(CJS_Field::g_nObjDefnID);
    if (pObj.IsEmpty())
      return CJS_Return(false);

    CJS_Field* pJSField =
        static_cast<CJS_Field*>(pRuntime->GetObjectPrivate(pObj));
    Field* pField = static_cast<Field*>(pJSField->GetEmbedObject());
    pField->AttachField(m_pJSDoc, *pStr);
    pRuntime->PutArrayElement(FormFieldArray, j++,
                              pJSField
                                  ? v8::Local<v8::Value>(pJSField->ToV8Object())
                                  : v8::Local<v8::Value>());
  }
  return CJS_Return(FormFieldArray);
}

CJS_Return Field::getItemAt(CJS_Runtime* pRuntime,
                            const std::vector<v8::Local<v8::Value>>& params) {
  int iSize = params.size();
  int nIdx = -1;
  if (iSize >= 1)
    nIdx = pRuntime->ToInt32(params[0]);

  bool bExport = true;
  if (iSize >= 2)
    bExport = pRuntime->ToBoolean(params[1]);

  std::vector<CPDF_FormField*> FieldArray = GetFormFields(m_FieldName);
  if (FieldArray.empty())
    return CJS_Return(false);

  CPDF_FormField* pFormField = FieldArray[0];
  if ((pFormField->GetFieldType() == FIELDTYPE_LISTBOX) ||
      (pFormField->GetFieldType() == FIELDTYPE_COMBOBOX)) {
    if (nIdx == -1 || nIdx > pFormField->CountOptions())
      nIdx = pFormField->CountOptions() - 1;
    if (bExport) {
      WideString strval = pFormField->GetOptionValue(nIdx);
      if (strval.IsEmpty()) {
        return CJS_Return(
            pRuntime->NewString(pFormField->GetOptionLabel(nIdx).c_str()));
      }
      return CJS_Return(pRuntime->NewString(strval.c_str()));
    }
    return CJS_Return(
        pRuntime->NewString(pFormField->GetOptionLabel(nIdx).c_str()));
  }
  return CJS_Return(false);
}

CJS_Return Field::getLock(CJS_Runtime* pRuntime,
                          const std::vector<v8::Local<v8::Value>>& params) {
  return CJS_Return(false);
}

CJS_Return Field::insertItemAt(
    CJS_Runtime* pRuntime,
    const std::vector<v8::Local<v8::Value>>& params) {
  return CJS_Return(true);
}

CJS_Return Field::isBoxChecked(
    CJS_Runtime* pRuntime,
    const std::vector<v8::Local<v8::Value>>& params) {
  int nIndex = -1;
  if (params.size() >= 1)
    nIndex = pRuntime->ToInt32(params[0]);

  std::vector<CPDF_FormField*> FieldArray = GetFormFields(m_FieldName);
  if (FieldArray.empty())
    return CJS_Return(false);

  CPDF_FormField* pFormField = FieldArray[0];
  if (nIndex < 0 || nIndex >= pFormField->CountControls())
    return CJS_Return(false);

  return CJS_Return(pRuntime->NewBoolean(
      ((pFormField->GetFieldType() == FIELDTYPE_CHECKBOX ||
        pFormField->GetFieldType() == FIELDTYPE_RADIOBUTTON) &&
       pFormField->GetControl(nIndex)->IsChecked() != 0)));
}

CJS_Return Field::isDefaultChecked(
    CJS_Runtime* pRuntime,
    const std::vector<v8::Local<v8::Value>>& params) {
  int nIndex = -1;
  if (params.size() >= 1)
    nIndex = pRuntime->ToInt32(params[0]);

  std::vector<CPDF_FormField*> FieldArray = GetFormFields(m_FieldName);
  if (FieldArray.empty())
    return CJS_Return(false);

  CPDF_FormField* pFormField = FieldArray[0];
  if (nIndex < 0 || nIndex >= pFormField->CountControls())
    return CJS_Return(false);

  return CJS_Return(pRuntime->NewBoolean(
      ((pFormField->GetFieldType() == FIELDTYPE_CHECKBOX ||
        pFormField->GetFieldType() == FIELDTYPE_RADIOBUTTON) &&
       pFormField->GetControl(nIndex)->IsDefaultChecked() != 0)));
}

CJS_Return Field::setAction(CJS_Runtime* pRuntime,
                            const std::vector<v8::Local<v8::Value>>& params) {
  return CJS_Return(true);
}

CJS_Return Field::setFocus(CJS_Runtime* pRuntime,
                           const std::vector<v8::Local<v8::Value>>& params) {
  std::vector<CPDF_FormField*> FieldArray = GetFormFields(m_FieldName);
  if (FieldArray.empty())
    return CJS_Return(false);

  CPDF_FormField* pFormField = FieldArray[0];
  int32_t nCount = pFormField->CountControls();
  if (nCount < 1)
    return CJS_Return(false);

  CPDFSDK_InterForm* pInterForm = m_pFormFillEnv->GetInterForm();
  CPDFSDK_Widget* pWidget = nullptr;
  if (nCount == 1) {
    pWidget = pInterForm->GetWidget(pFormField->GetControl(0));
  } else {
    UnderlyingPageType* pPage =
        UnderlyingFromFPDFPage(m_pFormFillEnv->GetCurrentPage(
            m_pFormFillEnv->GetUnderlyingDocument()));
    if (!pPage)
      return CJS_Return(false);
    if (CPDFSDK_PageView* pCurPageView =
            m_pFormFillEnv->GetPageView(pPage, true)) {
      for (int32_t i = 0; i < nCount; i++) {
        if (CPDFSDK_Widget* pTempWidget =
                pInterForm->GetWidget(pFormField->GetControl(i))) {
          if (pTempWidget->GetPDFPage() == pCurPageView->GetPDFPage()) {
            pWidget = pTempWidget;
            break;
          }
        }
      }
    }
  }

  if (pWidget) {
    CPDFSDK_Annot::ObservedPtr pObserved(pWidget);
    m_pFormFillEnv->SetFocusAnnot(&pObserved);
  }

  return CJS_Return(true);
}

CJS_Return Field::setItems(CJS_Runtime* pRuntime,
                           const std::vector<v8::Local<v8::Value>>& params) {
  return CJS_Return(true);
}

CJS_Return Field::setLock(CJS_Runtime* pRuntime,
                          const std::vector<v8::Local<v8::Value>>& params) {
  return CJS_Return(false);
}

CJS_Return Field::signatureGetModifications(
    CJS_Runtime* pRuntime,
    const std::vector<v8::Local<v8::Value>>& params) {
  return CJS_Return(false);
}

CJS_Return Field::signatureGetSeedValue(
    CJS_Runtime* pRuntime,
    const std::vector<v8::Local<v8::Value>>& params) {
  return CJS_Return(false);
}

CJS_Return Field::signatureInfo(
    CJS_Runtime* pRuntime,
    const std::vector<v8::Local<v8::Value>>& params) {
  return CJS_Return(false);
}

CJS_Return Field::signatureSetSeedValue(
    CJS_Runtime* pRuntime,
    const std::vector<v8::Local<v8::Value>>& params) {
  return CJS_Return(false);
}

CJS_Return Field::signatureSign(
    CJS_Runtime* pRuntime,
    const std::vector<v8::Local<v8::Value>>& params) {
  return CJS_Return(false);
}

CJS_Return Field::signatureValidate(
    CJS_Runtime* pRuntime,
    const std::vector<v8::Local<v8::Value>>& params) {
  return CJS_Return(false);
}

CJS_Return Field::get_source(CJS_Runtime* pRuntime) {
  return CJS_Return(true);
}

CJS_Return Field::set_source(CJS_Runtime* pRuntime, v8::Local<v8::Value> vp) {
  return CJS_Return(true);
}

void Field::AddDelay_Int(FIELD_PROP prop, int32_t n) {
  CJS_DelayData* pNewData =
      new CJS_DelayData(prop, m_nFormControlIndex, m_FieldName);
  pNewData->num = n;
  m_pJSDoc->AddDelayData(pNewData);
}

void Field::AddDelay_Bool(FIELD_PROP prop, bool b) {
  CJS_DelayData* pNewData =
      new CJS_DelayData(prop, m_nFormControlIndex, m_FieldName);
  pNewData->b = b;
  m_pJSDoc->AddDelayData(pNewData);
}

void Field::AddDelay_String(FIELD_PROP prop, const ByteString& string) {
  CJS_DelayData* pNewData =
      new CJS_DelayData(prop, m_nFormControlIndex, m_FieldName);
  pNewData->string = string;
  m_pJSDoc->AddDelayData(pNewData);
}

void Field::AddDelay_Rect(FIELD_PROP prop, const CFX_FloatRect& rect) {
  CJS_DelayData* pNewData =
      new CJS_DelayData(prop, m_nFormControlIndex, m_FieldName);
  pNewData->rect = rect;
  m_pJSDoc->AddDelayData(pNewData);
}

void Field::AddDelay_WordArray(FIELD_PROP prop,
                               const std::vector<uint32_t>& array) {
  CJS_DelayData* pNewData =
      new CJS_DelayData(prop, m_nFormControlIndex, m_FieldName);
  pNewData->wordarray = array;
  m_pJSDoc->AddDelayData(pNewData);
}

void Field::AddDelay_WideStringArray(FIELD_PROP prop,
                                     const std::vector<WideString>& array) {
  CJS_DelayData* pNewData =
      new CJS_DelayData(prop, m_nFormControlIndex, m_FieldName);
  pNewData->widestringarray = array;
  m_pJSDoc->AddDelayData(pNewData);
}

void Field::DoDelay(CPDFSDK_FormFillEnvironment* pFormFillEnv,
                    CJS_DelayData* pData) {
  ASSERT(pFormFillEnv);
  switch (pData->eProp) {
    case FP_BORDERSTYLE:
      Field::SetBorderStyle(pFormFillEnv, pData->sFieldName,
                            pData->nControlIndex, pData->string);
      break;
    case FP_CURRENTVALUEINDICES:
      Field::SetCurrentValueIndices(pFormFillEnv, pData->sFieldName,
                                    pData->nControlIndex, pData->wordarray);
      break;
    case FP_DISPLAY:
      Field::SetDisplay(pFormFillEnv, pData->sFieldName, pData->nControlIndex,
                        pData->num);
      break;
    case FP_HIDDEN:
      Field::SetHidden(pFormFillEnv, pData->sFieldName, pData->nControlIndex,
                       pData->b);
      break;
    case FP_LINEWIDTH:
      Field::SetLineWidth(pFormFillEnv, pData->sFieldName, pData->nControlIndex,
                          pData->num);
      break;
    case FP_RECT:
      Field::SetRect(pFormFillEnv, pData->sFieldName, pData->nControlIndex,
                     pData->rect);
      break;
    case FP_VALUE:
      Field::SetValue(pFormFillEnv, pData->sFieldName, pData->nControlIndex,
                      pData->widestringarray);
      break;
    default:
      NOTREACHED();
  }
}
