// Copyright 2014 The PDFium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com

#include "fxjs/cjs_publicmethods.h"

#include <math.h>

#include <algorithm>
#include <array>
#include <iomanip>
#include <iterator>
#include <limits>
#include <optional>
#include <sstream>
#include <string>
#include <utility>
#include <vector>

#include "build/build_config.h"
#include "core/fpdfapi/parser/cpdf_stream.h"
#include "core/fpdfdoc/cpdf_formcontrol.h"
#include "core/fpdfdoc/cpdf_interactiveform.h"
#include "core/fxcrt/check.h"
#include "core/fxcrt/compiler_specific.h"
#include "core/fxcrt/fx_extension.h"
#include "core/fxcrt/fx_string_wrappers.h"
#include "core/fxcrt/numerics/safe_conversions.h"
#include "core/fxcrt/span.h"
#include "core/fxge/cfx_color.h"
#include "fpdfsdk/cpdfsdk_formfillenvironment.h"
#include "fpdfsdk/cpdfsdk_interactiveform.h"
#include "fxjs/cjs_color.h"
#include "fxjs/cjs_event_context.h"
#include "fxjs/cjs_field.h"
#include "fxjs/cjs_object.h"
#include "fxjs/cjs_runtime.h"
#include "fxjs/cjs_util.h"
#include "fxjs/fx_date_helpers.h"
#include "fxjs/js_define.h"
#include "fxjs/js_resources.h"
#include "v8/include/v8-container.h"

// static
const JSMethodSpec CJS_PublicMethods::GlobalFunctionSpecs[] = {
    {"AFDate_Format", AFDate_Format_static},
    {"AFDate_FormatEx", AFDate_FormatEx_static},
    {"AFDate_Keystroke", AFDate_Keystroke_static},
    {"AFDate_KeystrokeEx", AFDate_KeystrokeEx_static},
    {"AFExtractNums", AFExtractNums_static},
    {"AFMakeNumber", AFMakeNumber_static},
    {"AFMergeChange", AFMergeChange_static},
    {"AFNumber_Format", AFNumber_Format_static},
    {"AFNumber_Keystroke", AFNumber_Keystroke_static},
    {"AFParseDateEx", AFParseDateEx_static},
    {"AFPercent_Format", AFPercent_Format_static},
    {"AFPercent_Keystroke", AFPercent_Keystroke_static},
    {"AFRange_Validate", AFRange_Validate_static},
    {"AFSimple", AFSimple_static},
    {"AFSimple_Calculate", AFSimple_Calculate_static},
    {"AFSpecial_Format", AFSpecial_Format_static},
    {"AFSpecial_Keystroke", AFSpecial_Keystroke_static},
    {"AFSpecial_KeystrokeEx", AFSpecial_KeystrokeEx_static},
    {"AFTime_Format", AFTime_Format_static},
    {"AFTime_FormatEx", AFTime_FormatEx_static},
    {"AFTime_Keystroke", AFTime_Keystroke_static},
    {"AFTime_KeystrokeEx", AFTime_KeystrokeEx_static},
};

namespace {

#if !BUILDFLAG(IS_ANDROID)
constexpr double kDoubleCorrect = 0.000000000000001;
#endif

constexpr std::array<const char*, 14> kDateFormats = {
    {"m/d", "m/d/yy", "mm/dd/yy", "mm/yy", "d-mmm", "d-mmm-yy", "dd-mmm-yy",
     "yy-mm-dd", "mmm-yy", "mmmm-yy", "mmm d, yyyy", "mmmm d, yyyy",
     "m/d/yy h:MM tt", "m/d/yy HH:MM"}};

constexpr std::array<const char*, 4> kTimeFormats = {
    {"HH:MM", "h:MM tt", "HH:MM:ss", "h:MM:ss tt"}};

template <typename T>
T StrTrim(const T& str) {
  T result = str;
  result.Trim(' ');
  return result;
}

void AlertIfPossible(CJS_EventContext* pContext,
                     const WideString& wsCaller,
                     const WideString& wsMsg) {
  CPDFSDK_FormFillEnvironment* pFormFillEnv = pContext->GetFormFillEnv();
  if (pFormFillEnv) {
    pFormFillEnv->JS_appAlert(wsMsg, wsCaller, JSPLATFORM_ALERT_BUTTON_OK,
                              JSPLATFORM_ALERT_ICON_STATUS);
  }
}

#if !BUILDFLAG(IS_ANDROID)
ByteString CalculateString(double dValue,
                           int iDec,
                           int* iDec2,
                           bool* bNegative) {
  *bNegative = dValue < 0;
  if (*bNegative)
    dValue = -dValue;

  // Make sure the number of precision characters will fit.
  iDec = std::min(iDec, std::numeric_limits<double>::digits10);

  fxcrt::ostringstream ss;
  ss << std::fixed << std::setprecision(iDec) << dValue;
  fxcrt::string value = ss.str();
  size_t pos = value.find('.');
  *iDec2 = pdfium::checked_cast<int>(pos == fxcrt::string::npos ? value.size()
                                                                : pos);
  return ByteString(value.c_str());
}
#endif

WideString CalcMergedString(const CJS_EventContext* event,
                            const WideString& value,
                            const WideString& change) {
  WideString prefix = value.First(event->SelStart());
  WideString postfix;
  int end = event->SelEnd();
  if (end >= 0 && static_cast<size_t>(end) < value.GetLength())
    postfix = value.Last(value.GetLength() - static_cast<size_t>(end));
  return prefix + change + postfix;
}

template <CJS_Result (*F)(CJS_Runtime*, pdfium::span<v8::Local<v8::Value>>)>
void JSGlobalFunc(const char* func_name_string,
                  const v8::FunctionCallbackInfo<v8::Value>& info) {
  auto* pObj = static_cast<CJS_Object*>(
      CFXJS_Engine::GetBinding(info.GetIsolate(), info.This()));
  if (!pObj)
    return;

  CJS_Runtime* pRuntime = pObj->GetRuntime();
  if (!pRuntime)
    return;

  v8::LocalVector<v8::Value> parameters(info.GetIsolate());
  for (int i = 0; i < info.Length(); ++i)
    parameters.push_back(info[i]);

  CJS_Result result = (*F)(pRuntime, parameters);
  if (result.HasError()) {
    pRuntime->Error(
        JSFormatErrorString(func_name_string, nullptr, result.Error()));
    return;
  }

  if (result.HasReturn())
    info.GetReturnValue().Set(result.Return());
}

int WithinBoundsOrZero(int value, size_t size) {
  return value >= 0 && static_cast<size_t>(value) < size ? value : 0;
}

int ValidStyleOrZero(int style) {
  return WithinBoundsOrZero(style, 4);
}

bool IsDigitSeparatorOrDecimalMark(int c) {
  return c == '.' || c == ',';
}

#if !BUILDFLAG(IS_ANDROID)
bool IsStyleWithDigitSeparator(int style) {
  return style == 0 || style == 2;
}

char DigitSeparatorForStyle(int style) {
  DCHECK(IsStyleWithDigitSeparator(style));
  return style == 0 ? ',' : '.';
}

bool IsStyleWithApostropheSeparator(int style) {
  return style >= 4;
}
#endif

bool IsStyleWithCommaDecimalMark(int style) {
  return style == 2 || style == 3;
}

char DecimalMarkForStyle(int style) {
  return IsStyleWithCommaDecimalMark(style) ? ',' : '.';
}

#if !BUILDFLAG(IS_ANDROID)
void NormalizeDecimalMark(ByteString* str) {
  str->Replace(",", ".");
}
#endif

void NormalizeDecimalMarkW(WideString* str) {
  str->Replace(L",", L".");
}

std::optional<double> ApplyNamedOperation(const WideString& wsFunction,
                                          double dValue1,
                                          double dValue2) {
  if (wsFunction.EqualsASCIINoCase("AVG") ||
      wsFunction.EqualsASCIINoCase("SUM")) {
    return dValue1 + dValue2;
  }
  if (wsFunction.EqualsASCIINoCase("PRD"))
    return dValue1 * dValue2;
  if (wsFunction.EqualsASCIINoCase("MIN"))
    return std::min(dValue1, dValue2);
  if (wsFunction.EqualsASCIINoCase("MAX"))
    return std::max(dValue1, dValue2);
  return std::nullopt;
}

}  // namespace

