// 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 <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/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 const wchar_t* kDateFormats[] = {L"m/d",
                                           L"m/d/yy",
                                           L"mm/dd/yy",
                                           L"mm/yy",
                                           L"d-mmm",
                                           L"d-mmm-yy",
                                           L"dd-mmm-yy",
                                           L"yy-mm-dd",
                                           L"mmm-yy",
                                           L"mmmm-yy",
                                           L"mmm d, yyyy",
                                           L"mmmm d, yyyy",
                                           L"m/d/yy h:MM tt",
                                           L"m/d/yy HH:MM"};

constexpr const wchar_t* kTimeFormats[] = {L"HH:MM", L"h:MM tt", L"HH:MM:ss",
                                           L"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) {
  CJS_Object* pObj =
      CFXJS_Engine::GetObjectPrivate(info.GetIsolate(), info.Holder());
  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;

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

  int number[3];

  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, L"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, L"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, L"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 = L"99999";
      break;
    case 1:
      wsFormat = L"99999-9999";
      break;
    case 2:
      if (CJS_Util::StringPrintx(L"9999999999", wsSource).GetLength() >= 10)
        wsFormat = L"(999) 999-9999";
      else
        wsFormat = L"999-9999";
      break;
    case 3:
      wsFormat = L"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, L"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, L"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, L"AFSpecial_KeystrokeEx",
                    JSGetStringFromID(JSMessage::kParamTooLongError));
    pEvent->Rc() = false;
    return CJS_Result::Success();
  }

  if (iIndexMask >= wstrMask.GetLength() && !wChange.IsEmpty()) {
    AlertIfPossible(pEvent, L"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, L"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(), L"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 (wcscmp(sFunction.c_str(), L"AVG") == 0)
    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 = wcscmp(sFunction.c_str(), L"PRD") == 0 ? 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 &&
          (wcscmp(sFunction.c_str(), L"MIN") == 0 ||
           wcscmp(sFunction.c_str(), L"MAX") == 0)) {
        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 (wcscmp(sFunction.c_str(), L"AVG") == 0 && 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, L"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());
}
