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

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

#include "core/fpdfdoc/include/cpdf_formfield.h"

#include <set>

#include "core/fpdfapi/fpdf_parser/include/cfdf_document.h"
#include "core/fpdfapi/fpdf_parser/include/cpdf_array.h"
#include "core/fpdfapi/fpdf_parser/include/cpdf_document.h"
#include "core/fpdfapi/fpdf_parser/include/cpdf_number.h"
#include "core/fpdfapi/fpdf_parser/include/cpdf_simple_parser.h"
#include "core/fpdfapi/fpdf_parser/include/cpdf_string.h"
#include "core/fpdfapi/fpdf_parser/include/fpdf_parser_decode.h"
#include "core/fpdfdoc/cpvt_generateap.h"
#include "core/fpdfdoc/include/cpdf_formcontrol.h"
#include "core/fpdfdoc/include/cpdf_interform.h"
#include "third_party/base/stl_util.h"

namespace {

const int kMaxRecursion = 32;

const int kFormListMultiSelect = 0x100;

const int kFormComboEdit = 0x100;

const int kFormFieldReadOnly = 0x01;
const int kFormFieldRequired = 0x02;
const int kFormFieldNoExport = 0x04;

const int kFormRadioNoToggleOff = 0x100;
const int kFormRadioUnison = 0x200;

const int kFormTextMultiLine = 0x100;
const int kFormTextPassword = 0x200;
const int kFormTextNoScroll = 0x400;
const int kFormTextComb = 0x800;

bool IsUnison(CPDF_FormField* pField) {
  if (pField->GetType() == CPDF_FormField::CheckBox)
    return true;
  return (pField->GetFieldFlags() & 0x2000000) != 0;
}

}  // namespace

CPDF_Object* FPDF_GetFieldAttr(CPDF_Dictionary* pFieldDict,
                               const FX_CHAR* name,
                               int nLevel) {
  if (nLevel > kMaxRecursion)
    return nullptr;
  if (!pFieldDict)
    return nullptr;

  CPDF_Object* pAttr = pFieldDict->GetDirectObjectFor(name);
  if (pAttr)
    return pAttr;

  CPDF_Dictionary* pParent = pFieldDict->GetDictFor("Parent");
  if (!pParent)
    return nullptr;
  return FPDF_GetFieldAttr(pParent, name, nLevel + 1);
}

CFX_WideString FPDF_GetFullName(CPDF_Dictionary* pFieldDict) {
  CFX_WideString full_name;
  std::set<CPDF_Dictionary*> visited;
  CPDF_Dictionary* pLevel = pFieldDict;
  while (pLevel) {
    visited.insert(pLevel);
    CFX_WideString short_name = pLevel->GetUnicodeTextFor("T");
    if (!short_name.IsEmpty()) {
      if (full_name.IsEmpty())
        full_name = short_name;
      else
        full_name = short_name + L"." + full_name;
    }
    pLevel = pLevel->GetDictFor("Parent");
    if (pdfium::ContainsKey(visited, pLevel))
      break;
  }
  return full_name;
}

CPDF_FormField::CPDF_FormField(CPDF_InterForm* pForm, CPDF_Dictionary* pDict)
    : m_Type(Unknown),
      m_pForm(pForm),
      m_pDict(pDict),
      m_FontSize(0),
      m_pFont(nullptr) {
  SyncFieldFlags();
}

CPDF_FormField::~CPDF_FormField() {}

