// 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 <vector>

#include "core/fpdfapi/fpdf_page/include/cpdf_page.h"
#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_string.h"
#include "core/fpdfdoc/doc_utils.h"
#include "core/include/fpdfdoc/fpdf_doc.h"
#include "third_party/base/stl_util.h"

namespace {

const int nMaxRecursion = 32;

const struct SupportFieldEncoding {
  const FX_CHAR* m_name;
  FX_WORD m_codePage;
} g_fieldEncoding[] = {
    {"BigFive", 950},
    {"GBK", 936},
    {"Shift-JIS", 932},
    {"UHC", 949},
};

CFX_WideString FPDFDOC_FDF_GetFieldValue(const CPDF_Dictionary& pFieldDict,
                                         const CFX_ByteString& bsEncoding) {
  const CFX_ByteString csBValue = pFieldDict.GetStringBy("V");
  for (const auto& encoding : g_fieldEncoding) {
    if (bsEncoding == encoding.m_name)
      return CFX_WideString::FromCodePage(csBValue, encoding.m_codePage);
  }
  CFX_ByteString csTemp = csBValue.Left(2);
  if (csTemp == "\xFF\xFE" || csTemp == "\xFE\xFF")
    return PDF_DecodeText(csBValue);
  return CFX_WideString::FromLocal(csBValue);
}

}  // namespace

class CFieldNameExtractor {
 public:
  explicit CFieldNameExtractor(const CFX_WideString& full_name) {
    m_pStart = full_name.c_str();
    m_pEnd = m_pStart + full_name.GetLength();
    m_pCur = m_pStart;
  }
  void GetNext(const FX_WCHAR*& pSubName, FX_STRSIZE& size) {
    pSubName = m_pCur;
    while (m_pCur < m_pEnd && m_pCur[0] != L'.') {
      m_pCur++;
    }
    size = (FX_STRSIZE)(m_pCur - pSubName);
    if (m_pCur < m_pEnd && m_pCur[0] == L'.') {
      m_pCur++;
    }
  }

