// 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);
  double dValue = 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
  double dValue = 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);
    FXSYS_snprintf(span.data(), szBufferSize, format, dValue);
    szNewSize = 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();

  double dEventValue = 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());
}