void CPDF_FormField::SyncFieldFlags() {
  CFX_ByteString type_name = FPDF_GetFieldAttr(m_pDict, "FT")
                                 ? FPDF_GetFieldAttr(m_pDict, "FT")->GetString()
                                 : CFX_ByteString();
  uint32_t flags = FPDF_GetFieldAttr(m_pDict, "Ff")
                       ? FPDF_GetFieldAttr(m_pDict, "Ff")->GetInteger()
                       : 0;
  m_Flags = 0;
  if (flags & 1)
    m_Flags |= kFormFieldReadOnly;
  if (flags & 2)
    m_Flags |= kFormFieldRequired;
  if (flags & 4)
    m_Flags |= kFormFieldNoExport;

  if (type_name == "Btn") {
    if (flags & 0x8000) {
      m_Type = RadioButton;
      if (flags & 0x4000)
        m_Flags |= kFormRadioNoToggleOff;
      if (flags & 0x2000000)
        m_Flags |= kFormRadioUnison;
    } else if (flags & 0x10000) {
      m_Type = PushButton;
    } else {
      m_Type = CheckBox;
    }
  } else if (type_name == "Tx") {
    if (flags & 0x100000) {
      m_Type = File;
    } else if (flags & 0x2000000) {
      m_Type = RichText;
    } else {
      m_Type = Text;
      if (flags & 0x1000)
        m_Flags |= kFormTextMultiLine;
      if (flags & 0x2000)
        m_Flags |= kFormTextPassword;
      if (flags & 0x800000)
        m_Flags |= kFormTextNoScroll;
      if (flags & 0x100000)
        m_Flags |= kFormTextComb;
    }
    LoadDA();
  } else if (type_name == "Ch") {
    if (flags & 0x20000) {
      m_Type = ComboBox;
      if (flags & 0x40000)
        m_Flags |= kFormComboEdit;
    } else {
      m_Type = ListBox;
      if (flags & 0x200000)
        m_Flags |= kFormListMultiSelect;
    }
    LoadDA();
  } else if (type_name == "Sig") {
    m_Type = Sign;
  }
}

CFX_WideString CPDF_FormField::GetFullName() const {
  return FPDF_GetFullName(m_pDict);
}

FX_BOOL CPDF_FormField::ResetField(FX_BOOL bNotify) {
  switch (m_Type) {
    case CPDF_FormField::CheckBox:
    case CPDF_FormField::RadioButton: {
      int iCount = CountControls();
      if (iCount) {
        // TODO(weili): Check whether anything special needs to be done for
        // unison field. Otherwise, merge these branches.
        if (IsUnison(this)) {
          for (int i = 0; i < iCount; i++)
            CheckControl(i, GetControl(i)->IsDefaultChecked(), FALSE);
        } else {
          for (int i = 0; i < iCount; i++)
            CheckControl(i, GetControl(i)->IsDefaultChecked(), FALSE);
        }
      }
      if (bNotify && m_pForm->m_pFormNotify)
        m_pForm->m_pFormNotify->AfterCheckedStatusChange(this);
      break;
    }
    case CPDF_FormField::ComboBox:
    case CPDF_FormField::ListBox: {
      CFX_WideString csValue;
      ClearSelection();
      int iIndex = GetDefaultSelectedItem();
      if (iIndex >= 0)
        csValue = GetOptionLabel(iIndex);

      if (bNotify && !NotifyListOrComboBoxBeforeChange(csValue))
        return FALSE;

      SetItemSelection(iIndex, TRUE);
      if (bNotify)
        NotifyListOrComboBoxAfterChange();
      break;
    }
    case CPDF_FormField::Text:
    case CPDF_FormField::RichText:
    case CPDF_FormField::File:
    default: {
      CPDF_Object* pDV = FPDF_GetFieldAttr(m_pDict, "DV");
      CFX_WideString csDValue;
      if (pDV)
        csDValue = pDV->GetUnicodeText();

      CPDF_Object* pV = FPDF_GetFieldAttr(m_pDict, "V");
      CFX_WideString csValue;
      if (pV)
        csValue = pV->GetUnicodeText();

      CPDF_Object* pRV = FPDF_GetFieldAttr(m_pDict, "RV");
      if (!pRV && (csDValue == csValue))
        return FALSE;

      if (bNotify && !NotifyBeforeValueChange(csDValue))
        return FALSE;

      if (pDV) {
        CPDF_Object* pClone = pDV->Clone();
        if (!pClone)
          return FALSE;

        m_pDict->SetFor("V", pClone);
        if (pRV) {
          CPDF_Object* pCloneR = pDV->Clone();
          m_pDict->SetFor("RV", pCloneR);
        }
      } else {
        m_pDict->RemoveFor("V");
        m_pDict->RemoveFor("RV");
      }
      if (bNotify)
        NotifyAfterValueChange();
      break;
    }
  }
  return TRUE;
}

int CPDF_FormField::GetControlIndex(const CPDF_FormControl* pControl) const {
  if (!pControl)
    return -1;

  for (int i = 0; i < m_ControlList.GetSize(); i++) {
    if (m_ControlList.GetAt(i) == pControl)
      return i;
  }
  return -1;
}