 protected:
  const FX_WCHAR* m_pStart;
  const FX_WCHAR* m_pEnd;
  const FX_WCHAR* m_pCur;
};
class CFieldTree {
 public:
  struct _Node {
    _Node* parent;
    CFX_ArrayTemplate<_Node*> children;
    CFX_WideString short_name;
    CPDF_FormField* field_ptr;
    int CountFields(int nLevel = 0) {
      if (nLevel > nMaxRecursion) {
        return 0;
      }
      if (field_ptr) {
        return 1;
      }
      int count = 0;
      for (int i = 0; i < children.GetSize(); i++) {
        count += children.GetAt(i)->CountFields(nLevel + 1);
      }
      return count;
    }
    CPDF_FormField* GetField(int* fields_to_go) {
      if (field_ptr) {
        if (*fields_to_go == 0) {
          return field_ptr;
        }
        --*fields_to_go;
        return NULL;
      }
      for (int i = 0; i < children.GetSize(); i++) {
        if (CPDF_FormField* pField = children.GetAt(i)->GetField(fields_to_go))
          return pField;
      }
      return NULL;
    }
    CPDF_FormField* GetField(int index) {
      int fields_to_go = index;
      return GetField(&fields_to_go);
    }
  };
  CFieldTree();
  ~CFieldTree();
  void SetField(const CFX_WideString& full_name, CPDF_FormField* field_ptr);
  CPDF_FormField* GetField(const CFX_WideString& full_name);
  CPDF_FormField* RemoveField(const CFX_WideString& full_name);
  void RemoveAll();
  _Node* FindNode(const CFX_WideString& full_name);
  _Node* AddChild(_Node* pParent,
                  const CFX_WideString& short_name,
                  CPDF_FormField* field_ptr);
  void RemoveNode(_Node* pNode, int nLevel = 0);
  _Node* _Lookup(_Node* pParent, const CFX_WideString& short_name);
  _Node m_Root;
};
CFieldTree::CFieldTree() {
  m_Root.parent = NULL;
  m_Root.field_ptr = NULL;
}
CFieldTree::~CFieldTree() {
  RemoveAll();
}
CFieldTree::_Node* CFieldTree::AddChild(_Node* pParent,
                                        const CFX_WideString& short_name,
                                        CPDF_FormField* field_ptr) {
  if (!pParent) {
    return NULL;
  }
  _Node* pNode = new _Node;
  pNode->parent = pParent;
  pNode->short_name = short_name;
  pNode->field_ptr = field_ptr;
  pParent->children.Add(pNode);
  return pNode;
}
void CFieldTree::RemoveNode(_Node* pNode, int nLevel) {
  if (!pNode) {
    return;
  }
  if (nLevel <= nMaxRecursion) {
    for (int i = 0; i < pNode->children.GetSize(); i++) {
      RemoveNode(pNode->children[i], nLevel + 1);
    }
  }
  delete pNode;
}
CFieldTree::_Node* CFieldTree::_Lookup(_Node* pParent,
                                       const CFX_WideString& short_name) {
  if (!pParent) {
    return NULL;
  }
  for (int i = 0; i < pParent->children.GetSize(); i++) {
    _Node* pNode = pParent->children[i];
    if (pNode->short_name.GetLength() == short_name.GetLength() &&
        FXSYS_memcmp(pNode->short_name.c_str(), short_name.c_str(),
                     short_name.GetLength() * sizeof(FX_WCHAR)) == 0) {
      return pNode;
    }
  }
  return NULL;
}
void CFieldTree::RemoveAll() {
  for (int i = 0; i < m_Root.children.GetSize(); i++) {
    RemoveNode(m_Root.children[i]);
  }
}
void CFieldTree::SetField(const CFX_WideString& full_name,
                          CPDF_FormField* field_ptr) {
  if (full_name == L"") {
    return;
  }
  CFieldNameExtractor name_extractor(full_name);
  const FX_WCHAR* pName;
  FX_STRSIZE nLength;
  name_extractor.GetNext(pName, nLength);
  _Node *pNode = &m_Root, *pLast = NULL;
  while (nLength > 0) {
    pLast = pNode;
    CFX_WideString name = CFX_WideString(pName, nLength);
    pNode = _Lookup(pLast, name);
    if (!pNode) {
      pNode = AddChild(pLast, name, NULL);
    }
    name_extractor.GetNext(pName, nLength);
  }
  if (pNode != &m_Root) {
    pNode->field_ptr = field_ptr;
  }
}
CPDF_FormField* CFieldTree::GetField(const CFX_WideString& full_name) {
  if (full_name == L"") {
    return NULL;
  }
  CFieldNameExtractor name_extractor(full_name);
  const FX_WCHAR* pName;
  FX_STRSIZE nLength;
  name_extractor.GetNext(pName, nLength);
  _Node *pNode = &m_Root, *pLast = NULL;
  while (nLength > 0 && pNode) {
    pLast = pNode;
    CFX_WideString name = CFX_WideString(pName, nLength);
    pNode = _Lookup(pLast, name);
    name_extractor.GetNext(pName, nLength);
  }
  return pNode ? pNode->field_ptr : NULL;
}
CPDF_FormField* CFieldTree::RemoveField(const CFX_WideString& full_name) {
  if (full_name == L"") {
    return NULL;
  }
  CFieldNameExtractor name_extractor(full_name);
  const FX_WCHAR* pName;
  FX_STRSIZE nLength;
  name_extractor.GetNext(pName, nLength);
  _Node *pNode = &m_Root, *pLast = NULL;
  while (nLength > 0 && pNode) {
    pLast = pNode;
    CFX_WideString name = CFX_WideString(pName, nLength);
    pNode = _Lookup(pLast, name);
    name_extractor.GetNext(pName, nLength);
  }
  if (pNode && pNode != &m_Root) {
    for (int i = 0; i < pLast->children.GetSize(); i++) {
      if (pNode == pLast->children[i]) {
        pLast->children.RemoveAt(i);
        break;
      }
    }
    CPDF_FormField* pField = pNode->field_ptr;
    RemoveNode(pNode);
    return pField;
  }
  return NULL;
}
CFieldTree::_Node* CFieldTree::FindNode(const CFX_WideString& full_name) {
  if (full_name == L"") {
    return NULL;
  }
  CFieldNameExtractor name_extractor(full_name);
  const FX_WCHAR* pName;
  FX_STRSIZE nLength;
  name_extractor.GetNext(pName, nLength);
  _Node *pNode = &m_Root, *pLast = NULL;
  while (nLength > 0 && pNode) {
    pLast = pNode;
    CFX_WideString name = CFX_WideString(pName, nLength);
    pNode = _Lookup(pLast, name);
    name_extractor.GetNext(pName, nLength);
  }
  return pNode;
}
CPDF_InterForm::CPDF_InterForm(CPDF_Document* pDocument, FX_BOOL bGenerateAP)
    : CFX_PrivateData(),
      m_pDocument(pDocument),
      m_bGenerateAP(bGenerateAP),
      m_pFormDict(nullptr),
      m_pFieldTree(new CFieldTree),
      m_pFormNotify(nullptr),
      m_bUpdated(FALSE) {
  CPDF_Dictionary* pRoot = m_pDocument->GetRoot();
  if (!pRoot)
    return;

  m_pFormDict = pRoot->GetDictBy("AcroForm");
  if (!m_pFormDict)
    return;

  CPDF_Array* pFields = m_pFormDict->GetArrayBy("Fields");
  if (!pFields)
    return;

  int count = pFields->GetCount();
  for (int i = 0; i < count; i++) {
    LoadField(pFields->GetDictAt(i));
  }
}

CPDF_InterForm::~CPDF_InterForm() {
  for (auto it : m_ControlMap)
    delete it.second;

  int nCount = m_pFieldTree->m_Root.CountFields();
  for (int i = 0; i < nCount; ++i) {
    delete m_pFieldTree->m_Root.GetField(i);
  }
}

