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

#include <memory>
#include <set>
#include <utility>

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

namespace {

const int kFormListMultiSelect = 0x100;

const int kFormComboEdit = 0x100;

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

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

constexpr int kGetFieldMaxRecursion = 32;

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

}  // namespace

Optional<FormFieldType> IntToFormFieldType(int value) {
  if (value >= static_cast<int>(FormFieldType::kUnknown) &&
      value < static_cast<int>(kFormFieldTypeCount)) {
    return {static_cast<FormFieldType>(value)};
  }
  return {};
}

const CPDF_Object* FPDF_GetFieldAttr(const CPDF_Dictionary* pFieldDict,
                                     const char* name,
                                     int nLevel) {
  if (!pFieldDict || nLevel > kGetFieldMaxRecursion)
    return nullptr;

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

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

CPDF_Object* FPDF_GetFieldAttr(CPDF_Dictionary* pFieldDict,
                               const char* name,
                               int nLevel) {
  if (!pFieldDict || nLevel > kGetFieldMaxRecursion)
    return nullptr;

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

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

WideString FPDF_GetFullName(CPDF_Dictionary* pFieldDict) {
  WideString full_name;
  std::set<CPDF_Dictionary*> visited;
  CPDF_Dictionary* pLevel = pFieldDict;
  while (pLevel) {
    visited.insert(pLevel);
    WideString short_name = pLevel->GetUnicodeTextFor("T");
    if (!short_name.IsEmpty()) {
      if (full_name.IsEmpty())
        full_name = std::move(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() {
  const CPDF_Object* ft_attr = FPDF_GetFieldAttr(m_pDict.Get(), "FT");
  ByteString type_name = ft_attr ? ft_attr->GetString() : ByteString();
  const CPDF_Object* ff_attr = FPDF_GetFieldAttr(m_pDict.Get(), "Ff");
  uint32_t flags = ff_attr ? ff_attr->GetInteger() : 0;
  m_Flags = 0;
  if (flags & FORMFLAG_READONLY)
    m_Flags |= FORMFLAG_READONLY;
  if (flags & FORMFLAG_REQUIRED)
    m_Flags |= FORMFLAG_REQUIRED;
  if (flags & FORMFLAG_NOEXPORT)
    m_Flags |= FORMFLAG_NOEXPORT;

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

WideString CPDF_FormField::GetFullName() const {
  return FPDF_GetFullName(m_pDict.Get());
}

bool CPDF_FormField::ResetField(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. (When IsUnison(this) returns true/false.)
        for (int i = 0; i < iCount; i++)
          CheckControl(i, GetControl(i)->IsDefaultChecked(), false);
      }
      if (bNotify && m_pForm->GetFormNotify())
        m_pForm->GetFormNotify()->AfterCheckedStatusChange(this);
      break;
    }
    case CPDF_FormField::ComboBox:
    case CPDF_FormField::ListBox: {
      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: {
      const CPDF_Object* pDV = FPDF_GetFieldAttr(m_pDict.Get(), "DV");
      WideString csDValue;
      if (pDV)
        csDValue = pDV->GetUnicodeText();

      const CPDF_Object* pV = FPDF_GetFieldAttr(m_pDict.Get(), "V");
      WideString csValue;
      if (pV)
        csValue = pV->GetUnicodeText();

      const CPDF_Object* pRV = FPDF_GetFieldAttr(m_pDict.Get(), "RV");
      if (!pRV && (csDValue == csValue))
        return false;

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

      if (pDV) {
        std::unique_ptr<CPDF_Object> pClone = pDV->Clone();
        if (!pClone)
          return false;

        m_pDict->SetFor("V", std::move(pClone));
        if (pRV)
          m_pDict->SetFor("RV", pDV->Clone());
      } 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;

  auto it = std::find(m_ControlList.begin(), m_ControlList.end(), pControl);
  return it != m_ControlList.end() ? it - m_ControlList.begin() : -1;
}

FormFieldType CPDF_FormField::GetFieldType() const {
  switch (m_Type) {
    case PushButton:
      return FormFieldType::kPushButton;
    case CheckBox:
      return FormFieldType::kCheckBox;
    case RadioButton:
      return FormFieldType::kRadioButton;
    case ComboBox:
      return FormFieldType::kComboBox;
    case ListBox:
      return FormFieldType::kListBox;
    case Text:
    case RichText:
    case File:
      return FormFieldType::kTextField;
    case Sign:
      return FormFieldType::kSignature;
    default:
      return FormFieldType::kUnknown;
  }
}

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

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

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

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

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

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

  const CPDF_Object* pValue =
      FPDF_GetFieldAttr(m_pDict.Get(), bDefault ? "DV" : "V");
  if (!pValue) {
    if (!bDefault) {
      if (m_Type == RichText)
        pValue = FPDF_GetFieldAttr(m_pDict.Get(), "V");
      if (!pValue && m_Type != Text)
        pValue = FPDF_GetFieldAttr(m_pDict.Get(), "DV");
    }
    if (!pValue)
      return 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 WideString();
}

WideString CPDF_FormField::GetValue() const {
  return GetValue(false);
}

WideString CPDF_FormField::GetDefaultValue() const {
  return GetValue(true);
}

bool CPDF_FormField::SetValue(const WideString& value,
                              bool bDefault,
                              bool bNotify) {
  switch (m_Type) {
    case CheckBox:
    case RadioButton: {
      SetCheckValue(value, bDefault, bNotify);
      return true;
    }
    case File:
    case RichText:
    case Text:
    case ComboBox: {
      WideString csValue = value;
      if (bNotify && !NotifyBeforeValueChange(csValue))
        return false;

      ByteString key(bDefault ? "DV" : "V");
      int iIndex = FindOptionValue(csValue);
      if (iIndex < 0) {
        ByteString bsEncodeText = PDF_EncodeText(csValue);
        m_pDict->SetNewFor<CPDF_String>(key, bsEncodeText, false);
        if (m_Type == RichText && !bDefault)
          m_pDict->SetNewFor<CPDF_String>("RV", bsEncodeText, false);
        m_pDict->RemoveFor("I");
      } else {
        m_pDict->SetNewFor<CPDF_String>(key, PDF_EncodeText(csValue), false);
        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;
}

bool CPDF_FormField::SetValue(const WideString& value, bool bNotify) {
  return SetValue(value, false, bNotify);
}

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

  for (auto& pControl : m_ControlList) {
    if (!pControl)
      continue;
    CPDF_Dictionary* pWidgetDict = pControl->GetWidget();
    if (pWidgetDict->KeyExist("MaxLen"))
      return pWidgetDict->GetIntegerFor("MaxLen");
  }
  return 0;
}

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

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

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

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

    const CPDF_Object* elementValue = pArray->GetDirectObjectAt(index);
    sel_value = elementValue ? elementValue->GetUnicodeText() : WideString();
  }
  if (index < CountSelectedOptions()) {
    int iOptIndex = GetSelectedOptionIndex(index);
    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;
}

bool CPDF_FormField::ClearSelection(bool bNotify) {
  if (bNotify && m_pForm->GetFormNotify()) {
    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;
}

bool CPDF_FormField::IsItemSelected(int index) const {
  ASSERT(GetType() == ComboBox || GetType() == ListBox);
  if (index < 0 || index >= CountOptions())
    return false;
  if (IsOptionSelected(index))
    return true;

  WideString opt_value = GetOptionValue(index);
  const CPDF_Object* pValue = FPDF_GetFieldAttr(m_pDict.Get(), "V");
  if (!pValue) {
    pValue = FPDF_GetFieldAttr(m_pDict.Get(), "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);
  }

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

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

  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->SetNewFor<CPDF_String>("V", PDF_EncodeText(opt_value), false);
      } else {
        CPDF_Array* pArray = m_pDict->SetNewFor<CPDF_Array>("V");
        for (int i = 0; i < CountOptions(); i++) {
          if (i == index || IsItemSelected(i)) {
            opt_value = GetOptionValue(i);
            pArray->AddNew<CPDF_String>(PDF_EncodeText(opt_value), false);
          }
        }
      }
    } else {
      m_pDict->SetNewFor<CPDF_String>("V", PDF_EncodeText(opt_value), false);
      CPDF_Array* pI = m_pDict->SetNewFor<CPDF_Array>("I");
      pI->AddNew<CPDF_Number>(index);
    }
  } else {
    const CPDF_Object* pValue = FPDF_GetFieldAttr(m_pDict.Get(), "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()) {
          auto pArray = pdfium::MakeUnique<CPDF_Array>();
          for (int i = 0; i < CountOptions(); i++) {
            if (i != index && IsItemSelected(i)) {
              opt_value = GetOptionValue(i);
              pArray->AddNew<CPDF_String>(PDF_EncodeText(opt_value), false);
            }
          }
          if (pArray->GetCount() > 0)
            m_pDict->SetFor("V", std::move(pArray));
        }
      } else {
        m_pDict->RemoveFor("V");
        m_pDict->RemoveFor("I");
      }
    }
  }
  if (bNotify)
    NotifyListOrComboBoxAfterChange();
  return true;
}

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);
  const CPDF_Object* pValue = FPDF_GetFieldAttr(m_pDict.Get(), "DV");
  if (!pValue)
    return -1;
  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 {
  const CPDF_Array* pArray = ToArray(FPDF_GetFieldAttr(m_pDict.Get(), "Opt"));
  return pArray ? pArray->GetCount() : 0;
}

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

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

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

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

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

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

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

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;

  WideString csWExport = pControl->GetExportValue();
  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) {
      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);
    }
  }

  const CPDF_Object* pOpt = FPDF_GetFieldAttr(m_pDict.Get(), "Opt");
  if (!ToArray(pOpt)) {
    if (bChecked) {
      m_pDict->SetNewFor<CPDF_Name>("V", csBExport);
    } else {
      ByteString csV;
      const CPDF_Object* pV = FPDF_GetFieldAttr(m_pDict.Get(), "V");
      if (pV)
        csV = pV->GetString();
      if (csV == csBExport)
        m_pDict->SetNewFor<CPDF_Name>("V", "Off");
    }
  } else if (bChecked) {
    m_pDict->SetNewFor<CPDF_Name>("V", ByteString::Format("%d", iControlIndex));
  }
  if (bNotify && m_pForm->GetFormNotify())
    m_pForm->GetFormNotify()->AfterCheckedStatusChange(this);
  return true;
}

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

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

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

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

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

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