int CPDF_FormField::GetFieldType() const {
  switch (m_Type) {
    case PushButton:
      return FIELDTYPE_PUSHBUTTON;
    case CheckBox:
      return FIELDTYPE_CHECKBOX;
    case RadioButton:
      return FIELDTYPE_RADIOBUTTON;
    case ComboBox:
      return FIELDTYPE_COMBOBOX;
    case ListBox:
      return FIELDTYPE_LISTBOX;
    case Text:
    case RichText:
    case File:
      return FIELDTYPE_TEXTFIELD;
    case Sign:
      return FIELDTYPE_SIGNATURE;
    default:
      break;
  }
  return FIELDTYPE_UNKNOWN;
}

CPDF_AAction CPDF_FormField::GetAdditionalAction() const {
  CPDF_Object* pObj = FPDF_GetFieldAttr(m_pDict, "AA");
  return CPDF_AAction(pObj ? pObj->GetDict() : nullptr);
}

CFX_WideString CPDF_FormField::GetAlternateName() const {
  CPDF_Object* pObj = FPDF_GetFieldAttr(m_pDict, "TU");
  return pObj ? pObj->GetUnicodeText() : L"";
}

CFX_WideString CPDF_FormField::GetMappingName() const {
  CPDF_Object* pObj = FPDF_GetFieldAttr(m_pDict, "TM");
  return pObj ? pObj->GetUnicodeText() : L"";
}

uint32_t CPDF_FormField::GetFieldFlags() const {
  CPDF_Object* pObj = FPDF_GetFieldAttr(m_pDict, "Ff");
  return pObj ? pObj->GetInteger() : 0;
}

CFX_ByteString CPDF_FormField::GetDefaultStyle() const {
  CPDF_Object* pObj = FPDF_GetFieldAttr(m_pDict, "DS");
  return pObj ? pObj->GetString() : "";
}

CFX_WideString CPDF_FormField::GetRichTextString() const {
  CPDF_Object* pObj = FPDF_GetFieldAttr(m_pDict, "RV");
  return pObj ? pObj->GetUnicodeText() : L"";
}

CFX_WideString CPDF_FormField::GetValue(FX_BOOL bDefault) const {
  if (GetType() == CheckBox || GetType() == RadioButton)
    return GetCheckValue(bDefault);

  CPDF_Object* pValue = FPDF_GetFieldAttr(m_pDict, bDefault ? "DV" : "V");
  if (!pValue) {
    if (!bDefault) {
      if (m_Type == RichText)
        pValue = FPDF_GetFieldAttr(m_pDict, "V");
      if (!pValue && m_Type != Text)
        pValue = FPDF_GetFieldAttr(m_pDict, "DV");
    }
    if (!pValue)
      return CFX_WideString();
  }

  switch (pValue->GetType()) {
    case CPDF_Object::STRING:
    case CPDF_Object::STREAM:
      return pValue->GetUnicodeText();
    case CPDF_Object::ARRAY:
      pValue = pValue->AsArray()->GetDirectObjectAt(0);
      if (pValue)
        return pValue->GetUnicodeText();
      break;
    default:
      break;
  }
  return CFX_WideString();
}

CFX_WideString CPDF_FormField::GetValue() const {
  return GetValue(FALSE);
}

CFX_WideString CPDF_FormField::GetDefaultValue() const {
  return GetValue(TRUE);
}

FX_BOOL CPDF_FormField::SetValue(const CFX_WideString& value,
                                 FX_BOOL bDefault,
                                 FX_BOOL bNotify) {
  switch (m_Type) {
    case CheckBox:
    case RadioButton: {
      SetCheckValue(value, bDefault, bNotify);
      return TRUE;
    }
    case File:
    case RichText:
    case Text:
    case ComboBox: {
      CFX_WideString csValue = value;
      if (bNotify && !NotifyBeforeValueChange(csValue))
        return FALSE;

      int iIndex = FindOptionValue(csValue);
      if (iIndex < 0) {
        CFX_ByteString bsEncodeText = PDF_EncodeText(csValue);
        m_pDict->SetStringFor(bDefault ? "DV" : "V", bsEncodeText);
        if (m_Type == RichText && !bDefault)
          m_pDict->SetStringFor("RV", bsEncodeText);
        m_pDict->RemoveFor("I");
      } else {
        m_pDict->SetStringFor(bDefault ? "DV" : "V", PDF_EncodeText(csValue));
        if (!bDefault) {
          ClearSelection();
          SetItemSelection(iIndex, TRUE);
        }
      }
      if (bNotify)
        NotifyAfterValueChange();
      break;
    }
    case ListBox: {
      int iIndex = FindOptionValue(value);
      if (iIndex < 0)
        return FALSE;

      if (bDefault && iIndex == GetDefaultSelectedItem())
        return FALSE;

      if (bNotify && !NotifyBeforeSelectionChange(value))
        return FALSE;

      if (!bDefault) {
        ClearSelection();
        SetItemSelection(iIndex, TRUE);
      }
      if (bNotify)
        NotifyAfterSelectionChange();
      break;
    }
    default:
      break;
  }
  return TRUE;
}