FX_BOOL CPDF_InterForm::m_bUpdateAP = TRUE;
FX_BOOL CPDF_InterForm::UpdatingAPEnabled() {
  return m_bUpdateAP;
}
void CPDF_InterForm::EnableUpdateAP(FX_BOOL bUpdateAP) {
  m_bUpdateAP = bUpdateAP;
}
CFX_ByteString CPDF_InterForm::GenerateNewResourceName(
    const CPDF_Dictionary* pResDict,
    const FX_CHAR* csType,
    int iMinLen,
    const FX_CHAR* csPrefix) {
  CFX_ByteString csStr = csPrefix;
  CFX_ByteString csBType = csType;
  if (csStr.IsEmpty()) {
    if (csBType == "ExtGState") {
      csStr = "GS";
    } else if (csBType == "ColorSpace") {
      csStr = "CS";
    } else if (csBType == "Font") {
      csStr = "ZiTi";
    } else {
      csStr = "Res";
    }
  }
  CFX_ByteString csTmp = csStr;
  int iCount = csStr.GetLength();
  int m = 0;
  if (iMinLen > 0) {
    csTmp = "";
    while (m < iMinLen && m < iCount) {
      csTmp += csStr[m++];
    }
    while (m < iMinLen) {
      csTmp += '0' + m % 10;
      m++;
    }
  } else {
    m = iCount;
  }
  if (!pResDict) {
    return csTmp;
  }
  CPDF_Dictionary* pDict = pResDict->GetDictBy(csType);
  if (!pDict) {
    return csTmp;
  }
  int num = 0;
  CFX_ByteString bsNum;
  while (TRUE) {
    if (!pDict->KeyExist(csTmp + bsNum)) {
      return csTmp + bsNum;
    }
    if (m < iCount) {
      csTmp += csStr[m++];
    } else {
      bsNum.Format("%d", num++);
    }
    m++;
  }
  return csTmp;
}
#if _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_
typedef struct PDF_FONTDATA_ {
  FX_BOOL bFind;
  LOGFONTA lf;
} PDF_FONTDATA, FAR* LPDF_FONTDATA;
static int CALLBACK EnumFontFamExProc(ENUMLOGFONTEXA* lpelfe,
                                      NEWTEXTMETRICEX* lpntme,
                                      DWORD FontType,
                                      LPARAM lParam) {
  if (FontType != 0x004 || strchr(lpelfe->elfLogFont.lfFaceName, '@')) {
    return 1;
  }
  LPDF_FONTDATA pData = (LPDF_FONTDATA)lParam;
  memcpy(&pData->lf, &lpelfe->elfLogFont, sizeof(LOGFONTA));
  pData->bFind = TRUE;
  return 0;
}
static FX_BOOL RetrieveSpecificFont(LOGFONTA& lf) {
  PDF_FONTDATA fd;
  memset(&fd, 0, sizeof(PDF_FONTDATA));
  HDC hDC = ::GetDC(NULL);
  EnumFontFamiliesExA(hDC, &lf, (FONTENUMPROCA)EnumFontFamExProc, (LPARAM)&fd,
                      0);
  ::ReleaseDC(NULL, hDC);
  if (fd.bFind) {
    memcpy(&lf, &fd.lf, sizeof(LOGFONTA));
  }
  return fd.bFind;
}
static FX_BOOL RetrieveSpecificFont(uint8_t charSet,
                                    uint8_t pitchAndFamily,
                                    LPCSTR pcsFontName,
                                    LOGFONTA& lf) {
  memset(&lf, 0, sizeof(LOGFONTA));
  lf.lfCharSet = charSet;
  lf.lfPitchAndFamily = pitchAndFamily;
  if (pcsFontName) {
    // TODO(dsinclair): Should this be strncpy?
    strcpy(lf.lfFaceName, pcsFontName);
  }
  return RetrieveSpecificFont(lf);
}
#endif  // _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_

CPDF_Font* CPDF_InterForm::AddStandardFont(CPDF_Document* pDocument,
                                           CFX_ByteString csFontName) {
  if (!pDocument || csFontName.IsEmpty())
    return nullptr;

  if (csFontName == "ZapfDingbats")
    return pDocument->AddStandardFont(csFontName.c_str(), nullptr);

  CPDF_FontEncoding encoding(PDFFONT_ENCODING_WINANSI);
  return pDocument->AddStandardFont(csFontName.c_str(), &encoding);
}

CFX_ByteString CPDF_InterForm::GetNativeFont(uint8_t charSet, void* pLogFont) {
  CFX_ByteString csFontName;
#if _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_
  LOGFONTA lf;
  FX_BOOL bRet;
  if (charSet == ANSI_CHARSET) {
    csFontName = "Helvetica";
    return csFontName;
  }
  bRet = FALSE;
  if (charSet == SHIFTJIS_CHARSET) {
    bRet = RetrieveSpecificFont(charSet, DEFAULT_PITCH | FF_DONTCARE,
                                "MS Mincho", lf);
  } else if (charSet == GB2312_CHARSET) {
    bRet = RetrieveSpecificFont(charSet, DEFAULT_PITCH | FF_DONTCARE, "SimSun",
                                lf);
  } else if (charSet == CHINESEBIG5_CHARSET) {
    bRet = RetrieveSpecificFont(charSet, DEFAULT_PITCH | FF_DONTCARE, "MingLiU",
                                lf);
  }
  if (!bRet) {
    bRet = RetrieveSpecificFont(charSet, DEFAULT_PITCH | FF_DONTCARE,
                                "Arial Unicode MS", lf);
  }
  if (!bRet) {
    bRet = RetrieveSpecificFont(charSet, DEFAULT_PITCH | FF_DONTCARE,
                                "Microsoft Sans Serif", lf);
  }
  if (!bRet) {
    bRet = RetrieveSpecificFont(charSet, DEFAULT_PITCH | FF_DONTCARE, NULL, lf);
  }
  if (bRet) {
    if (pLogFont) {
      memcpy(pLogFont, &lf, sizeof(LOGFONTA));
    }
    csFontName = lf.lfFaceName;
    return csFontName;
  }
#endif
  return csFontName;
}
CFX_ByteString CPDF_InterForm::GetNativeFont(void* pLogFont) {
#if _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_
  uint8_t charSet = GetNativeCharSet();
  return GetNativeFont(charSet, pLogFont);
#else
  return CFX_ByteString();
#endif
}
uint8_t CPDF_InterForm::GetNativeCharSet() {
#if _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_
  uint8_t charSet = ANSI_CHARSET;
  UINT iCodePage = ::GetACP();
  switch (iCodePage) {
    case 932:
      charSet = SHIFTJIS_CHARSET;
      break;
    case 936:
      charSet = GB2312_CHARSET;
      break;
    case 950:
      charSet = CHINESEBIG5_CHARSET;
      break;
    case 1252:
      charSet = ANSI_CHARSET;
      break;
    case 874:
      charSet = THAI_CHARSET;
      break;
    case 949:
      charSet = HANGUL_CHARSET;
      break;
    case 1200:
      charSet = ANSI_CHARSET;
      break;
    case 1250:
      charSet = EASTEUROPE_CHARSET;
      break;
    case 1251:
      charSet = RUSSIAN_CHARSET;
      break;
    case 1253:
      charSet = GREEK_CHARSET;
      break;
    case 1254:
      charSet = TURKISH_CHARSET;
      break;
    case 1255:
      charSet = HEBREW_CHARSET;
      break;
    case 1256:
      charSet = ARABIC_CHARSET;
      break;
    case 1257:
      charSet = BALTIC_CHARSET;
      break;
    case 1258:
      charSet = VIETNAMESE_CHARSET;
      break;
    case 1361:
      charSet = JOHAB_CHARSET;
      break;
  }
  return charSet;
#else
  return 0;
#endif
}