// static
void CJS_PublicMethods::DefineJSObjects(CFXJS_Engine* pEngine) {
  for (const auto& spec : GlobalFunctionSpecs)
    pEngine->DefineGlobalMethod(spec.pName, spec.pMethodCall);
}

#define JS_STATIC_GLOBAL_FUN(fun_name)                   \
  void CJS_PublicMethods::fun_name##_static(             \
      const v8::FunctionCallbackInfo<v8::Value>& info) { \
    JSGlobalFunc<fun_name>(#fun_name, info);             \
  }

JS_STATIC_GLOBAL_FUN(AFNumber_Format)
JS_STATIC_GLOBAL_FUN(AFNumber_Keystroke)
JS_STATIC_GLOBAL_FUN(AFPercent_Format)
JS_STATIC_GLOBAL_FUN(AFPercent_Keystroke)
JS_STATIC_GLOBAL_FUN(AFDate_FormatEx)
JS_STATIC_GLOBAL_FUN(AFDate_KeystrokeEx)
JS_STATIC_GLOBAL_FUN(AFDate_Format)
JS_STATIC_GLOBAL_FUN(AFDate_Keystroke)
JS_STATIC_GLOBAL_FUN(AFTime_FormatEx)
JS_STATIC_GLOBAL_FUN(AFTime_KeystrokeEx)
JS_STATIC_GLOBAL_FUN(AFTime_Format)
JS_STATIC_GLOBAL_FUN(AFTime_Keystroke)
JS_STATIC_GLOBAL_FUN(AFSpecial_Format)
JS_STATIC_GLOBAL_FUN(AFSpecial_Keystroke)
JS_STATIC_GLOBAL_FUN(AFSpecial_KeystrokeEx)
JS_STATIC_GLOBAL_FUN(AFSimple)
JS_STATIC_GLOBAL_FUN(AFMakeNumber)
JS_STATIC_GLOBAL_FUN(AFSimple_Calculate)
JS_STATIC_GLOBAL_FUN(AFRange_Validate)
JS_STATIC_GLOBAL_FUN(AFMergeChange)
JS_STATIC_GLOBAL_FUN(AFParseDateEx)
JS_STATIC_GLOBAL_FUN(AFExtractNums)

bool CJS_PublicMethods::IsNumber(const WideString& str) {
  WideString sTrim = StrTrim(str);
  const wchar_t* pTrim = sTrim.c_str();
  const wchar_t* p = pTrim;
  bool bDot = false;
  bool bKXJS = false;

  UNSAFE_TODO({
    wchar_t c;
    while ((c = *p) != L'\0') {
      if (IsDigitSeparatorOrDecimalMark(c)) {
        if (bDot) {
          return false;
        }
        bDot = true;
      } else if (c == L'-' || c == L'+') {
        if (p != pTrim) {
          return false;
        }
      } else if (c == L'e' || c == L'E') {
        if (bKXJS) {
          return false;
        }

        p++;
        c = *p;
        if (c != L'+' && c != L'-') {
          return false;
        }
        bKXJS = true;
      } else if (!FXSYS_IsDecimalDigit(c)) {
        return false;
      }
      p++;
    }
  });
  return true;
}

bool CJS_PublicMethods::MaskSatisfied(wchar_t c_Change, wchar_t c_Mask) {
  switch (c_Mask) {
    case L'9':
      return !!FXSYS_IsDecimalDigit(c_Change);
    case L'A':
      return isascii(c_Change) && isalpha(c_Change);
    case L'O':
      return isascii(c_Change) && isalnum(c_Change);
    case L'X':
      return true;
    default:
      return (c_Change == c_Mask);
  }
}

bool CJS_PublicMethods::IsReservedMaskChar(wchar_t ch) {
  return ch == L'9' || ch == L'A' || ch == L'O' || ch == L'X';
}

v8::Local<v8::Array> CJS_PublicMethods::AF_MakeArrayFromList(
    CJS_Runtime* pRuntime,
    v8::Local<v8::Value> val) {
  DCHECK(!val.IsEmpty());
  if (val->IsArray())
    return pRuntime->ToArray(val);

  DCHECK(val->IsString());
  ByteString bsVal = pRuntime->ToByteString(val);
  const char* p = bsVal.c_str();

  int nIndex = 0;
  v8::Local<v8::Array> StrArray = pRuntime->NewArray();

  UNSAFE_TODO({
    while (*p) {
      const char* pTemp = strchr(p, ',');
      if (!pTemp) {
        pRuntime->PutArrayElement(
            StrArray, nIndex,
            pRuntime->NewString(StrTrim(ByteString(p)).AsStringView()));
        break;
      }

      pRuntime->PutArrayElement(
          StrArray, nIndex,
          pRuntime->NewString(
              StrTrim(ByteString(p, pTemp - p)).AsStringView()));

      nIndex++;
      p = ++pTemp;
    }
  });
  return StrArray;
}

double CJS_PublicMethods::ParseDate(v8::Isolate* isolate,
                                    const WideString& value,
                                    bool* bWrongFormat) {
  double dt = FX_GetDateTime();
  int nYear = FX_GetYearFromTime(dt);
  int nMonth = FX_GetMonthFromTime(dt) + 1;
  int nDay = FX_GetDayFromTime(dt);
  int nHour = FX_GetHourFromTime(dt);
  int nMin = FX_GetMinFromTime(dt);
  int nSec = FX_GetSecFromTime(dt);

  std::array<int, 3> number;

  size_t nSkip = 0;
  size_t nLen = value.GetLength();
  size_t nIndex = 0;
  size_t i = 0;
  while (i < nLen) {
    if (nIndex > 2)
      break;

    wchar_t c = value[i];
    if (FXSYS_IsDecimalDigit(c)) {
      number[nIndex++] = FX_ParseStringInteger(value, i, &nSkip, 4);
      i += nSkip;
    } else {
      i++;
    }
  }

  if (nIndex == 2) {
    // TODO(thestig): Should the else case set |bWrongFormat| to true?
    // case2: month/day
    // case3: day/month
    if (FX_IsValidMonth(number[0]) && FX_IsValidDay(number[1])) {
      nMonth = number[0];
      nDay = number[1];
    } else if (FX_IsValidDay(number[0]) && FX_IsValidMonth(number[1])) {
      nDay = number[0];
      nMonth = number[1];
    }

    if (bWrongFormat)
      *bWrongFormat = false;
  } else if (nIndex == 3) {
    // TODO(thestig): Should the else case set |bWrongFormat| to true?
    // case1: year/month/day
    // case2: month/day/year
    // case3: day/month/year
    if (number[0] > 12 && FX_IsValidMonth(number[1]) &&
        FX_IsValidDay(number[2])) {
      nYear = number[0];
      nMonth = number[1];
      nDay = number[2];
    } else if (FX_IsValidMonth(number[0]) && FX_IsValidDay(number[1]) &&
               number[2] > 31) {
      nMonth = number[0];
      nDay = number[1];
      nYear = number[2];
    } else if (FX_IsValidDay(number[0]) && FX_IsValidMonth(number[1]) &&
               number[2] > 31) {
      nDay = number[0];
      nMonth = number[1];
      nYear = number[2];
    }

    if (bWrongFormat)
      *bWrongFormat = false;
  } else {
    if (bWrongFormat)
      *bWrongFormat = true;
    return dt;
  }

  // TODO(thestig): Should we set |bWrongFormat| to false here too?
  return JS_DateParse(
      isolate, WideString::Format(L"%d/%d/%d %d:%d:%d", nMonth, nDay, nYear,
                                  nHour, nMin, nSec));
}

double CJS_PublicMethods::ParseDateUsingFormat(v8::Isolate* isolate,
                                               const WideString& value,
                                               const WideString& format,
                                               bool* bWrongFormat) {
  double dRet = nan("");
  fxjs::ConversionStatus status = FX_ParseDateUsingFormat(value, format, &dRet);
  if (status == fxjs::ConversionStatus::kSuccess)
    return dRet;

  if (status == fxjs::ConversionStatus::kBadDate) {
    dRet = JS_DateParse(isolate, value);
    if (!isnan(dRet))
      return dRet;
  }

  bool bBadFormat = false;
  dRet = ParseDate(isolate, value, &bBadFormat);
  if (bWrongFormat)
    *bWrongFormat = bBadFormat;

  return dRet;
}

WideString CJS_PublicMethods::PrintDateUsingFormat(double dDate,
                                                   const WideString& format) {
  WideString sRet;
  WideString sPart;

  int nYear = FX_GetYearFromTime(dDate);
  int nMonth = FX_GetMonthFromTime(dDate) + 1;
  int nDay = FX_GetDayFromTime(dDate);
  int nHour = FX_GetHourFromTime(dDate);
  int nMin = FX_GetMinFromTime(dDate);
  int nSec = FX_GetSecFromTime(dDate);

  size_t i = 0;
  while (i < format.GetLength()) {
    wchar_t c = format[i];
    size_t remaining = format.GetLength() - i - 1;
    sPart.clear();
    switch (c) {
      case 'y':
      case 'm':
      case 'd':
      case 'H':
      case 'h':
      case 'M':
      case 's':
      case 't':
        if (remaining == 0 || format[i + 1] != c) {
          switch (c) {
            case 'y':
              sPart += c;
              break;
            case 'm':
              sPart = WideString::FormatInteger(nMonth);
              break;
            case 'd':
              sPart = WideString::FormatInteger(nDay);
              break;
            case 'H':
              sPart = WideString::FormatInteger(nHour);
              break;
            case 'h':
              sPart =
                  WideString::FormatInteger(nHour > 12 ? nHour - 12 : nHour);
              break;
            case 'M':
              sPart = WideString::FormatInteger(nMin);
              break;
            case 's':
              sPart = WideString::FormatInteger(nSec);
              break;
            case 't':
              sPart += nHour > 12 ? 'p' : 'a';
              break;
          }
          i++;
        } else if (remaining == 1 || format[i + 2] != c) {
          switch (c) {
            case 'y':
              sPart = WideString::Format(L"%02d", nYear - (nYear / 100) * 100);
              break;
            case 'm':
              sPart = WideString::Format(L"%02d", nMonth);
              break;
            case 'd':
              sPart = WideString::Format(L"%02d", nDay);
              break;
            case 'H':
              sPart = WideString::Format(L"%02d", nHour);
              break;
            case 'h':
              sPart =
                  WideString::Format(L"%02d", nHour > 12 ? nHour - 12 : nHour);
              break;
            case 'M':
              sPart = WideString::Format(L"%02d", nMin);
              break;
            case 's':
              sPart = WideString::Format(L"%02d", nSec);
              break;
            case 't':
              sPart = nHour > 12 ? L"pm" : L"am";
              break;
          }
          i += 2;
        } else if (remaining == 2 || format[i + 3] != c) {
          switch (c) {
            case 'm':
              i += 3;
              if (FX_IsValidMonth(nMonth))
                sPart += WideString::FromASCII(fxjs::kMonths[nMonth - 1]);
              break;
            default:
              i += 3;
              sPart += c;
              sPart += c;
              sPart += c;
              break;
          }
        } else if (remaining == 3 || format[i + 4] != c) {
          switch (c) {
            case 'y':
              sPart = WideString::Format(L"%04d", nYear);
              i += 4;
              break;
            case 'm':
              i += 4;
              if (FX_IsValidMonth(nMonth))
                sPart += WideString::FromASCII(fxjs::kFullMonths[nMonth - 1]);
              break;
            default:
              i += 4;
              sPart += c;
              sPart += c;
              sPart += c;
              sPart += c;
              break;
          }
        } else {
          i++;
          sPart += c;
        }
        break;
      default:
        i++;
        sPart += c;
        break;
    }

    sRet += sPart;
  }

  return sRet;
}

// function AFNumber_Format(nDec, sepStyle, negStyle, currStyle, strCurrency,
// bCurrencyPrepend)
CJS_Result CJS_PublicMethods::AFNumber_Format(
    CJS_Runtime* pRuntime,
    pdfium::span<v8::Local<v8::Value>> params) {
#if !BUILDFLAG(IS_ANDROID)
  if (params.size() != 6)
    return CJS_Result::Failure(JSMessage::kParamError);

  CJS_EventContext* pEventContext = pRuntime->GetCurrentEventContext();
  if (!pEventContext->HasValue())
    return CJS_Result::Failure(WideString::FromASCII("No event handler"));

  WideString& Value = pEventContext->Value();
  ByteString strValue = StrTrim(Value.ToUTF8());
  if (strValue.IsEmpty())
    return CJS_Result::Success();

  int iDec = abs(pRuntime->ToInt32(params[0]));
  int iSepStyle = ValidStyleOrZero(pRuntime->ToInt32(params[1]));
  int iNegStyle = ValidStyleOrZero(pRuntime->ToInt32(params[2]));
  // params[3] is iCurrStyle, it's not used.
  WideString wstrCurrency = pRuntime->ToWideString(params[4]);
  bool bCurrencyPrepend = pRuntime->ToBoolean(params[5]);

  // Processing decimal places
  NormalizeDecimalMark(&strValue);

  // SAFETY: ByteStrings are always NUL-terminated.
  double dValue = UNSAFE_BUFFERS(atof(strValue.c_str()));
  if (iDec > 0)
    dValue += kDoubleCorrect;

  // Calculating number string
  bool bNegative;
  int iDec2;
  strValue = CalculateString(dValue, iDec, &iDec2, &bNegative);
  if (strValue.IsEmpty()) {
    dValue = 0;
    strValue = CalculateString(dValue, iDec, &iDec2, &bNegative);
    if (strValue.IsEmpty()) {
      strValue = "0";
      iDec2 = 1;
    }
  }
  DCHECK(iDec2 >= 0);

  // Processing separator style
  if (static_cast<size_t>(iDec2) < strValue.GetLength()) {
    if (IsStyleWithCommaDecimalMark(iSepStyle))
      strValue.Replace(".", ",");

    if (iDec2 == 0)
      strValue.Insert(iDec2, '0');
  }
  if (IsStyleWithDigitSeparator(iSepStyle)) {
    char cSeparator = DigitSeparatorForStyle(iSepStyle);
    for (int iDecPositive = iDec2 - 3; iDecPositive > 0; iDecPositive -= 3)
      strValue.Insert(iDecPositive, cSeparator);
  }

  // Processing currency string
  Value = WideString::FromUTF8(strValue.AsStringView());
  if (bCurrencyPrepend)
    Value = wstrCurrency + Value;
  else
    Value = Value + wstrCurrency;

  // Processing negative style
  if (bNegative) {
    if (iNegStyle == 0) {
      Value.InsertAtFront(L'-');
    } else if (iNegStyle == 2 || iNegStyle == 3) {
      Value.InsertAtFront(L'(');
      Value += L')';
    }
    if (iNegStyle == 1 || iNegStyle == 3) {
      if (CJS_Field* fTarget = pEventContext->TargetField()) {
        v8::Local<v8::Array> arColor = pRuntime->NewArray();
        pRuntime->PutArrayElement(arColor, 0, pRuntime->NewString("RGB"));
        pRuntime->PutArrayElement(arColor, 1, pRuntime->NewNumber(1));
        pRuntime->PutArrayElement(arColor, 2, pRuntime->NewNumber(0));
        pRuntime->PutArrayElement(arColor, 3, pRuntime->NewNumber(0));
        fTarget->set_text_color(pRuntime, arColor);
      }
    }
  } else {
    if (iNegStyle == 1 || iNegStyle == 3) {
      if (CJS_Field* fTarget = pEventContext->TargetField()) {
        v8::Local<v8::Array> arColor = pRuntime->NewArray();
        pRuntime->PutArrayElement(arColor, 0, pRuntime->NewString("RGB"));
        pRuntime->PutArrayElement(arColor, 1, pRuntime->NewNumber(0));
        pRuntime->PutArrayElement(arColor, 2, pRuntime->NewNumber(0));
        pRuntime->PutArrayElement(arColor, 3, pRuntime->NewNumber(0));

        CJS_Result result = fTarget->get_text_color(pRuntime);
        CFX_Color crProp = CJS_Color::ConvertArrayToPWLColor(
            pRuntime, pRuntime->ToArray(result.Return()));
        CFX_Color crColor =
            CJS_Color::ConvertArrayToPWLColor(pRuntime, arColor);
        if (crColor != crProp)
          fTarget->set_text_color(pRuntime, arColor);
      }
    }
  }
#endif
  return CJS_Result::Success();
}

// function AFNumber_Keystroke(nDec, sepStyle, negStyle, currStyle, strCurrency,
// bCurrencyPrepend)
CJS_Result CJS_PublicMethods::AFNumber_Keystroke(
    CJS_Runtime* pRuntime,
    pdfium::span<v8::Local<v8::Value>> params) {
  if (params.size() < 2)
    return CJS_Result::Failure(JSMessage::kParamError);

  CJS_EventContext* pContext = pRuntime->GetCurrentEventContext();
  if (!pContext->HasValue())
    return CJS_Result::Failure(JSMessage::kBadObjectError);

  WideString& val = pContext->Value();
  WideString& wstrChange = pContext->Change();
  WideString wstrValue = val;

  if (pContext->WillCommit()) {
    WideString swTemp = StrTrim(wstrValue);
    if (swTemp.IsEmpty())
      return CJS_Result::Success();

    NormalizeDecimalMarkW(&swTemp);
    if (!IsNumber(swTemp)) {
      pContext->Rc() = false;
      WideString sError = JSGetStringFromID(JSMessage::kInvalidInputError);
      AlertIfPossible(pContext, WideString::FromASCII("AFNumber_Keystroke"),
                      sError);
      return CJS_Result::Failure(sError);
    }
    // It happens after the last keystroke and before validating,
    return CJS_Result::Success();
  }

  WideString wstrSelected;
  if (pContext->SelStart() != -1) {
    wstrSelected = wstrValue.Substr(pContext->SelStart(),
                                    pContext->SelEnd() - pContext->SelStart());
  }

  bool bHasSign = wstrValue.Contains(L'-') && !wstrSelected.Contains(L'-');
  if (bHasSign) {
    // can't insert "change" in front of sign position.
    if (!wstrSelected.IsEmpty() && pContext->SelStart() == 0) {
      pContext->Rc() = false;
      return CJS_Result::Success();
    }
  }

  int iSepStyle = ValidStyleOrZero(pRuntime->ToInt32(params[1]));
  const wchar_t cSep = DecimalMarkForStyle(iSepStyle);

  bool bHasSep = wstrValue.Contains(cSep);
  for (size_t i = 0; i < wstrChange.GetLength(); ++i) {
    if (wstrChange[i] == cSep) {
      if (bHasSep) {
        pContext->Rc() = false;
        return CJS_Result::Success();
      }
      bHasSep = true;
      continue;
    }
    if (wstrChange[i] == L'-') {
      if (bHasSign) {
        pContext->Rc() = false;
        return CJS_Result::Success();
      }
      // sign's position is not correct
      if (i != 0) {
        pContext->Rc() = false;
        return CJS_Result::Success();
      }
      if (pContext->SelStart() != 0) {
        pContext->Rc() = false;
        return CJS_Result::Success();
      }
      bHasSign = true;
      continue;
    }

    if (!FXSYS_IsDecimalDigit(wstrChange[i])) {
      pContext->Rc() = false;
      return CJS_Result::Success();
    }
  }

  val = CalcMergedString(pContext, wstrValue, wstrChange);
  return CJS_Result::Success();
}

// function AFPercent_Format(nDec, sepStyle, bPercentPrepend)
CJS_Result CJS_PublicMethods::AFPercent_Format(
    CJS_Runtime* pRuntime,
    pdfium::span<v8::Local<v8::Value>> params) {
#if !BUILDFLAG(IS_ANDROID)
  if (params.size() < 2)
    return CJS_Result::Failure(JSMessage::kParamError);

  CJS_EventContext* pEvent = pRuntime->GetCurrentEventContext();
  if (!pEvent->HasValue())
    return CJS_Result::Failure(JSMessage::kBadObjectError);

  // Acrobat will accept this. Anything larger causes it to throw an error.
  static constexpr int kMaxSepStyle = 49;

  int iDec = pRuntime->ToInt32(params[0]);
  int iSepStyle = pRuntime->ToInt32(params[1]);
  // TODO(thestig): How do we handle negative raw |bPercentPrepend| values?
  bool bPercentPrepend = params.size() > 2 && pRuntime->ToBoolean(params[2]);
  if (iDec < 0 || iSepStyle < 0 || iSepStyle > kMaxSepStyle)
    return CJS_Result::Failure(JSMessage::kValueError);

  // When the |iDec| value is too big, Acrobat will just return "%".
  static constexpr int kDecLimit = 512;
  // This count must be in sync with |kDecLimit|.
  static constexpr size_t kDigitsInDecLimit = 3;
  WideString& Value = pEvent->Value();
  if (iDec > kDecLimit) {
    Value = L"%";
    return CJS_Result::Success();
  }

  ByteString strValue = StrTrim(Value.ToUTF8());
  if (strValue.IsEmpty())
    strValue = "0";

  // for processing decimal places
  // SAFETY: ByteStrings are always NUL-terminated.
  double dValue = UNSAFE_BUFFERS(atof(strValue.c_str()));
  dValue *= 100;

  size_t szNewSize;
  {
    // Figure out the format to use with FXSYS_snprintf() below.
    // |format| is small because |iDec| is limited in size.
    char format[sizeof("%.f") + kDigitsInDecLimit];  // e.g. "%.512f"
    FXSYS_snprintf(format, sizeof(format), "%%.%df", iDec);

    // Calculate the new size for |strValue| and get a span.
    size_t szBufferSize = iDec + 3;  // Negative sign, decimal point, and NUL.
    double dValueCopy = fabs(dValue);
    while (dValueCopy > 1) {
      dValueCopy /= 10;
      ++szBufferSize;
    }

    // Write into |strValue|.
    pdfium::span<char> span = strValue.GetBuffer(szBufferSize);
    UNSAFE_TODO(FXSYS_snprintf(span.data(), szBufferSize, format, dValue));
    szNewSize = UNSAFE_TODO(strlen(span.data()));
  }
  strValue.ReleaseBuffer(szNewSize);

  // for processing separator style
  std::optional<size_t> mark_pos = strValue.Find('.');
  if (mark_pos.has_value()) {
    char mark = DecimalMarkForStyle(iSepStyle);
    if (mark != '.')
      strValue.SetAt(mark_pos.value(), mark);
  }
  bool bUseDigitSeparator = IsStyleWithDigitSeparator(iSepStyle);
  if (bUseDigitSeparator || IsStyleWithApostropheSeparator(iSepStyle)) {
    char cSeparator =
        bUseDigitSeparator ? DigitSeparatorForStyle(iSepStyle) : '\'';
    int iEnd = mark_pos.value_or(strValue.GetLength());
    int iStop = dValue < 0 ? 1 : 0;
    for (int i = iEnd - 3; i > iStop; i -= 3)
      strValue.Insert(i, cSeparator);
  }

  if (bPercentPrepend)
    strValue.InsertAtFront('%');
  else
    strValue.InsertAtBack('%');
  Value = WideString::FromUTF8(strValue.AsStringView());
#endif
  return CJS_Result::Success();
}

// AFPercent_Keystroke(nDec, sepStyle)
CJS_Result CJS_PublicMethods::AFPercent_Keystroke(
    CJS_Runtime* pRuntime,
    pdfium::span<v8::Local<v8::Value>> params) {
  return AFNumber_Keystroke(pRuntime, params);
}

// function AFDate_FormatEx(cFormat)
CJS_Result CJS_PublicMethods::AFDate_FormatEx(
    CJS_Runtime* pRuntime,
    pdfium::span<v8::Local<v8::Value>> params) {
  if (params.size() != 1)
    return CJS_Result::Failure(JSMessage::kParamError);

  CJS_EventContext* pEvent = pRuntime->GetCurrentEventContext();
  if (!pEvent->HasValue())
    return CJS_Result::Failure(JSMessage::kBadObjectError);

  WideString& val = pEvent->Value();
  WideString strValue = val;
  if (strValue.IsEmpty())
    return CJS_Result::Success();

  WideString sFormat = pRuntime->ToWideString(params[0]);
  double dDate;
  if (strValue.Contains(L"GMT")) {
    // e.g. "Tue Aug 11 14:24:16 GMT+08002009"
    dDate = ParseDateAsGMT(pRuntime->GetIsolate(), strValue);
  } else {
    dDate = ParseDateUsingFormat(pRuntime->GetIsolate(), strValue, sFormat,
                                 nullptr);
  }

  if (isnan(dDate)) {
    WideString swMsg = WideString::Format(
        JSGetStringFromID(JSMessage::kParseDateError).c_str(), sFormat.c_str());
    AlertIfPossible(pEvent, WideString::FromASCII("AFDate_FormatEx"), swMsg);
    return CJS_Result::Failure(JSMessage::kParseDateError);
  }

  val = PrintDateUsingFormat(dDate, sFormat);
  return CJS_Result::Success();
}

double CJS_PublicMethods::ParseDateAsGMT(v8::Isolate* isolate,
                                         const WideString& strValue) {
  std::vector<WideString> wsArray;
  WideString sTemp;
  for (const auto& c : strValue) {
    if (c == L' ' || c == L':') {
      wsArray.push_back(std::move(sTemp));
      continue;
    }
    sTemp += c;
  }
  wsArray.push_back(std::move(sTemp));
  if (wsArray.size() != 8)
    return 0;

  int nMonth = 1;
  sTemp = wsArray[1];
  for (size_t i = 0; i < std::size(fxjs::kMonths); ++i) {
    if (sTemp.EqualsASCII(fxjs::kMonths[i])) {
      nMonth = static_cast<int>(i) + 1;
      break;
    }
  }

  int nDay = StringToFloat(wsArray[2].AsStringView());
  int nHour = StringToFloat(wsArray[3].AsStringView());
  int nMin = StringToFloat(wsArray[4].AsStringView());
  int nSec = StringToFloat(wsArray[5].AsStringView());
  int nYear = StringToFloat(wsArray[7].AsStringView());
  double dRet = FX_MakeDate(FX_MakeDay(nYear, nMonth - 1, nDay),
                            FX_MakeTime(nHour, nMin, nSec, 0));
  if (isnan(dRet))
    dRet = JS_DateParse(isolate, strValue);

  return dRet;
}

// AFDate_KeystrokeEx(cFormat)
CJS_Result CJS_PublicMethods::AFDate_KeystrokeEx(
    CJS_Runtime* pRuntime,
    pdfium::span<v8::Local<v8::Value>> params) {
  if (params.size() != 1) {
    return CJS_Result::Failure(WideString::FromASCII(
        "AFDate_KeystrokeEx's parameter size not correct"));
  }

  CJS_EventContext* pEvent = pRuntime->GetCurrentEventContext();
  if (!pEvent->WillCommit())
    return CJS_Result::Success();

  if (!pEvent->HasValue())
    return CJS_Result::Failure(JSMessage::kBadObjectError);

  const WideString& strValue = pEvent->Value();
  if (strValue.IsEmpty())
    return CJS_Result::Success();

  bool bWrongFormat = false;
  WideString sFormat = pRuntime->ToWideString(params[0]);
  double dRet = ParseDateUsingFormat(pRuntime->GetIsolate(), strValue, sFormat,
                                     &bWrongFormat);
  if (bWrongFormat || isnan(dRet)) {
    WideString swMsg = WideString::Format(
        JSGetStringFromID(JSMessage::kParseDateError).c_str(), sFormat.c_str());
    AlertIfPossible(pEvent, WideString::FromASCII("AFDate_KeystrokeEx"), swMsg);
    pEvent->Rc() = false;
  }
  return CJS_Result::Success();
}

CJS_Result CJS_PublicMethods::AFDate_Format(
    CJS_Runtime* pRuntime,
    pdfium::span<v8::Local<v8::Value>> params) {
  if (params.size() != 1)
    return CJS_Result::Failure(JSMessage::kParamError);

  int iIndex =
      WithinBoundsOrZero(pRuntime->ToInt32(params[0]), std::size(kDateFormats));
  v8::LocalVector<v8::Value> newParams(pRuntime->GetIsolate());
  newParams.push_back(pRuntime->NewString(kDateFormats[iIndex]));
  return AFDate_FormatEx(pRuntime, newParams);
}

// AFDate_KeystrokeEx(cFormat)
CJS_Result CJS_PublicMethods::AFDate_Keystroke(
    CJS_Runtime* pRuntime,
    pdfium::span<v8::Local<v8::Value>> params) {
  if (params.size() != 1)
    return CJS_Result::Failure(JSMessage::kParamError);

  int iIndex =
      WithinBoundsOrZero(pRuntime->ToInt32(params[0]), std::size(kDateFormats));
  v8::LocalVector<v8::Value> newParams(pRuntime->GetIsolate());
  newParams.push_back(pRuntime->NewString(kDateFormats[iIndex]));
  return AFDate_KeystrokeEx(pRuntime, newParams);
}

// function AFTime_Format(ptf)
CJS_Result CJS_PublicMethods::AFTime_Format(
    CJS_Runtime* pRuntime,
    pdfium::span<v8::Local<v8::Value>> params) {
  if (params.size() != 1)
    return CJS_Result::Failure(JSMessage::kParamError);

  int iIndex =
      WithinBoundsOrZero(pRuntime->ToInt32(params[0]), std::size(kTimeFormats));
  v8::LocalVector<v8::Value> newParams(pRuntime->GetIsolate());
  newParams.push_back(pRuntime->NewString(kTimeFormats[iIndex]));
  return AFDate_FormatEx(pRuntime, newParams);
}

CJS_Result CJS_PublicMethods::AFTime_Keystroke(
    CJS_Runtime* pRuntime,
    pdfium::span<v8::Local<v8::Value>> params) {
  if (params.size() != 1)
    return CJS_Result::Failure(JSMessage::kParamError);

  int iIndex =
      WithinBoundsOrZero(pRuntime->ToInt32(params[0]), std::size(kTimeFormats));
  v8::LocalVector<v8::Value> newParams(pRuntime->GetIsolate());
  newParams.push_back(pRuntime->NewString(kTimeFormats[iIndex]));
  return AFDate_KeystrokeEx(pRuntime, newParams);
}

CJS_Result CJS_PublicMethods::AFTime_FormatEx(
    CJS_Runtime* pRuntime,
    pdfium::span<v8::Local<v8::Value>> params) {
  return AFDate_FormatEx(pRuntime, params);
}

CJS_Result CJS_PublicMethods::AFTime_KeystrokeEx(
    CJS_Runtime* pRuntime,
    pdfium::span<v8::Local<v8::Value>> params) {
  return AFDate_KeystrokeEx(pRuntime, params);
}

// function AFSpecial_Format(psf)
CJS_Result CJS_PublicMethods::AFSpecial_Format(
    CJS_Runtime* pRuntime,
    pdfium::span<v8::Local<v8::Value>> params) {
  if (params.size() != 1)
    return CJS_Result::Failure(JSMessage::kParamError);

  CJS_EventContext* pEvent = pRuntime->GetCurrentEventContext();
  if (!pEvent->HasValue())
    return CJS_Result::Failure(JSMessage::kBadObjectError);

  const WideString& wsSource = pEvent->Value();
  WideString wsFormat;
  switch (pRuntime->ToInt32(params[0])) {
    case 0:
      wsFormat = WideString::FromASCII("99999");
      break;
    case 1:
      wsFormat = WideString::FromASCII("99999-9999");
      break;
    case 2:
      if (CJS_Util::StringPrintx(L"9999999999", wsSource).GetLength() >= 10)
        wsFormat = WideString::FromASCII("(999) 999-9999");
      else
        wsFormat = WideString::FromASCII("999-9999");
      break;
    case 3:
      wsFormat = WideString::FromASCII("999-99-9999");
      break;
  }

  pEvent->Value() = CJS_Util::StringPrintx(wsFormat, wsSource);
  return CJS_Result::Success();
}

// function AFSpecial_KeystrokeEx(mask)
CJS_Result CJS_PublicMethods::AFSpecial_KeystrokeEx(
    CJS_Runtime* pRuntime,
    pdfium::span<v8::Local<v8::Value>> params) {
  if (params.size() < 1)
    return CJS_Result::Failure(JSMessage::kParamError);

  CJS_EventContext* pEvent = pRuntime->GetCurrentEventContext();
  if (!pEvent->HasValue())
    return CJS_Result::Failure(JSMessage::kBadObjectError);

  const WideString& valEvent = pEvent->Value();
  WideString wstrMask = pRuntime->ToWideString(params[0]);
  if (wstrMask.IsEmpty())
    return CJS_Result::Success();

  if (pEvent->WillCommit()) {
    if (valEvent.IsEmpty())
      return CJS_Result::Success();

    if (valEvent.GetLength() > wstrMask.GetLength()) {
      AlertIfPossible(pEvent, WideString::FromASCII("AFSpecial_KeystrokeEx"),
                      JSGetStringFromID(JSMessage::kParamTooLongError));
      pEvent->Rc() = false;
      return CJS_Result::Success();
    }

    size_t iIndex = 0;
    for (iIndex = 0; iIndex < valEvent.GetLength(); ++iIndex) {
      if (!MaskSatisfied(valEvent[iIndex], wstrMask[iIndex]))
        break;
    }
    if (iIndex != wstrMask.GetLength()) {
      AlertIfPossible(pEvent, WideString::FromASCII("AFSpecial_KeystrokeEx"),
                      JSGetStringFromID(JSMessage::kInvalidInputError));
      pEvent->Rc() = false;
    }
    return CJS_Result::Success();
  }

  WideString& wideChange = pEvent->Change();
  if (wideChange.IsEmpty())
    return CJS_Result::Success();

  WideString wChange = wideChange;
  size_t iIndexMask = pEvent->SelStart();
  size_t combined_len = valEvent.GetLength() + wChange.GetLength() +
                        pEvent->SelStart() - pEvent->SelEnd();
  if (combined_len > wstrMask.GetLength()) {
    AlertIfPossible(pEvent, WideString::FromASCII("AFSpecial_KeystrokeEx"),
                    JSGetStringFromID(JSMessage::kParamTooLongError));
    pEvent->Rc() = false;
    return CJS_Result::Success();
  }

  if (iIndexMask >= wstrMask.GetLength() && !wChange.IsEmpty()) {
    AlertIfPossible(pEvent, WideString::FromASCII("AFSpecial_KeystrokeEx"),
                    JSGetStringFromID(JSMessage::kParamTooLongError));
    pEvent->Rc() = false;
    return CJS_Result::Success();
  }

  for (size_t i = 0; i < wChange.GetLength(); ++i) {
    if (iIndexMask >= wstrMask.GetLength()) {
      AlertIfPossible(pEvent, WideString::FromASCII("AFSpecial_KeystrokeEx"),
                      JSGetStringFromID(JSMessage::kParamTooLongError));
      pEvent->Rc() = false;
      return CJS_Result::Success();
    }
    wchar_t wMask = wstrMask[iIndexMask];
    if (!IsReservedMaskChar(wMask))
      wChange.SetAt(i, wMask);

    if (!MaskSatisfied(wChange[i], wMask)) {
      pEvent->Rc() = false;
      return CJS_Result::Success();
    }
    iIndexMask++;
  }
  wideChange = std::move(wChange);
  return CJS_Result::Success();
}

// function AFSpecial_Keystroke(psf)
CJS_Result CJS_PublicMethods::AFSpecial_Keystroke(
    CJS_Runtime* pRuntime,
    pdfium::span<v8::Local<v8::Value>> params) {
  if (params.size() != 1)
    return CJS_Result::Failure(JSMessage::kParamError);

  CJS_EventContext* pEvent = pRuntime->GetCurrentEventContext();
  if (!pEvent->HasValue())
    return CJS_Result::Failure(JSMessage::kBadObjectError);

  const char* cFormat = "";
  switch (pRuntime->ToInt32(params[0])) {
    case 0:
      cFormat = "99999";
      break;
    case 1:
      cFormat = "999999999";
      break;
    case 2:
      if (pEvent->Value().GetLength() + pEvent->Change().GetLength() > 7)
        cFormat = "9999999999";
      else
        cFormat = "9999999";
      break;
    case 3:
      cFormat = "999999999";
      break;
  }

  v8::LocalVector<v8::Value> params2(pRuntime->GetIsolate());
  params2.push_back(pRuntime->NewString(cFormat));
  return AFSpecial_KeystrokeEx(pRuntime, params2);
}

CJS_Result CJS_PublicMethods::AFMergeChange(
    CJS_Runtime* pRuntime,
    pdfium::span<v8::Local<v8::Value>> params) {
  if (params.size() != 1)
    return CJS_Result::Failure(JSMessage::kParamError);

  CJS_EventContext* pEvent = pRuntime->GetCurrentEventContext();

  WideString swValue;
  if (pEvent->HasValue())
    swValue = pEvent->Value();

  if (pEvent->WillCommit())
    return CJS_Result::Success(pRuntime->NewString(swValue.AsStringView()));

  return CJS_Result::Success(pRuntime->NewString(
      CalcMergedString(pEvent, swValue, pEvent->Change()).AsStringView()));
}

CJS_Result CJS_PublicMethods::AFParseDateEx(
    CJS_Runtime* pRuntime,
    pdfium::span<v8::Local<v8::Value>> params) {
  if (params.size() != 2)
    return CJS_Result::Failure(JSMessage::kParamError);

  WideString sValue = pRuntime->ToWideString(params[0]);
  WideString sFormat = pRuntime->ToWideString(params[1]);
  double dDate =
      ParseDateUsingFormat(pRuntime->GetIsolate(), sValue, sFormat, nullptr);
  if (isnan(dDate)) {
    WideString swMsg = WideString::Format(
        JSGetStringFromID(JSMessage::kParseDateError).c_str(), sFormat.c_str());
    AlertIfPossible(pRuntime->GetCurrentEventContext(),
                    WideString::FromASCII("AFParseDateEx"), swMsg);
    return CJS_Result::Failure(JSMessage::kParseDateError);
  }
  return CJS_Result::Success(pRuntime->NewNumber(dDate));
}

CJS_Result CJS_PublicMethods::AFSimple(
    CJS_Runtime* pRuntime,
    pdfium::span<v8::Local<v8::Value>> params) {
  if (params.size() != 3)
    return CJS_Result::Failure(JSMessage::kParamError);

  WideString sFunction = pRuntime->ToWideString(params[0]);
  double arg1 = pRuntime->ToDouble(params[1]);
  double arg2 = pRuntime->ToDouble(params[2]);
  if (isnan(arg1) || isnan(arg2))
    return CJS_Result::Failure(JSMessage::kValueError);

  std::optional<double> result = ApplyNamedOperation(sFunction, arg1, arg2);
  if (!result.has_value())
    return CJS_Result::Failure(JSMessage::kValueError);

  double dValue = result.value();
  if (sFunction.EqualsASCII("AVG")) {
    dValue /= 2.0;
  }
  return CJS_Result::Success(pRuntime->NewNumber(dValue));
}

CJS_Result CJS_PublicMethods::AFMakeNumber(
    CJS_Runtime* pRuntime,
    pdfium::span<v8::Local<v8::Value>> params) {
  if (params.size() != 1)
    return CJS_Result::Failure(JSMessage::kParamError);

  WideString ws = pRuntime->ToWideString(params[0]);
  NormalizeDecimalMarkW(&ws);

  v8::Local<v8::Value> val =
      pRuntime->MaybeCoerceToNumber(pRuntime->NewString(ws.AsStringView()));
  if (!val->IsNumber())
    return CJS_Result::Success(pRuntime->NewNumber(0));

  return CJS_Result::Success(val);
}

CJS_Result CJS_PublicMethods::AFSimple_Calculate(
    CJS_Runtime* pRuntime,
    pdfium::span<v8::Local<v8::Value>> params) {
  if (params.size() != 2)
    return CJS_Result::Failure(JSMessage::kParamError);

  if (params[1].IsEmpty() || (!params[1]->IsArray() && !params[1]->IsString()))
    return CJS_Result::Failure(JSMessage::kParamError);

  WideString sFunction = pRuntime->ToWideString(params[0]);
  v8::Local<v8::Array> FieldNameArray =
      AF_MakeArrayFromList(pRuntime, params[1]);

  CPDFSDK_InteractiveForm* pReaderForm =
      pRuntime->GetFormFillEnv()->GetInteractiveForm();
  CPDF_InteractiveForm* pForm = pReaderForm->GetInteractiveForm();

  double dValue = sFunction.EqualsASCII("PRD") ? 1.0 : 0.0;
  int nFieldsCount = 0;
  for (size_t i = 0; i < pRuntime->GetArrayLength(FieldNameArray); ++i) {
    WideString wsFieldName =
        pRuntime->ToWideString(pRuntime->GetArrayElement(FieldNameArray, i));

    for (size_t j = 0; j < pForm->CountFields(wsFieldName); ++j) {
      CPDF_FormField* pFormField = pForm->GetField(j, wsFieldName);
      if (!pFormField)
        continue;

      double dTemp = 0.0;
      switch (pFormField->GetFieldType()) {
        case FormFieldType::kTextField:
        case FormFieldType::kComboBox: {
          WideString trimmed = pFormField->GetValue();
          trimmed.TrimWhitespaceBack();
          trimmed.TrimWhitespaceFront();
          dTemp = StringToDouble(trimmed.AsStringView());
          break;
        }
        case FormFieldType::kPushButton:
          break;
        case FormFieldType::kCheckBox:
        case FormFieldType::kRadioButton:
          for (int c = 0; c < pFormField->CountControls(); ++c) {
            CPDF_FormControl* pFormCtrl = pFormField->GetControl(c);
            if (!pFormField || !pFormCtrl->IsChecked())
              continue;

            WideString trimmed = pFormCtrl->GetExportValue();
            trimmed.TrimWhitespaceBack();
            trimmed.TrimWhitespaceFront();
            dTemp = StringToFloat(trimmed.AsStringView());
            break;
          }
          break;
        case FormFieldType::kListBox:
          if (pFormField->CountSelectedItems() <= 1) {
            WideString trimmed = pFormField->GetValue();
            trimmed.TrimWhitespaceBack();
            trimmed.TrimWhitespaceFront();
            dTemp = StringToFloat(trimmed.AsStringView());
          }
          break;
        default:
          break;
      }

      if (i == 0 && j == 0 &&
          (sFunction.EqualsASCII("MIN") || sFunction.EqualsASCII("MAX"))) {
        dValue = dTemp;
      }
      std::optional<double> dResult =
          ApplyNamedOperation(sFunction, dValue, dTemp);
      if (!dResult.has_value())
        return CJS_Result::Failure(JSMessage::kValueError);

      dValue = dResult.value();
      nFieldsCount++;
    }
  }

  if (sFunction.EqualsASCII("AVG") && nFieldsCount > 0) {
    dValue /= nFieldsCount;
  }
  dValue = floor(dValue * powf(10, 6) + 0.49) / powf(10, 6);

  CJS_EventContext* pContext = pRuntime->GetCurrentEventContext();
  if (pContext->HasValue())
    pContext->Value() = pRuntime->ToWideString(pRuntime->NewNumber(dValue));

  return CJS_Result::Success();
}

// This function validates the current event to ensure that its value is
// within the specified range.
CJS_Result CJS_PublicMethods::AFRange_Validate(
    CJS_Runtime* pRuntime,
    pdfium::span<v8::Local<v8::Value>> params) {
  if (params.size() != 4)
    return CJS_Result::Failure(JSMessage::kParamError);

  CJS_EventContext* pEvent = pRuntime->GetCurrentEventContext();
  if (!pEvent->HasValue())
    return CJS_Result::Failure(JSMessage::kBadObjectError);

  if (pEvent->Value().IsEmpty())
    return CJS_Result::Success();

  // SAFETY: ByteStrings are always NUL-terminated.
  double dEventValue = UNSAFE_BUFFERS(atof(pEvent->Value().ToUTF8().c_str()));
  bool bGreaterThan = pRuntime->ToBoolean(params[0]);
  double dGreaterThan = pRuntime->ToDouble(params[1]);
  bool bLessThan = pRuntime->ToBoolean(params[2]);
  double dLessThan = pRuntime->ToDouble(params[3]);
  WideString swMsg;

  if (bGreaterThan && bLessThan) {
    if (dEventValue < dGreaterThan || dEventValue > dLessThan)
      swMsg = WideString::Format(
          JSGetStringFromID(JSMessage::kRangeBetweenError).c_str(),
          pRuntime->ToWideString(params[1]).c_str(),
          pRuntime->ToWideString(params[3]).c_str());
  } else if (bGreaterThan) {
    if (dEventValue < dGreaterThan)
      swMsg = WideString::Format(
          JSGetStringFromID(JSMessage::kRangeGreaterError).c_str(),
          pRuntime->ToWideString(params[1]).c_str());
  } else if (bLessThan) {
    if (dEventValue > dLessThan)
      swMsg = WideString::Format(
          JSGetStringFromID(JSMessage::kRangeLessError).c_str(),
          pRuntime->ToWideString(params[3]).c_str());
  }

  if (!swMsg.IsEmpty()) {
    AlertIfPossible(pEvent, WideString::FromASCII("AFRange_Validate"), swMsg);
    pEvent->Rc() = false;
  }
  return CJS_Result::Success();
}

CJS_Result CJS_PublicMethods::AFExtractNums(
    CJS_Runtime* pRuntime,
    pdfium::span<v8::Local<v8::Value>> params) {
  if (params.size() != 1)
    return CJS_Result::Failure(JSMessage::kParamError);

  WideString str = pRuntime->ToWideString(params[0]);
  if (str.GetLength() > 0 && IsDigitSeparatorOrDecimalMark(str[0]))
    str.InsertAtFront(L'0');

  WideString sPart;
  v8::Local<v8::Array> nums = pRuntime->NewArray();
  int nIndex = 0;
  for (const auto& wc : str) {
    if (FXSYS_IsDecimalDigit(wc)) {
      sPart += wc;
    } else if (sPart.GetLength() > 0) {
      pRuntime->PutArrayElement(nums, nIndex,
                                pRuntime->NewString(sPart.AsStringView()));
      sPart.clear();
      nIndex++;
    }
  }
  if (sPart.GetLength() > 0) {
    pRuntime->PutArrayElement(nums, nIndex,
                              pRuntime->NewString(sPart.AsStringView()));
  }
  if (pRuntime->GetArrayLength(nums) > 0)
    return CJS_Result::Success(nums);

  return CJS_Result::Success(pRuntime->NewUndefined());
}