FX_BOOL CPDF_FormField::SetValue(const CFX_WideString& value, FX_BOOL bNotify) {
  return SetValue(value, FALSE, bNotify);
}

int CPDF_FormField::GetMaxLen() const {
  if (CPDF_Object* pObj = FPDF_GetFieldAttr(m_pDict, "MaxLen"))
    return pObj->GetInteger();

  for (int i = 0; i < m_ControlList.GetSize(); i++) {
    CPDF_FormControl* pControl = m_ControlList.GetAt(i);
    if (!pControl)
      continue;

    CPDF_Dictionary* pWidgetDict = pControl->m_pWidgetDict;
    if (pWidgetDict->KeyExist("MaxLen"))
      return pWidgetDict->GetIntegerFor("MaxLen");
  }
  return 0;
}

int CPDF_FormField::CountSelectedItems() const {
  CPDF_Object* pValue = FPDF_GetFieldAttr(m_pDict, "V");
  if (!pValue) {
    pValue = FPDF_GetFieldAttr(m_pDict, "I");
    if (!pValue)
      return 0;
  }

  if (pValue->IsString() || pValue->IsNumber())
    return pValue->GetString().IsEmpty() ? 0 : 1;
  if (CPDF_Array* pArray = pValue->AsArray())
    return pArray->GetCount();
  return 0;
}

int CPDF_FormField::GetSelectedIndex(int index) const {
  CPDF_Object* pValue = FPDF_GetFieldAttr(m_pDict, "V");
  if (!pValue) {
    pValue = FPDF_GetFieldAttr(m_pDict, "I");
    if (!pValue)
      return -1;
  }
  if (pValue->IsNumber())
    return pValue->GetInteger();

  CFX_WideString sel_value;
  if (pValue->IsString()) {
    if (index != 0)
      return -1;
    sel_value = pValue->GetUnicodeText();
  } else {
    CPDF_Array* pArray = pValue->AsArray();
    if (!pArray || index < 0)
      return -1;

    CPDF_Object* elementValue = pArray->GetDirectObjectAt(index);
    sel_value =
        elementValue ? elementValue->GetUnicodeText() : CFX_WideString();
  }
  if (index < CountSelectedOptions()) {
    int iOptIndex = GetSelectedOptionIndex(index);
    CFX_WideString csOpt = GetOptionValue(iOptIndex);
    if (csOpt == sel_value)
      return iOptIndex;
  }
  for (int i = 0; i < CountOptions(); i++) {
    if (sel_value == GetOptionValue(i))
      return i;
  }
  return -1;
}

FX_BOOL CPDF_FormField::ClearSelection(FX_BOOL bNotify) {
  if (bNotify && m_pForm->m_pFormNotify) {
    CFX_WideString csValue;
    int iIndex = GetSelectedIndex(0);
    if (iIndex >= 0)
      csValue = GetOptionLabel(iIndex);

    if (!NotifyListOrComboBoxBeforeChange(csValue))
      return FALSE;
  }
  m_pDict->RemoveFor("V");
  m_pDict->RemoveFor("I");
  if (bNotify)
    NotifyListOrComboBoxAfterChange();
  return TRUE;
}