CPDF_Font* CPDF_InterForm::AddNativeFont(uint8_t charSet,
                                         CPDF_Document* pDocument) {
  if (!pDocument)
    return nullptr;

#if _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_
  LOGFONTA lf;
  CFX_ByteString csFontName = GetNativeFont(charSet, &lf);
  if (!csFontName.IsEmpty()) {
    if (csFontName == "Helvetica")
      return AddStandardFont(pDocument, csFontName);
    return pDocument->AddWindowsFont(&lf, FALSE, TRUE);
  }
#endif
  return nullptr;
}

CPDF_Font* CPDF_InterForm::AddNativeFont(CPDF_Document* pDocument) {
  return pDocument ? AddNativeFont(GetNativeCharSet(), pDocument) : nullptr;
}

FX_BOOL CPDF_InterForm::ValidateFieldName(
    CFX_WideString& csNewFieldName,
    int iType,
    const CPDF_FormField* pExcludedField,
    const CPDF_FormControl* pExcludedControl) {
  if (csNewFieldName.IsEmpty()) {
    return FALSE;
  }
  int iPos = 0;
  int iLength = csNewFieldName.GetLength();
  CFX_WideString csSub;
  while (TRUE) {
    while (iPos < iLength &&
           (csNewFieldName[iPos] == L'.' || csNewFieldName[iPos] == L' ')) {
      iPos++;
    }
    if (iPos < iLength && !csSub.IsEmpty()) {
      csSub += L'.';
    }
    while (iPos < iLength && csNewFieldName[iPos] != L'.') {
      csSub += csNewFieldName[iPos++];
    }
    for (int i = csSub.GetLength() - 1; i > -1; i--) {
      if (csSub[i] == L' ' || csSub[i] == L'.') {
        csSub.SetAt(i, L'\0');
      } else {
        break;
      }
    }
    FX_DWORD dwCount = m_pFieldTree->m_Root.CountFields();
    for (FX_DWORD m = 0; m < dwCount; m++) {
      CPDF_FormField* pField = m_pFieldTree->m_Root.GetField(m);
      if (!pField) {
        continue;
      }
      if (pField == pExcludedField) {
        if (pExcludedControl) {
          if (pField->CountControls() < 2) {
            continue;
          }
        } else {
          continue;
        }
      }
      CFX_WideString csFullName = pField->GetFullName();
      int iRet = CompareFieldName(csSub, csFullName);
      if (iRet == 1) {
        if (pField->GetFieldType() != iType) {
          return FALSE;
        }
      } else if (iRet == 2 && csSub == csNewFieldName) {
        if (csFullName[iPos] == L'.') {
          return FALSE;
        }
      } else if (iRet == 3 && csSub == csNewFieldName) {
        if (csNewFieldName[csFullName.GetLength()] == L'.') {
          return FALSE;
        }
      }
    }
    if (iPos >= iLength) {
      break;
    }
  }
  if (csSub.IsEmpty()) {
    return FALSE;
  }
  csNewFieldName = csSub;
  return TRUE;
}
FX_BOOL CPDF_InterForm::ValidateFieldName(CFX_WideString& csNewFieldName,
                                          int iType) {
  return ValidateFieldName(csNewFieldName, iType, NULL, NULL);
}
FX_BOOL CPDF_InterForm::ValidateFieldName(const CPDF_FormField* pField,
                                          CFX_WideString& csNewFieldName) {
  return pField && !csNewFieldName.IsEmpty() &&
         ValidateFieldName(csNewFieldName,
                           ((CPDF_FormField*)pField)->GetFieldType(), pField,
                           NULL);
}
FX_BOOL CPDF_InterForm::ValidateFieldName(const CPDF_FormControl* pControl,
                                          CFX_WideString& csNewFieldName) {
  if (!pControl || csNewFieldName.IsEmpty()) {
    return FALSE;
  }
  CPDF_FormField* pField = ((CPDF_FormControl*)pControl)->GetField();
  return ValidateFieldName(csNewFieldName, pField->GetFieldType(), pField,
                           pControl);
}
int CPDF_InterForm::CompareFieldName(const CFX_ByteString& name1,
                                     const CFX_ByteString& name2) {
  const FX_CHAR* ptr1 = name1;
  const FX_CHAR* ptr2 = name2;
  if (name1.GetLength() == name2.GetLength()) {
    return name1 == name2 ? 1 : 0;
  }
  int i = 0;
  while (ptr1[i] == ptr2[i]) {
    i++;
  }
  if (i == name1.GetLength()) {
    return 2;
  }
  if (i == name2.GetLength()) {
    return 3;
  }
  return 0;
}
int CPDF_InterForm::CompareFieldName(const CFX_WideString& name1,
                                     const CFX_WideString& name2) {
  const FX_WCHAR* ptr1 = name1.c_str();
  const FX_WCHAR* ptr2 = name2.c_str();
  if (name1.GetLength() == name2.GetLength()) {
    return name1 == name2 ? 1 : 0;
  }
  int i = 0;
  while (ptr1[i] == ptr2[i]) {
    i++;
  }
  if (i == name1.GetLength()) {
    return 2;
  }
  if (i == name2.GetLength()) {
    return 3;
  }
  return 0;
}
FX_DWORD CPDF_InterForm::CountFields(const CFX_WideString& csFieldName) {
  if (csFieldName.IsEmpty()) {
    return (FX_DWORD)m_pFieldTree->m_Root.CountFields();
  }
  CFieldTree::_Node* pNode = m_pFieldTree->FindNode(csFieldName);
  return pNode ? pNode->CountFields() : 0;
}
CPDF_FormField* CPDF_InterForm::GetField(FX_DWORD index,
                                         const CFX_WideString& csFieldName) {
  if (csFieldName == L"") {
    return m_pFieldTree->m_Root.GetField(index);
  }
  CFieldTree::_Node* pNode = m_pFieldTree->FindNode(csFieldName);
  return pNode ? pNode->GetField(index) : nullptr;
}