bool CPDF_FormField::IsOptionSelected(int iOptIndex) const {
  const CPDF_Array* pArray = ToArray(FPDF_GetFieldAttr(m_pDict.Get(), "I"));
  if (!pArray)
    return false;

  for (const auto& pObj : *pArray) {
    if (pObj->GetInteger() == iOptIndex)
      return true;
  }
  return false;
}

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

    pArray = m_pDict->SetNewFor<CPDF_Array>("I");
  }

  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->GetFormNotify()) {
        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->GetFormNotify()) {
        WideString csValue = GetOptionLabel(iOptIndex);
        if (!NotifyListOrComboBoxBeforeChange(csValue))
          return false;
      }
      pArray->InsertNewAt<CPDF_Number>(i, iOptIndex);
      bReturn = true;
      break;
    }
  }
  if (!bReturn) {
    if (bSelected)
      pArray->AddNew<CPDF_Number>(iOptIndex);

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

  return true;
}

bool CPDF_FormField::ClearSelectedOptions(bool bNotify) {
  if (bNotify && m_pForm->GetFormNotify()) {
    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->GetFormDict();
  if (!pFormDict)
    return;

  ByteString DA;
  if (const CPDF_Object* pObj = FPDF_GetFieldAttr(m_pDict.Get(), "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_DefaultAppearance appearance(DA);
  Optional<ByteString> font_name = appearance.GetFont(&m_FontSize);
  if (!font_name)
    return;

  CPDF_Dictionary* pFontDict = pFont->GetDictFor(*font_name);
  if (!pFontDict)
    return;

  m_pFont = m_pForm->GetDocument()->LoadFont(pFontDict);
}

bool CPDF_FormField::NotifyBeforeSelectionChange(const WideString& value) {
  if (!m_pForm->GetFormNotify())
    return true;
  return m_pForm->GetFormNotify()->BeforeSelectionChange(this, value);
}

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

bool CPDF_FormField::NotifyBeforeValueChange(const WideString& value) {
  if (!m_pForm->GetFormNotify())
    return true;
  return m_pForm->GetFormNotify()->BeforeValueChange(this, value);
}

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

bool CPDF_FormField::NotifyListOrComboBoxBeforeChange(const 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;
  }
}