FX_BOOL CPDF_FormField::IsItemSelected(int index) const {
  ASSERT(GetType() == ComboBox || GetType() == ListBox);
  if (index < 0 || index >= CountOptions())
    return FALSE;
  if (IsOptionSelected(index))
    return TRUE;

  CFX_WideString opt_value = GetOptionValue(index);
  CPDF_Object* pValue = FPDF_GetFieldAttr(m_pDict, "V");
  if (!pValue) {
    pValue = FPDF_GetFieldAttr(m_pDict, "I");
    if (!pValue)
      return FALSE;
  }

  if (pValue->IsString())
    return pValue->GetUnicodeText() == opt_value;

  if (pValue->IsNumber()) {
    if (pValue->GetString().IsEmpty())
      return FALSE;
    return (pValue->GetInteger() == index);
  }

  CPDF_Array* pArray = pValue->AsArray();
  if (!pArray)
    return FALSE;

  int iPos = -1;
  for (int j = 0; j < CountSelectedOptions(); j++) {
    if (GetSelectedOptionIndex(j) == index) {
      iPos = j;
      break;
    }
  }
  for (int i = 0; i < static_cast<int>(pArray->GetCount()); i++)
    if (pArray->GetDirectObjectAt(i)->GetUnicodeText() == opt_value &&
        i == iPos) {
      return TRUE;
    }
  return FALSE;
}

FX_BOOL CPDF_FormField::SetItemSelection(int index,
                                         FX_BOOL bSelected,
                                         FX_BOOL bNotify) {
  ASSERT(GetType() == ComboBox || GetType() == ListBox);
  if (index < 0 || index >= CountOptions())
    return FALSE;

  CFX_WideString opt_value = GetOptionValue(index);
  if (bNotify && !NotifyListOrComboBoxBeforeChange(opt_value))
    return FALSE;

  if (bSelected) {
    if (GetType() == ListBox) {
      SelectOption(index, TRUE);
      if (!(m_Flags & kFormListMultiSelect)) {
        m_pDict->SetStringFor("V", PDF_EncodeText(opt_value));
      } else {
        CPDF_Array* pArray = new CPDF_Array;
        for (int i = 0; i < CountOptions(); i++) {
          if (i == index || IsItemSelected(i)) {
            opt_value = GetOptionValue(i);
            pArray->AddString(PDF_EncodeText(opt_value));
          }
        }
        m_pDict->SetFor("V", pArray);
      }
    } else {
      m_pDict->SetStringFor("V", PDF_EncodeText(opt_value));
      CPDF_Array* pI = new CPDF_Array;
      pI->AddInteger(index);
      m_pDict->SetFor("I", pI);
    }
  } else {
    CPDF_Object* pValue = FPDF_GetFieldAttr(m_pDict, "V");
    if (pValue) {
      if (GetType() == ListBox) {
        SelectOption(index, FALSE);
        if (pValue->IsString()) {
          if (pValue->GetUnicodeText() == opt_value)
            m_pDict->RemoveFor("V");
        } else if (pValue->IsArray()) {
          std::unique_ptr<CPDF_Array, ReleaseDeleter<CPDF_Array>> pArray(
              new CPDF_Array);
          for (int i = 0; i < CountOptions(); i++) {
            if (i != index && IsItemSelected(i)) {
              opt_value = GetOptionValue(i);
              pArray->AddString(PDF_EncodeText(opt_value));
            }
          }
          if (pArray->GetCount() > 0)
            m_pDict->SetFor("V", pArray.release());  // std::move someday
        }
      } else {
        m_pDict->RemoveFor("V");
        m_pDict->RemoveFor("I");
      }
    }
  }
  if (bNotify)
    NotifyListOrComboBoxAfterChange();
  return TRUE;
}

FX_BOOL CPDF_FormField::IsItemDefaultSelected(int index) const {
  ASSERT(GetType() == ComboBox || GetType() == ListBox);
  if (index < 0 || index >= CountOptions())
    return FALSE;
  int iDVIndex = GetDefaultSelectedItem();
  return iDVIndex >= 0 && iDVIndex == index;
}

int CPDF_FormField::GetDefaultSelectedItem() const {
  ASSERT(GetType() == ComboBox || GetType() == ListBox);
  CPDF_Object* pValue = FPDF_GetFieldAttr(m_pDict, "DV");
  if (!pValue)
    return -1;
  CFX_WideString csDV = pValue->GetUnicodeText();
  if (csDV.IsEmpty())
    return -1;
  for (int i = 0; i < CountOptions(); i++) {
    if (csDV == GetOptionValue(i))
      return i;
  }
  return -1;
}

int CPDF_FormField::CountOptions() const {
  CPDF_Array* pArray = ToArray(FPDF_GetFieldAttr(m_pDict, "Opt"));
  return pArray ? pArray->GetCount() : 0;
}