CPDF_FormField* CPDF_InterForm::GetFieldByDict(
    CPDF_Dictionary* pFieldDict) const {
  if (!pFieldDict) {
    return NULL;
  }
  CFX_WideString csWName = GetFullName(pFieldDict);
  return m_pFieldTree->GetField(csWName);
}

CPDF_FormControl* CPDF_InterForm::GetControlAtPoint(CPDF_Page* pPage,
                                                    FX_FLOAT pdf_x,
                                                    FX_FLOAT pdf_y,
                                                    int* z_order) const {
  CPDF_Array* pAnnotList = pPage->m_pFormDict->GetArrayBy("Annots");
  if (!pAnnotList)
    return nullptr;

  for (FX_DWORD i = pAnnotList->GetCount(); i > 0; --i) {
    FX_DWORD annot_index = i - 1;
    CPDF_Dictionary* pAnnot = pAnnotList->GetDictAt(annot_index);
    if (!pAnnot)
      continue;

    const auto it = m_ControlMap.find(pAnnot);
    if (it == m_ControlMap.end())
      continue;

    CPDF_FormControl* pControl = it->second;
    CFX_FloatRect rect = pControl->GetRect();
    if (!rect.Contains(pdf_x, pdf_y))
      continue;

    if (z_order)
      *z_order = annot_index;
    return pControl;
  }
  return nullptr;
}

CPDF_FormControl* CPDF_InterForm::GetControlByDict(
    const CPDF_Dictionary* pWidgetDict) const {
  const auto it = m_ControlMap.find(pWidgetDict);
  return it != m_ControlMap.end() ? it->second : nullptr;
}

FX_BOOL CPDF_InterForm::NeedConstructAP() {
  return m_pFormDict && m_pFormDict->GetBooleanBy("NeedAppearances");
}
void CPDF_InterForm::NeedConstructAP(FX_BOOL bNeedAP) {
  if (!m_pFormDict) {
    InitInterFormDict(m_pFormDict, m_pDocument);
  }
  m_pFormDict->SetAtBoolean("NeedAppearances", bNeedAP);
  m_bGenerateAP = bNeedAP;
}
int CPDF_InterForm::CountFieldsInCalculationOrder() {
  if (!m_pFormDict) {
    return 0;
  }
  CPDF_Array* pArray = m_pFormDict->GetArrayBy("CO");
  return pArray ? pArray->GetCount() : 0;
}
CPDF_FormField* CPDF_InterForm::GetFieldInCalculationOrder(int index) {
  if (!m_pFormDict || index < 0) {
    return NULL;
  }
  CPDF_Array* pArray = m_pFormDict->GetArrayBy("CO");
  if (!pArray) {
    return NULL;
  }
  if (CPDF_Dictionary* pElement =
          ToDictionary(pArray->GetElementValue(index))) {
    return GetFieldByDict(pElement);
  }
  return NULL;
}
int CPDF_InterForm::FindFieldInCalculationOrder(const CPDF_FormField* pField) {
  if (!m_pFormDict || !pField) {
    return -1;
  }
  CPDF_Array* pArray = m_pFormDict->GetArrayBy("CO");
  if (!pArray) {
    return -1;
  }
  for (FX_DWORD i = 0; i < pArray->GetCount(); i++) {
    CPDF_Object* pElement = pArray->GetElementValue(i);
    if (pElement == pField->m_pDict) {
      return i;
    }
  }
  return -1;
}
FX_DWORD CPDF_InterForm::CountFormFonts() {
  return CountInterFormFonts(m_pFormDict);
}
CPDF_Font* CPDF_InterForm::GetFormFont(FX_DWORD index,
                                       CFX_ByteString& csNameTag) {
  return GetInterFormFont(m_pFormDict, m_pDocument, index, csNameTag);
}
CPDF_Font* CPDF_InterForm::GetFormFont(CFX_ByteString csNameTag) {
  return GetInterFormFont(m_pFormDict, m_pDocument, csNameTag);
}
CPDF_Font* CPDF_InterForm::GetFormFont(CFX_ByteString csFontName,
                                       CFX_ByteString& csNameTag) {
  return GetInterFormFont(m_pFormDict, m_pDocument, csFontName, csNameTag);
}
CPDF_Font* CPDF_InterForm::GetNativeFormFont(uint8_t charSet,
                                             CFX_ByteString& csNameTag) {
  return GetNativeInterFormFont(m_pFormDict, m_pDocument, charSet, csNameTag);
}
CPDF_Font* CPDF_InterForm::GetNativeFormFont(CFX_ByteString& csNameTag) {
  return GetNativeInterFormFont(m_pFormDict, m_pDocument, csNameTag);
}
FX_BOOL CPDF_InterForm::FindFormFont(const CPDF_Font* pFont,
                                     CFX_ByteString& csNameTag) {
  return FindInterFormFont(m_pFormDict, pFont, csNameTag);
}
FX_BOOL CPDF_InterForm::FindFormFont(CFX_ByteString csFontName,
                                     CPDF_Font*& pFont,
                                     CFX_ByteString& csNameTag) {
  return FindInterFormFont(m_pFormDict, m_pDocument, csFontName, pFont,
                           csNameTag);
}
void CPDF_InterForm::AddFormFont(const CPDF_Font* pFont,
                                 CFX_ByteString& csNameTag) {
  AddInterFormFont(m_pFormDict, m_pDocument, pFont, csNameTag);
  m_bUpdated = TRUE;
}
CPDF_Font* CPDF_InterForm::AddNativeFormFont(uint8_t charSet,
                                             CFX_ByteString& csNameTag) {
  m_bUpdated = TRUE;
  return AddNativeInterFormFont(m_pFormDict, m_pDocument, charSet, csNameTag);
}
CPDF_Font* CPDF_InterForm::AddNativeFormFont(CFX_ByteString& csNameTag) {
  m_bUpdated = TRUE;
  return AddNativeInterFormFont(m_pFormDict, m_pDocument, csNameTag);
}
void CPDF_InterForm::RemoveFormFont(const CPDF_Font* pFont) {
  m_bUpdated = TRUE;
  RemoveInterFormFont(m_pFormDict, pFont);
}
void CPDF_InterForm::RemoveFormFont(CFX_ByteString csNameTag) {
  m_bUpdated = TRUE;
  RemoveInterFormFont(m_pFormDict, csNameTag);
}

