// 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 "fxjs/cjs_field.h"

#include <algorithm>
#include <memory>
#include <utility>

#include "core/fpdfapi/font/cpdf_font.h"
#include "core/fpdfdoc/cpdf_formfield.h"
#include "core/fpdfdoc/cpdf_interform.h"
#include "fpdfsdk/cpdfsdk_interform.h"
#include "fpdfsdk/cpdfsdk_pageview.h"
#include "fpdfsdk/cpdfsdk_widget.h"
#include "fxjs/cjs_color.h"
#include "fxjs/cjs_delaydata.h"
#include "fxjs/cjs_document.h"
#include "fxjs/cjs_icon.h"
#include "fxjs/js_resources.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

const 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}};

const 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}};

int CJS_Field::ObjDefnID = -1;

// static
int CJS_Field::GetObjDefnID() {
  return ObjDefnID;
}

// static
void CJS_Field::DefineJSObjects(CFXJS_Engine* pEngine) {
  ObjDefnID = pEngine->DefineObj("Field", FXJSOBJTYPE_DYNAMIC,
                                 JSConstructor<CJS_Field, Field>, JSDestructor);
  DefineProps(pEngine, ObjDefnID, PropertySpecs, FX_ArraySize(PropertySpecs));
  DefineMethods(pEngine, ObjDefnID, MethodSpecs, FX_ArraySize(MethodSpecs));
}

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);

    FormFieldType fieldType = pFormField->GetFieldType();
    if (fieldType == FormFieldType::kComboBox ||
        fieldType == FormFieldType::kTextField) {
      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) {
      FormFieldType fieldType = pWidget->GetFieldType();
      if (fieldType == FormFieldType::kComboBox ||
          fieldType == FormFieldType::kTextField) {
        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() != FormFieldType::kTextField)
    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() != FormFieldType::kPushButton)
    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() != FormFieldType::kPushButton)
    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() != FormFieldType::kPushButton)
    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() != FormFieldType::kPushButton)
    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() != FormFieldType::kPushButton)
    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() != FormFieldType::kPushButton)
    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() != FormFieldType::kComboBox &&
      pFormField->GetFieldType() != FormFieldType::kTextField) {
    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() != FormFieldType::kTextField)
    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() != FormFieldType::kTextField)
    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() != FormFieldType::kComboBox &&
      pFormField->GetFieldType() != FormFieldType::kListBox) {
    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() != FormFieldType::kComboBox &&
      pFormField->GetFieldType() != FormFieldType::kListBox) {
    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) {
    FormFieldType fieldType = pFormField->GetFieldType();
    if (fieldType == FormFieldType::kComboBox ||
        fieldType == FormFieldType::kListBox) {
      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() == FormFieldType::kPushButton ||
      pFormField->GetFieldType() == FormFieldType::kSignature) {
    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() != FormFieldType::kTextField)
    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() != FormFieldType::kTextField &&
      pFormField->GetFieldType() != FormFieldType::kComboBox) {
    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() != FormFieldType::kComboBox)
    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() != FormFieldType::kCheckBox &&
      pFormField->GetFieldType() != FormFieldType::kRadioButton) {
    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() != FormFieldType::kCheckBox &&
      pFormField->GetFieldType() != FormFieldType::kRadioButton) {
    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() != FormFieldType::kTextField)
    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() != FormFieldType::kTextField)
    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() != FormFieldType::kPushButton)
    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() != FormFieldType::kTextField)
    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() != FormFieldType::kListBox)
    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() != FormFieldType::kComboBox &&
      pFormField->GetFieldType() != FormFieldType::kListBox) {
    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(JSMessage::kBadObjectError));

    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(JSMessage::kReadOnlyError));
}

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() != FormFieldType::kTextField)
    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() != FormFieldType::kRadioButton)
    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() == FormFieldType::kPushButton)
    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() != FormFieldType::kTextField)
    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() != FormFieldType::kRadioButton &&
      pFormField->GetFieldType() != FormFieldType::kCheckBox) {
    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);

  FormFieldType fieldType = pFormField->GetFieldType();
  if (fieldType != FormFieldType::kPushButton &&
      fieldType != FormFieldType::kComboBox &&
      fieldType != FormFieldType::kListBox &&
      fieldType != FormFieldType::kTextField) {
    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 FormFieldType::kUnknown:
      return CJS_Return(pRuntime->NewString(L"unknown"));
    case FormFieldType::kPushButton:
      return CJS_Return(pRuntime->NewString(L"button"));
    case FormFieldType::kCheckBox:
      return CJS_Return(pRuntime->NewString(L"checkbox"));
    case FormFieldType::kRadioButton:
      return CJS_Return(pRuntime->NewString(L"radiobutton"));
    case FormFieldType::kComboBox:
      return CJS_Return(pRuntime->NewString(L"combobox"));
    case FormFieldType::kListBox:
      return CJS_Return(pRuntime->NewString(L"listbox"));
    case FormFieldType::kTextField:
      return CJS_Return(pRuntime->NewString(L"text"));
    case FormFieldType::kSignature:
      return CJS_Return(pRuntime->NewString(L"signature"));
    default:
      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 FormFieldType::kPushButton:
      return CJS_Return(false);
    case FormFieldType::kComboBox:
    case FormFieldType::kTextField:
      ret = pRuntime->NewString(pFormField->GetValue().c_str());
      break;
    case FormFieldType::kListBox: {
      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 FormFieldType::kCheckBox:
    case FormFieldType::kRadioButton: {
      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 FormFieldType::kTextField:
      case FormFieldType::kComboBox:
        if (pFormField->GetValue() != strArray[0]) {
          pFormField->SetValue(strArray[0], true);
          UpdateFormField(pFormFillEnv, pFormField, true, false, true);
        }
        break;
      case FormFieldType::kCheckBox:
      case FormFieldType::kRadioButton:
        if (pFormField->GetValue() != strArray[0]) {
          pFormField->SetValue(strArray[0], true);
          UpdateFormField(pFormFillEnv, pFormField, true, false, true);
        }
        break;
      case FormFieldType::kListBox: {
        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() == FormFieldType::kPushButton)
    return CJS_Return(false);

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

  if (pFormField->GetFieldType() == FormFieldType::kRadioButton &&
      !(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() == FormFieldType::kListBox &&
      (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() == FormFieldType::kTextField)) {
    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() != FormFieldType::kPushButton)
    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() != FormFieldType::kPushButton)
    return CJS_Return(false);

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

  v8::Local<v8::Object> pObj =
      pRuntime->NewFxDynamicObj(CJS_Icon::GetObjDefnID());
  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() != FormFieldType::kCheckBox &&
      pFormField->GetFieldType() != FormFieldType::kRadioButton) {
    return CJS_Return(false);
  }
  if (nWidget < 0 || nWidget >= pFormField->CountControls())
    return CJS_Return(false);

  // TODO(weili): Check whether anything special needed for radio button.
  // (When pFormField->GetFieldType() == FormFieldType::kRadioButton.)
  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() == FormFieldType::kCheckBox ||
      pFormField->GetFieldType() == FormFieldType::kRadioButton));
}

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::GetObjDefnID());
    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() == FormFieldType::kListBox) ||
      (pFormField->GetFieldType() == FormFieldType::kComboBox)) {
    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() == FormFieldType::kCheckBox ||
        pFormField->GetFieldType() == FormFieldType::kRadioButton) &&
       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() == FormFieldType::kCheckBox ||
        pFormField->GetFieldType() == FormFieldType::kRadioButton) &&
       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) {
  auto pNewData =
      pdfium::MakeUnique<CJS_DelayData>(prop, m_nFormControlIndex, m_FieldName);
  pNewData->num = n;
  m_pJSDoc->AddDelayData(std::move(pNewData));
}