CFX_WideString CPDF_FormField::GetOptionText(int index, int sub_index) const {
  CPDF_Array* pArray = ToArray(FPDF_GetFieldAttr(m_pDict, "Opt"));
  if (!pArray)
    return CFX_WideString();

  CPDF_Object* pOption = pArray->GetDirectObjectAt(index);
  if (!pOption)
    return CFX_WideString();
  if (CPDF_Array* pOptionArray = pOption->AsArray())
    pOption = pOptionArray->GetDirectObjectAt(sub_index);

  CPDF_String* pString = ToString(pOption);
  return pString ? pString->GetUnicodeText() : CFX_WideString();
}

CFX_WideString CPDF_FormField::GetOptionLabel(int index) const {
  return GetOptionText(index, 1);
}

CFX_WideString CPDF_FormField::GetOptionValue(int index) const {
  return GetOptionText(index, 0);
}

int CPDF_FormField::FindOption(CFX_WideString csOptLabel) const {
  for (int i = 0; i < CountOptions(); i++) {
    if (GetOptionValue(i) == csOptLabel)
      return i;
  }
  return -1;
}

int CPDF_FormField::FindOptionValue(const CFX_WideString& csOptValue) const {
  for (int i = 0; i < CountOptions(); i++) {
    if (GetOptionValue(i) == csOptValue)
      return i;
  }
  return -1;
}

#ifdef PDF_ENABLE_XFA
int CPDF_FormField::InsertOption(CFX_WideString csOptLabel,
                                 int index,
                                 FX_BOOL bNotify) {
  if (csOptLabel.IsEmpty())
    return -1;

  if (bNotify && !NotifyListOrComboBoxBeforeChange(csOptLabel))
    return -1;

  CFX_ByteString csStr =
      PDF_EncodeText(csOptLabel.c_str(), csOptLabel.GetLength());
  CPDF_Object* pValue = FPDF_GetFieldAttr(m_pDict, "Opt");
  CPDF_Array* pOpt = ToArray(pValue);
  if (!pOpt) {
    pOpt = new CPDF_Array;
    m_pDict->SetFor("Opt", pOpt);
  }

  int iCount = pdfium::base::checked_cast<int, size_t>(pOpt->GetCount());
  if (index >= iCount) {
    pOpt->AddString(csStr);
    index = iCount;
  } else {
    CPDF_String* pString = new CPDF_String(csStr, FALSE);
    pOpt->InsertAt(index, pString);
  }

  if (bNotify)
    NotifyListOrComboBoxAfterChange();
  return index;
}

FX_BOOL CPDF_FormField::ClearOptions(FX_BOOL bNotify) {
  if (bNotify && m_pForm->m_pFormNotify) {
    CFX_WideString csValue;
    int iIndex = GetSelectedIndex(0);
    if (iIndex >= 0)
      csValue = GetOptionLabel(iIndex);
    if (!NotifyListOrComboBoxBeforeChange(csValue))
      return FALSE;
  }

  m_pDict->RemoveFor("Opt");
  m_pDict->RemoveFor("V");
  m_pDict->RemoveFor("DV");
  m_pDict->RemoveFor("I");
  m_pDict->RemoveFor("TI");

  if (bNotify)
    NotifyListOrComboBoxAfterChange();

  return TRUE;
}
#endif  // PDF_ENABLE_XFA