CPDF_DefaultAppearance CPDF_InterForm::GetDefaultAppearance() {
  if (!m_pFormDict)
    return CPDF_DefaultAppearance();
  return CPDF_DefaultAppearance(m_pFormDict->GetStringBy("DA"));
}

CPDF_Font* CPDF_InterForm::GetDefaultFormFont() {
  return GetDefaultInterFormFont(m_pFormDict, m_pDocument);
}
int CPDF_InterForm::GetFormAlignment() {
  return m_pFormDict ? m_pFormDict->GetIntegerBy("Q", 0) : 0;
}

bool CPDF_InterForm::ResetForm(const std::vector<CPDF_FormField*>& fields,
                               bool bIncludeOrExclude,
                               bool bNotify) {
  if (bNotify && m_pFormNotify && m_pFormNotify->BeforeFormReset(this) < 0)
    return false;

  int nCount = m_pFieldTree->m_Root.CountFields();
  for (int i = 0; i < nCount; ++i) {
    CPDF_FormField* pField = m_pFieldTree->m_Root.GetField(i);
    if (!pField)
      continue;

    if (bIncludeOrExclude == pdfium::ContainsValue(fields, pField))
      pField->ResetField(bNotify);
  }
  if (bNotify && m_pFormNotify)
    m_pFormNotify->AfterFormReset(this);
  return true;
}

bool CPDF_InterForm::ResetForm(bool bNotify) {
  if (bNotify && m_pFormNotify && m_pFormNotify->BeforeFormReset(this) < 0)
    return false;

  int nCount = m_pFieldTree->m_Root.CountFields();
  for (int i = 0; i < nCount; ++i) {
    CPDF_FormField* pField = m_pFieldTree->m_Root.GetField(i);
    if (!pField)
      continue;

    pField->ResetField(bNotify);
  }
  if (bNotify && m_pFormNotify)
    m_pFormNotify->AfterFormReset(this);
  return true;
}