void Field::AddDelay_Bool(FIELD_PROP prop, bool b) {
  auto pNewData =
      pdfium::MakeUnique<CJS_DelayData>(prop, m_nFormControlIndex, m_FieldName);
  pNewData->b = b;
  m_pJSDoc->AddDelayData(std::move(pNewData));
}

void Field::AddDelay_String(FIELD_PROP prop, const ByteString& string) {
  auto pNewData =
      pdfium::MakeUnique<CJS_DelayData>(prop, m_nFormControlIndex, m_FieldName);
  pNewData->string = string;
  m_pJSDoc->AddDelayData(std::move(pNewData));
}

void Field::AddDelay_Rect(FIELD_PROP prop, const CFX_FloatRect& rect) {
  auto pNewData =
      pdfium::MakeUnique<CJS_DelayData>(prop, m_nFormControlIndex, m_FieldName);
  pNewData->rect = rect;
  m_pJSDoc->AddDelayData(std::move(pNewData));
}

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

void Field::AddDelay_WideStringArray(FIELD_PROP prop,
                                     const std::vector<WideString>& array) {
  auto pNewData =
      pdfium::MakeUnique<CJS_DelayData>(prop, m_nFormControlIndex, m_FieldName);
  pNewData->widestringarray = array;
  m_pJSDoc->AddDelayData(std::move(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();
  }
}