FX_BOOL CPDF_FormField::CheckControl(int iControlIndex,
                                     bool bChecked,
                                     bool bNotify) {
  ASSERT(GetType() == CheckBox || GetType() == RadioButton);
  CPDF_FormControl* pControl = GetControl(iControlIndex);
  if (!pControl)
    return FALSE;
  if (!bChecked && pControl->IsChecked() == bChecked)
    return FALSE;

  CFX_WideString csWExport = pControl->GetExportValue();
  CFX_ByteString csBExport = PDF_EncodeText(csWExport);
  int iCount = CountControls();
  bool bUnison = IsUnison(this);
  for (int i = 0; i < iCount; i++) {
    CPDF_FormControl* pCtrl = GetControl(i);
    if (bUnison) {
      CFX_WideString csEValue = pCtrl->GetExportValue();
      if (csEValue == csWExport) {
        if (pCtrl->GetOnStateName() == pControl->GetOnStateName())
          pCtrl->CheckControl(bChecked);
        else if (bChecked)
          pCtrl->CheckControl(FALSE);
      } else if (bChecked) {
        pCtrl->CheckControl(FALSE);
      }
    } else {
      if (i == iControlIndex)
        pCtrl->CheckControl(bChecked);
      else if (bChecked)
        pCtrl->CheckControl(FALSE);
    }
  }

  CPDF_Object* pOpt = FPDF_GetFieldAttr(m_pDict, "Opt");
  if (!ToArray(pOpt)) {
    if (bChecked) {
      m_pDict->SetNameFor("V", csBExport);
    } else {
      CFX_ByteString csV;
      CPDF_Object* pV = FPDF_GetFieldAttr(m_pDict, "V");
      if (pV)
        csV = pV->GetString();
      if (csV == csBExport)
        m_pDict->SetNameFor("V", "Off");
    }
  } else if (bChecked) {
    CFX_ByteString csIndex;
    csIndex.Format("%d", iControlIndex);
    m_pDict->SetNameFor("V", csIndex);
  }
  if (bNotify && m_pForm->m_pFormNotify)
    m_pForm->m_pFormNotify->AfterCheckedStatusChange(this);
  return TRUE;
}

CFX_WideString CPDF_FormField::GetCheckValue(FX_BOOL bDefault) const {
  ASSERT(GetType() == CheckBox || GetType() == RadioButton);
  CFX_WideString csExport = L"Off";
  int iCount = CountControls();
  for (int i = 0; i < iCount; i++) {
    CPDF_FormControl* pControl = GetControl(i);
    FX_BOOL bChecked =
        bDefault ? pControl->IsDefaultChecked() : pControl->IsChecked();
    if (bChecked) {
      csExport = pControl->GetExportValue();
      break;
    }
  }
  return csExport;
}

FX_BOOL CPDF_FormField::SetCheckValue(const CFX_WideString& value,
                                      FX_BOOL bDefault,
                                      FX_BOOL bNotify) {
  ASSERT(GetType() == CheckBox || GetType() == RadioButton);
  int iCount = CountControls();
  for (int i = 0; i < iCount; i++) {
    CPDF_FormControl* pControl = GetControl(i);
    CFX_WideString csExport = pControl->GetExportValue();
    bool val = csExport == value;
    if (!bDefault)
      CheckControl(GetControlIndex(pControl), val);
    if (val)
      break;
  }
  if (bNotify && m_pForm->m_pFormNotify)
    m_pForm->m_pFormNotify->AfterCheckedStatusChange(this);
  return TRUE;
}

int CPDF_FormField::GetTopVisibleIndex() const {
  CPDF_Object* pObj = FPDF_GetFieldAttr(m_pDict, "TI");
  return pObj ? pObj->GetInteger() : 0;
}

int CPDF_FormField::CountSelectedOptions() const {
  CPDF_Array* pArray = ToArray(FPDF_GetFieldAttr(m_pDict, "I"));
  return pArray ? pArray->GetCount() : 0;
}

int CPDF_FormField::GetSelectedOptionIndex(int index) const {
  CPDF_Array* pArray = ToArray(FPDF_GetFieldAttr(m_pDict, "I"));
  if (!pArray)
    return -1;

  int iCount = pArray->GetCount();
  if (iCount < 0 || index >= iCount)
    return -1;
  return pArray->GetIntegerAt(index);
}

FX_BOOL CPDF_FormField::IsOptionSelected(int iOptIndex) const {
  CPDF_Array* pArray = ToArray(FPDF_GetFieldAttr(m_pDict, "I"));
  if (!pArray)
    return FALSE;

  for (CPDF_Object* pObj : *pArray) {
    if (pObj->GetInteger() == iOptIndex)
      return TRUE;
  }
  return FALSE;
}