void CPDF_InterForm::LoadField(CPDF_Dictionary* pFieldDict, int nLevel) {
  if (nLevel > nMaxRecursion) {
    return;
  }
  if (!pFieldDict) {
    return;
  }
  FX_DWORD dwParentObjNum = pFieldDict->GetObjNum();
  CPDF_Array* pKids = pFieldDict->GetArrayBy("Kids");
  if (!pKids) {
    AddTerminalField(pFieldDict);
    return;
  }
  CPDF_Dictionary* pFirstKid = pKids->GetDictAt(0);
  if (!pFirstKid) {
    return;
  }
  if (pFirstKid->KeyExist("T") || pFirstKid->KeyExist("Kids")) {
    for (FX_DWORD i = 0; i < pKids->GetCount(); i++) {
      CPDF_Dictionary* pChildDict = pKids->GetDictAt(i);
      if (pChildDict) {
        if (pChildDict->GetObjNum() != dwParentObjNum) {
          LoadField(pChildDict, nLevel + 1);
        }
      }
    }
  } else {
    AddTerminalField(pFieldDict);
  }
}
FX_BOOL CPDF_InterForm::HasXFAForm() const {
  return m_pFormDict && m_pFormDict->GetArrayBy("XFA");
}
void CPDF_InterForm::FixPageFields(const CPDF_Page* pPage) {
  CPDF_Dictionary* pPageDict = pPage->m_pFormDict;
  if (!pPageDict) {
    return;
  }
  CPDF_Array* pAnnots = pPageDict->GetArrayBy("Annots");
  if (!pAnnots) {
    return;
  }
  int iAnnotCount = pAnnots->GetCount();
  for (int i = 0; i < iAnnotCount; i++) {
    CPDF_Dictionary* pAnnot = pAnnots->GetDictAt(i);
    if (pAnnot && pAnnot->GetStringBy("Subtype") == "Widget") {
      LoadField(pAnnot);
    }
  }
}
CPDF_FormField* CPDF_InterForm::AddTerminalField(CPDF_Dictionary* pFieldDict) {
  if (!pFieldDict->KeyExist("T")) {
    return NULL;
  }
  CPDF_Dictionary* pDict = pFieldDict;
  CFX_WideString csWName = GetFullName(pFieldDict);
  if (csWName.IsEmpty()) {
    return NULL;
  }
  CPDF_FormField* pField = NULL;
  pField = m_pFieldTree->GetField(csWName);
  if (!pField) {
    CPDF_Dictionary* pParent = pFieldDict;
    if (!pFieldDict->KeyExist("T") &&
        pFieldDict->GetStringBy("Subtype") == "Widget") {
      pParent = pFieldDict->GetDictBy("Parent");
      if (!pParent) {
        pParent = pFieldDict;
      }
    }
    if (pParent && pParent != pFieldDict && !pParent->KeyExist("FT")) {
      if (pFieldDict->KeyExist("FT")) {
        CPDF_Object* pFTValue = pFieldDict->GetElementValue("FT");
        if (pFTValue) {
          pParent->SetAt("FT", pFTValue->Clone());
        }
      }
      if (pFieldDict->KeyExist("Ff")) {
        CPDF_Object* pFfValue = pFieldDict->GetElementValue("Ff");
        if (pFfValue) {
          pParent->SetAt("Ff", pFfValue->Clone());
        }
      }
    }
    pField = new CPDF_FormField(this, pParent);
    CPDF_Object* pTObj = pDict->GetElement("T");
    if (ToReference(pTObj)) {
      CPDF_Object* pClone = pTObj->Clone(TRUE);
      if (pClone)
        pDict->SetAt("T", pClone);
      else
        pDict->SetAtName("T", "");
    }
    m_pFieldTree->SetField(csWName, pField);
  }
  CPDF_Array* pKids = pFieldDict->GetArrayBy("Kids");
  if (!pKids) {
    if (pFieldDict->GetStringBy("Subtype") == "Widget") {
      AddControl(pField, pFieldDict);
    }
  } else {
    for (FX_DWORD i = 0; i < pKids->GetCount(); i++) {
      CPDF_Dictionary* pKid = pKids->GetDictAt(i);
      if (!pKid) {
        continue;
      }
      if (pKid->GetStringBy("Subtype") != "Widget") {
        continue;
      }
      AddControl(pField, pKid);
    }
  }
  return pField;
}
CPDF_FormControl* CPDF_InterForm::AddControl(const CPDF_FormField* pField,
                                             CPDF_Dictionary* pWidgetDict) {
  const auto it = m_ControlMap.find(pWidgetDict);
  if (it != m_ControlMap.end())
    return it->second;

  CPDF_FormControl* pControl =
      new CPDF_FormControl((CPDF_FormField*)pField, pWidgetDict);
  m_ControlMap[pWidgetDict] = pControl;
  ((CPDF_FormField*)pField)->m_ControlList.Add(pControl);
  return pControl;
}

CPDF_FormField* CPDF_InterForm::CheckRequiredFields(
    const std::vector<CPDF_FormField*>* fields,
    bool bIncludeOrExclude) const {
  int nCount = m_pFieldTree->m_Root.CountFields();
  for (int i = 0; i < nCount; ++i) {
    CPDF_FormField* pField = m_pFieldTree->m_Root.GetField(i);
    if (!pField)
      continue;

    int32_t iType = pField->GetType();
    if (iType == CPDF_FormField::PushButton ||
        iType == CPDF_FormField::CheckBox || iType == CPDF_FormField::ListBox) {
      continue;
    }
    FX_DWORD dwFlags = pField->GetFieldFlags();
    // TODO(thestig): Look up these magic numbers and add constants for them.
    if (dwFlags & 0x04)
      continue;

    bool bFind = true;
    if (fields)
      bFind = pdfium::ContainsValue(*fields, pField);
    if (bIncludeOrExclude == bFind) {
      CPDF_Dictionary* pFieldDict = pField->m_pDict;
      if ((dwFlags & 0x02) != 0 && pFieldDict->GetStringBy("V").IsEmpty()) {
        return pField;
      }
    }
  }
  return nullptr;
}

CFDF_Document* CPDF_InterForm::ExportToFDF(const CFX_WideStringC& pdf_path,
                                           bool bSimpleFileSpec) const {
  std::vector<CPDF_FormField*> fields;
  int nCount = m_pFieldTree->m_Root.CountFields();
  for (int i = 0; i < nCount; ++i)
    fields.push_back(m_pFieldTree->m_Root.GetField(i));
  return ExportToFDF(pdf_path, fields, true, bSimpleFileSpec);
}