FX_BOOL CPDF_FormField::SelectOption(int iOptIndex,
                                     FX_BOOL bSelected,
                                     FX_BOOL bNotify) {
  CPDF_Array* pArray = m_pDict->GetArrayFor("I");
  if (!pArray) {
    if (!bSelected)
      return TRUE;

    pArray = new CPDF_Array;
    m_pDict->SetFor("I", pArray);
  }

  FX_BOOL bReturn = FALSE;
  for (size_t i = 0; i < pArray->GetCount(); i++) {
    int iFind = pArray->GetIntegerAt(i);
    if (iFind == iOptIndex) {
      if (bSelected)
        return TRUE;

      if (bNotify && m_pForm->m_pFormNotify) {
        CFX_WideString csValue = GetOptionLabel(iOptIndex);
        if (!NotifyListOrComboBoxBeforeChange(csValue))
          return FALSE;
      }
      pArray->RemoveAt(i);
      bReturn = TRUE;
      break;
    }

    if (iFind > iOptIndex) {
      if (!bSelected)
        continue;

      if (bNotify && m_pForm->m_pFormNotify) {
        CFX_WideString csValue = GetOptionLabel(iOptIndex);
        if (!NotifyListOrComboBoxBeforeChange(csValue))
          return FALSE;
      }
      pArray->InsertAt(i, new CPDF_Number(iOptIndex));
      bReturn = TRUE;
      break;
    }
  }
  if (!bReturn) {
    if (bSelected)
      pArray->AddInteger(iOptIndex);

    if (pArray->IsEmpty())
      m_pDict->RemoveFor("I");
  }
  if (bNotify)
    NotifyListOrComboBoxAfterChange();

  return TRUE;
}

FX_BOOL CPDF_FormField::ClearSelectedOptions(FX_BOOL bNotify) {
  if (bNotify && m_pForm->m_pFormNotify) {
    CFX_WideString csValue;
    int iIndex = GetSelectedIndex(0);
    if (iIndex >= 0)
      csValue = GetOptionLabel(iIndex);

    if (!NotifyListOrComboBoxBeforeChange(csValue))
      return FALSE;
  }
  m_pDict->RemoveFor("I");
  if (bNotify)
    NotifyListOrComboBoxAfterChange();

  return TRUE;
}

void CPDF_FormField::LoadDA() {
  CPDF_Dictionary* pFormDict = m_pForm->m_pFormDict;
  if (!pFormDict)
    return;

  CFX_ByteString DA;
  if (CPDF_Object* pObj = FPDF_GetFieldAttr(m_pDict, "DA"))
    DA = pObj->GetString();

  if (DA.IsEmpty())
    DA = pFormDict->GetStringFor("DA");

  if (DA.IsEmpty())
    return;

  CPDF_Dictionary* pDR = pFormDict->GetDictFor("DR");
  if (!pDR)
    return;

  CPDF_Dictionary* pFont = pDR->GetDictFor("Font");
  if (!pFont)
    return;

  CPDF_SimpleParser syntax(DA.AsStringC());
  syntax.FindTagParamFromStart("Tf", 2);
  CFX_ByteString font_name(syntax.GetWord());
  CPDF_Dictionary* pFontDict = pFont->GetDictFor(font_name);
  if (!pFontDict)
    return;

  m_pFont = m_pForm->m_pDocument->LoadFont(pFontDict);
  m_FontSize = FX_atof(syntax.GetWord());
}

bool CPDF_FormField::NotifyBeforeSelectionChange(const CFX_WideString& value) {
  if (!m_pForm->m_pFormNotify)
    return true;
  return m_pForm->m_pFormNotify->BeforeSelectionChange(this, value) >= 0;
}

void CPDF_FormField::NotifyAfterSelectionChange() {
  if (!m_pForm->m_pFormNotify)
    return;
  m_pForm->m_pFormNotify->AfterSelectionChange(this);
}

bool CPDF_FormField::NotifyBeforeValueChange(const CFX_WideString& value) {
  if (!m_pForm->m_pFormNotify)
    return true;
  return m_pForm->m_pFormNotify->BeforeValueChange(this, value) >= 0;
}

void CPDF_FormField::NotifyAfterValueChange() {
  if (!m_pForm->m_pFormNotify)
    return;
  m_pForm->m_pFormNotify->AfterValueChange(this);
}

bool CPDF_FormField::NotifyListOrComboBoxBeforeChange(
    const CFX_WideString& value) {
  switch (GetType()) {
    case ListBox:
      return NotifyBeforeSelectionChange(value);
    case ComboBox:
      return NotifyBeforeValueChange(value);
    default:
      return true;
  }
}

void CPDF_FormField::NotifyListOrComboBoxAfterChange() {
  switch (GetType()) {
    case ListBox:
      NotifyAfterSelectionChange();
      break;
    case ComboBox:
      NotifyAfterValueChange();
      break;
    default:
      break;
  }
}