CFDF_Document* CPDF_InterForm::ExportToFDF(
    const CFX_WideStringC& pdf_path,
    const std::vector<CPDF_FormField*>& fields,
    bool bIncludeOrExclude,
    bool bSimpleFileSpec) const {
  CFDF_Document* pDoc = CFDF_Document::CreateNewDoc();
  if (!pDoc) {
    return NULL;
  }
  CPDF_Dictionary* pMainDict = pDoc->GetRoot()->GetDictBy("FDF");
  if (!pdf_path.IsEmpty()) {
    if (bSimpleFileSpec) {
      CFX_WideString wsFilePath = CPDF_FileSpec::EncodeFileName(pdf_path);
      pMainDict->SetAtString("F", CFX_ByteString::FromUnicode(wsFilePath));
      pMainDict->SetAtString("UF", PDF_EncodeText(wsFilePath));
    } else {
      CPDF_FileSpec filespec;
      filespec.SetFileName(pdf_path);
      pMainDict->SetAt("F", filespec.GetObj());
    }
  }
  CPDF_Array* pFields = new CPDF_Array;
  pMainDict->SetAt("Fields", pFields);
  int nCount = m_pFieldTree->m_Root.CountFields();
  for (int i = 0; i < nCount; i++) {
    CPDF_FormField* pField = m_pFieldTree->m_Root.GetField(i);
    if (!pField || pField->GetType() == CPDF_FormField::PushButton) {
      continue;
    }
    FX_DWORD dwFlags = pField->GetFieldFlags();
    if (dwFlags & 0x04)
      continue;

    if (bIncludeOrExclude == pdfium::ContainsValue(fields, pField)) {
      if ((dwFlags & 0x02) != 0 && pField->m_pDict->GetStringBy("V").IsEmpty())
        continue;

      CFX_WideString fullname = GetFullName(pField->GetFieldDict());
      CPDF_Dictionary* pFieldDict = new CPDF_Dictionary;
      pFieldDict->SetAt("T", new CPDF_String(fullname));
      if (pField->GetType() == CPDF_FormField::CheckBox ||
          pField->GetType() == CPDF_FormField::RadioButton) {
        CFX_WideString csExport = pField->GetCheckValue(FALSE);
        CFX_ByteString csBExport = PDF_EncodeText(csExport);
        CPDF_Object* pOpt = FPDF_GetFieldAttr(pField->m_pDict, "Opt");
        if (pOpt)
          pFieldDict->SetAtString("V", csBExport);
        else
          pFieldDict->SetAtName("V", csBExport);
      } else {
        CPDF_Object* pV = FPDF_GetFieldAttr(pField->m_pDict, "V");
        if (pV)
          pFieldDict->SetAt("V", pV->Clone(TRUE));
      }
      pFields->Add(pFieldDict);
    }
  }
  return pDoc;
}

void CPDF_InterForm::FDF_ImportField(CPDF_Dictionary* pFieldDict,
                                     const CFX_WideString& parent_name,
                                     FX_BOOL bNotify,
                                     int nLevel) {
  CFX_WideString name;
  if (!parent_name.IsEmpty()) {
    name = parent_name + L".";
  }
  name += pFieldDict->GetUnicodeTextBy("T");
  CPDF_Array* pKids = pFieldDict->GetArrayBy("Kids");
  if (pKids) {
    for (FX_DWORD i = 0; i < pKids->GetCount(); i++) {
      CPDF_Dictionary* pKid = pKids->GetDictAt(i);
      if (!pKid) {
        continue;
      }
      if (nLevel <= nMaxRecursion) {
        FDF_ImportField(pKid, name, bNotify, nLevel + 1);
      }
    }
    return;
  }
  if (!pFieldDict->KeyExist("V")) {
    return;
  }
  CPDF_FormField* pField = m_pFieldTree->GetField(name);
  if (!pField) {
    return;
  }
  CFX_WideString csWValue =
      FPDFDOC_FDF_GetFieldValue(*pFieldDict, m_bsEncoding);
  int iType = pField->GetFieldType();
  if (bNotify && m_pFormNotify) {
    int iRet = 0;
    if (iType == FIELDTYPE_LISTBOX) {
      iRet = m_pFormNotify->BeforeSelectionChange(pField, csWValue);
    } else if (iType == FIELDTYPE_COMBOBOX || iType == FIELDTYPE_TEXTFIELD) {
      iRet = m_pFormNotify->BeforeValueChange(pField, csWValue);
    }
    if (iRet < 0) {
      return;
    }
  }
  pField->SetValue(csWValue);
  CPDF_FormField::Type eType = pField->GetType();
  if ((eType == CPDF_FormField::ListBox || eType == CPDF_FormField::ComboBox) &&
      pFieldDict->KeyExist("Opt")) {
    pField->m_pDict->SetAt("Opt",
                           pFieldDict->GetElementValue("Opt")->Clone(TRUE));
  }
  if (bNotify && m_pFormNotify) {
    if (iType == FIELDTYPE_CHECKBOX || iType == FIELDTYPE_RADIOBUTTON) {
      m_pFormNotify->AfterCheckedStatusChange(pField);
    } else if (iType == FIELDTYPE_LISTBOX) {
      m_pFormNotify->AfterSelectionChange(pField);
    } else if (iType == FIELDTYPE_COMBOBOX || iType == FIELDTYPE_TEXTFIELD) {
      m_pFormNotify->AfterValueChange(pField);
    }
  }
  if (CPDF_InterForm::m_bUpdateAP) {
    pField->UpdateAP(NULL);
  }
}
FX_BOOL CPDF_InterForm::ImportFromFDF(const CFDF_Document* pFDF,
                                      FX_BOOL bNotify) {
  if (!pFDF) {
    return FALSE;
  }
  CPDF_Dictionary* pMainDict = pFDF->GetRoot()->GetDictBy("FDF");
  if (!pMainDict) {
    return FALSE;
  }
  CPDF_Array* pFields = pMainDict->GetArrayBy("Fields");
  if (!pFields) {
    return FALSE;
  }
  m_bsEncoding = pMainDict->GetStringBy("Encoding");
  if (bNotify && m_pFormNotify) {
    int iRet = m_pFormNotify->BeforeFormImportData(this);
    if (iRet < 0) {
      return FALSE;
    }
  }
  for (FX_DWORD i = 0; i < pFields->GetCount(); i++) {
    CPDF_Dictionary* pField = pFields->GetDictAt(i);
    if (!pField) {
      continue;
    }
    FDF_ImportField(pField, L"", bNotify);
  }
  if (bNotify && m_pFormNotify) {
    m_pFormNotify->AfterFormImportData(this);
  }
  return TRUE;
}
void CPDF_InterForm::SetFormNotify(const CPDF_FormNotify* pNotify) {
  m_pFormNotify = (CPDF_FormNotify*)pNotify;
}
