// 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 "../../include/fpdfdoc/fpdf_doc.h"
#include "doc_utils.h"

const int nMaxRecursion = 32;

class _CFieldNameExtractor {
 public:
  _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_PtrArray 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 += ((_Node*)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++) {
        _Node* pNode = (_Node*)children.GetAt(i);
        CPDF_FormField* pField = pNode->GetField(fields_to_go);
        if (pField) {
          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 == NULL) {
    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 == NULL) {
    return;
  }
  if (nLevel > nMaxRecursion) {
    delete pNode;
    return;
  }
  CFX_PtrArray& ptr_array = pNode->children;
  for (int i = 0; i < ptr_array.GetSize(); i++) {
    _Node* pChild = (_Node*)ptr_array[i];
    RemoveNode(pChild, nLevel + 1);
  }
  delete pNode;
}
CFieldTree::_Node* CFieldTree::_Lookup(_Node* pParent,
                                       const CFX_WideString& short_name) {
  if (pParent == NULL) {
    return NULL;
  }
  CFX_PtrArray& ptr_array = pParent->children;
  for (int i = 0; i < ptr_array.GetSize(); i++) {
    _Node* pNode = (_Node*)ptr_array[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() {
  CFX_PtrArray& ptr_array = m_Root.children;
  for (int i = 0; i < ptr_array.GetSize(); i++) {
    _Node* pNode = (_Node*)ptr_array[i];
    RemoveNode(pNode);
  }
}
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 == NULL) {
      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) {
    CFX_PtrArray& ptr_array = pLast->children;
    for (int i = 0; i < ptr_array.GetSize(); i++) {
      if (pNode == (_Node*)ptr_array[i]) {
        ptr_array.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_pFormNotify = NULL;
  m_bUpdated = FALSE;
  m_pFieldTree = new CFieldTree;
  CPDF_Dictionary* pRoot = m_pDocument->GetRoot();
  m_pFormDict = pRoot->GetDict("AcroForm");
  if (m_pFormDict == NULL) {
    return;
  }
  CPDF_Array* pFields = m_pFormDict->GetArray("Fields");
  if (pFields == NULL) {
    return;
  }
  int count = pFields->GetCount();
  for (int i = 0; i < count; i++) {
    LoadField(pFields->GetDict(i));
  }
}
CPDF_InterForm::~CPDF_InterForm() {
  FX_POSITION pos = m_ControlMap.GetStartPosition();
  while (pos) {
    void* key;
    void* value;
    m_ControlMap.GetNextAssoc(pos, key, value);
    delete (CPDF_FormControl*)value;
  }
  if (m_pFieldTree != NULL) {
    int nCount = m_pFieldTree->m_Root.CountFields();
    for (int i = 0; i < nCount; i++) {
      CPDF_FormField* pField = m_pFieldTree->m_Root.GetField(i);
      delete pField;
    }
    delete m_pFieldTree;
  }
}
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 == NULL) {
    return csTmp;
  }
  CPDF_Dictionary* pDict = pResDict->GetDict(csType);
  if (pDict == NULL) {
    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, '@') != NULL) {
    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 != NULL) {
    strcpy(lf.lfFaceName, pcsFontName);
  }
  return RetrieveSpecificFont(lf);
}
static FX_BOOL RetrieveStockFont(int iFontObject,
                                 uint8_t charSet,
                                 LOGFONTA& lf) {
  HFONT hFont = (HFONT)::GetStockObject(iFontObject);
  if (hFont != NULL) {
    memset(&lf, 0, sizeof(LOGFONTA));
    int iRet = ::GetObject(hFont, sizeof(LOGFONTA), &lf);
    if (iRet > 0 && (lf.lfCharSet == charSet || charSet == 255)) {
      return RetrieveSpecificFont(lf);
    }
  }
  return FALSE;
}
#endif
CPDF_Font* CPDF_InterForm::AddSystemDefaultFont(
    const CPDF_Document* pDocument) {
  if (pDocument == NULL) {
    return NULL;
  }
  CPDF_Font* pFont = NULL;
#if _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_
  LOGFONTA lf;
  FX_BOOL bRet;
  bRet = RetrieveStockFont(DEFAULT_GUI_FONT, 255, lf);
  if (!bRet) {
    bRet = RetrieveStockFont(SYSTEM_FONT, 255, lf);
  }
  if (bRet) {
    pFont = ((CPDF_Document*)pDocument)->AddWindowsFont(&lf, FALSE, TRUE);
  }
#endif
  return pFont;
}
CPDF_Font* CPDF_InterForm::AddSystemFont(const CPDF_Document* pDocument,
                                         CFX_ByteString csFontName,
                                         uint8_t iCharSet) {
  if (pDocument == NULL || csFontName.IsEmpty()) {
    return NULL;
  }
#if _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_
  if (iCharSet == 1) {
    iCharSet = GetNativeCharSet();
  }
  HFONT hFont = ::CreateFontA(
      0, 0, 0, 0, 0, 0, 0, 0, iCharSet, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS,
      DEFAULT_QUALITY, DEFAULT_PITCH | FF_DONTCARE, csFontName.c_str());
  if (hFont != NULL) {
    LOGFONTA lf;
    memset(&lf, 0, sizeof(LOGFONTA));
    ::GetObjectA(hFont, sizeof(LOGFONTA), &lf);
    ::DeleteObject(hFont);
    if (strlen(lf.lfFaceName) > 0) {
      return ((CPDF_Document*)pDocument)->AddWindowsFont(&lf, FALSE, TRUE);
    }
  }
#endif
  return NULL;
}
CPDF_Font* CPDF_InterForm::AddSystemFont(const CPDF_Document* pDocument,
                                         CFX_WideString csFontName,
                                         uint8_t iCharSet) {
  if (pDocument == NULL || csFontName.IsEmpty()) {
    return NULL;
  }
#if _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_
  if (iCharSet == 1) {
    iCharSet = GetNativeCharSet();
  }
  HFONT hFont = ::CreateFontW(
      0, 0, 0, 0, 0, 0, 0, 0, iCharSet, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS,
      DEFAULT_QUALITY, DEFAULT_PITCH | FF_DONTCARE, csFontName.c_str());
  if (hFont != NULL) {
    LOGFONTA lf;
    memset(&lf, 0, sizeof(LOGFONTA));
    ::GetObject(hFont, sizeof(LOGFONTA), &lf);
    ::DeleteObject(hFont);
    if (strlen(lf.lfFaceName) > 0) {
      return ((CPDF_Document*)pDocument)->AddWindowsFont(&lf, FALSE, TRUE);
    }
  }
#endif
  return NULL;
}
CPDF_Font* CPDF_InterForm::AddStandardFont(const CPDF_Document* pDocument,
                                           CFX_ByteString csFontName) {
  if (pDocument == NULL || csFontName.IsEmpty()) {
    return NULL;
  }
  CPDF_Font* pFont = NULL;
  if (csFontName == "ZapfDingbats") {
    pFont = ((CPDF_Document*)pDocument)->AddStandardFont(csFontName, NULL);
  } else {
    CPDF_FontEncoding encoding(PDFFONT_ENCODING_WINANSI);
    pFont = ((CPDF_Document*)pDocument)->AddStandardFont(csFontName, &encoding);
  }
  return pFont;
}
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 != NULL) {
      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,
                                         const CPDF_Document* pDocument) {
  if (pDocument == NULL) {
    return NULL;
  }
  CPDF_Font* pFont = NULL;
#if _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_
  LOGFONTA lf;
  CFX_ByteString csFontName = GetNativeFont(charSet, &lf);
  if (!csFontName.IsEmpty()) {
    if (csFontName == "Helvetica") {
      pFont = AddStandardFont(pDocument, csFontName);
    } else {
      pFont = ((CPDF_Document*)pDocument)->AddWindowsFont(&lf, FALSE, TRUE);
    }
  }
#endif
  return pFont;
}
CPDF_Font* CPDF_InterForm::AddNativeFont(const CPDF_Document* pDocument) {
  if (pDocument == NULL) {
    return NULL;
  }
  CPDF_Font* pFont = NULL;
  uint8_t charSet = GetNativeCharSet();
  pFont = AddNativeFont(charSet, pDocument);
  return pFont;
}
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 == NULL) {
        continue;
      }
      if (pField == pExcludedField) {
        if (pExcludedControl != NULL) {
          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) {
  if (pField == NULL || csNewFieldName.IsEmpty()) {
    return FALSE;
  }
  return ValidateFieldName(
      csNewFieldName, ((CPDF_FormField*)pField)->GetFieldType(), pField, NULL);
}
FX_BOOL CPDF_InterForm::ValidateFieldName(const CPDF_FormControl* pControl,
                                          CFX_WideString& csNewFieldName) {
  if (pControl == NULL || 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);
  if (pNode == NULL) {
    return 0;
  }
  return pNode->CountFields();
}
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);
  if (pNode == NULL) {
    return NULL;
  }
  return pNode->GetField(index);
}
void CPDF_InterForm::GetAllFieldNames(CFX_WideStringArray& allFieldNames) {
  allFieldNames.RemoveAll();
  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) {
      CFX_WideString full_name = GetFullName(pField->GetFieldDict());
      allFieldNames.Add(full_name);
    }
  }
}
FX_BOOL CPDF_InterForm::IsValidFormField(const void* pField) {
  if (pField == NULL) {
    return FALSE;
  }
  int nCount = m_pFieldTree->m_Root.CountFields();
  for (int i = 0; i < nCount; i++) {
    CPDF_FormField* pFormField = m_pFieldTree->m_Root.GetField(i);
    if (pField == pFormField) {
      return TRUE;
    }
  }
  return FALSE;
}
CPDF_FormField* CPDF_InterForm::GetFieldByDict(
    CPDF_Dictionary* pFieldDict) const {
  if (pFieldDict == NULL) {
    return NULL;
  }
  CFX_WideString csWName = GetFullName(pFieldDict);
  return m_pFieldTree->GetField(csWName);
}
FX_DWORD CPDF_InterForm::CountControls(CFX_WideString csFieldName) {
  if (csFieldName.IsEmpty()) {
    return (FX_DWORD)m_ControlMap.GetCount();
  }
  CPDF_FormField* pField = m_pFieldTree->GetField(csFieldName);
  if (pField == NULL) {
    return 0;
  }
  return pField->m_ControlList.GetSize();
}
CPDF_FormControl* CPDF_InterForm::GetControl(FX_DWORD index,
                                             CFX_WideString csFieldName) {
  CPDF_FormField* pField = m_pFieldTree->GetField(csFieldName);
  if (pField == NULL) {
    return NULL;
  }
  if (index < (FX_DWORD)pField->m_ControlList.GetSize()) {
    return (CPDF_FormControl*)pField->m_ControlList.GetAt(index);
  }
  return NULL;
}
FX_BOOL CPDF_InterForm::IsValidFormControl(const void* pControl) {
  if (pControl == NULL) {
    return FALSE;
  }
  FX_POSITION pos = m_ControlMap.GetStartPosition();
  while (pos) {
    CPDF_Dictionary* pWidgetDict = NULL;
    void* pFormControl = NULL;
    m_ControlMap.GetNextAssoc(pos, (void*&)pWidgetDict, pFormControl);
    if (pControl == pFormControl) {
      return TRUE;
    }
  }
  return FALSE;
}
int CPDF_InterForm::CountPageControls(CPDF_Page* pPage) const {
  CPDF_Array* pAnnotList = pPage->m_pFormDict->GetArray("Annots");
  if (pAnnotList == NULL) {
    return 0;
  }
  int count = 0;
  for (FX_DWORD i = 0; i < pAnnotList->GetCount(); i++) {
    CPDF_Dictionary* pAnnot = pAnnotList->GetDict(i);
    if (pAnnot == NULL) {
      continue;
    }
    CPDF_FormControl* pControl;
    if (!m_ControlMap.Lookup(pAnnot, (void*&)pControl)) {
      continue;
    }
    count++;
  }
  return count;
}
CPDF_FormControl* CPDF_InterForm::GetPageControl(CPDF_Page* pPage,
                                                 int index) const {
  CPDF_Array* pAnnotList = pPage->m_pFormDict->GetArray("Annots");
  if (pAnnotList == NULL) {
    return NULL;
  }
  int count = 0;
  for (FX_DWORD i = 0; i < pAnnotList->GetCount(); i++) {
    CPDF_Dictionary* pAnnot = pAnnotList->GetDict(i);
    if (pAnnot == NULL) {
      continue;
    }
    CPDF_FormControl* pControl;
    if (!m_ControlMap.Lookup(pAnnot, (void*&)pControl)) {
      continue;
    }
    if (index == count) {
      return pControl;
    }
    count++;
  }
  return NULL;
}
CPDF_FormControl* CPDF_InterForm::GetControlAtPoint(CPDF_Page* pPage,
                                                    FX_FLOAT pdf_x,
                                                    FX_FLOAT pdf_y) const {
  CPDF_Array* pAnnotList = pPage->m_pFormDict->GetArray("Annots");
  if (pAnnotList == NULL) {
    return NULL;
  }
  for (FX_DWORD i = pAnnotList->GetCount(); i > 0; i--) {
    CPDF_Dictionary* pAnnot = pAnnotList->GetDict(i - 1);
    if (pAnnot == NULL) {
      continue;
    }
    CPDF_FormControl* pControl;
    if (!m_ControlMap.Lookup(pAnnot, (void*&)pControl)) {
      continue;
    }
    CFX_FloatRect rect = pControl->GetRect();
    if (rect.Contains(pdf_x, pdf_y)) {
      return pControl;
    }
  }
  return NULL;
}
CPDF_FormControl* CPDF_InterForm::GetControlByDict(
    CPDF_Dictionary* pWidgetDict) const {
  CPDF_FormControl* pControl = NULL;
  m_ControlMap.Lookup(pWidgetDict, (void*&)pControl);
  return pControl;
}
FX_DWORD CPDF_InterForm::CountInternalFields(
    const CFX_WideString& csFieldName) const {
  if (!m_pFormDict) {
    return 0;
  }
  CPDF_Array* pArray = m_pFormDict->GetArray("Fields");
  if (!pArray) {
    return 0;
  }
  if (csFieldName.IsEmpty()) {
    return pArray->GetCount();
  }
  int iLength = csFieldName.GetLength();
  int iPos = 0;
  CPDF_Dictionary* pDict = NULL;
  while (pArray != NULL) {
    CFX_WideString csSub;
    if (iPos < iLength && csFieldName[iPos] == L'.') {
      iPos++;
    }
    while (iPos < iLength && csFieldName[iPos] != L'.') {
      csSub += csFieldName[iPos++];
    }
    int iCount = pArray->GetCount();
    FX_BOOL bFind = FALSE;
    for (int i = 0; i < iCount; i++) {
      pDict = pArray->GetDict(i);
      if (pDict == NULL) {
        continue;
      }
      CFX_WideString csT = pDict->GetUnicodeText("T");
      if (csT == csSub) {
        bFind = TRUE;
        break;
      }
    }
    if (!bFind) {
      return 0;
    }
    if (iPos >= iLength) {
      break;
    }
    pArray = pDict->GetArray("Kids");
  }
  if (!pDict) {
    return 0;
  }
  pArray = pDict->GetArray("Kids");
  return pArray ? pArray->GetCount() : 1;
}

CPDF_Dictionary* CPDF_InterForm::GetInternalField(
    FX_DWORD index,
    const CFX_WideString& csFieldName) const {
  if (!m_pFormDict) {
    return nullptr;
  }
  CPDF_Array* pArray = m_pFormDict->GetArray("Fields");
  if (!pArray) {
    return nullptr;
  }
  if (csFieldName.IsEmpty()) {
    return pArray->GetDict(index);
  }
  int iLength = csFieldName.GetLength();
  int iPos = 0;
  CPDF_Dictionary* pDict = NULL;
  while (pArray != NULL) {
    CFX_WideString csSub;
    if (iPos < iLength && csFieldName[iPos] == L'.') {
      iPos++;
    }
    while (iPos < iLength && csFieldName[iPos] != L'.') {
      csSub += csFieldName[iPos++];
    }
    int iCount = pArray->GetCount();
    FX_BOOL bFind = FALSE;
    for (int i = 0; i < iCount; i++) {
      pDict = pArray->GetDict(i);
      if (pDict == NULL) {
        continue;
      }
      CFX_WideString csT = pDict->GetUnicodeText("T");
      if (csT == csSub) {
        bFind = TRUE;
        break;
      }
    }
    if (!bFind) {
      return NULL;
    }
    if (iPos >= iLength) {
      break;
    }
    pArray = pDict->GetArray("Kids");
  }
  if (!pDict) {
    return nullptr;
  }
  pArray = pDict->GetArray("Kids");
  return pArray ? pArray->GetDict(index) : pDict;
}
FX_BOOL CPDF_InterForm::NeedConstructAP() {
  if (m_pFormDict == NULL) {
    return FALSE;
  }
  return m_pFormDict->GetBoolean("NeedAppearances");
}
void CPDF_InterForm::NeedConstructAP(FX_BOOL bNeedAP) {
  if (m_pFormDict == NULL) {
    InitInterFormDict(m_pFormDict, m_pDocument);
  }
  m_pFormDict->SetAtBoolean("NeedAppearances", bNeedAP);
  m_bGenerateAP = bNeedAP;
}
int CPDF_InterForm::CountFieldsInCalculationOrder() {
  if (m_pFormDict == NULL) {
    return 0;
  }
  CPDF_Array* pArray = m_pFormDict->GetArray("CO");
  if (pArray == NULL) {
    return 0;
  }
  return pArray->GetCount();
}
CPDF_FormField* CPDF_InterForm::GetFieldInCalculationOrder(int index) {
  if (m_pFormDict == NULL || index < 0) {
    return NULL;
  }
  CPDF_Array* pArray = m_pFormDict->GetArray("CO");
  if (pArray == NULL) {
    return NULL;
  }
  CPDF_Object* pElement = pArray->GetElementValue(index);
  if (pElement != NULL && pElement->GetType() == PDFOBJ_DICTIONARY) {
    return GetFieldByDict((CPDF_Dictionary*)pElement);
  }
  return NULL;
}
int CPDF_InterForm::FindFieldInCalculationOrder(const CPDF_FormField* pField) {
  if (m_pFormDict == NULL || pField == NULL) {
    return -1;
  }
  CPDF_Array* pArray = m_pFormDict->GetArray("CO");
  if (pArray == NULL) {
    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() {
  CFX_ByteString csDA;
  if (m_pFormDict == NULL) {
    return csDA;
  }
  csDA = m_pFormDict->GetString("DA");
  return csDA;
}
CPDF_Font* CPDF_InterForm::GetDefaultFormFont() {
  return GetDefaultInterFormFont(m_pFormDict, m_pDocument);
}
int CPDF_InterForm::GetFormAlignment() {
  if (m_pFormDict == NULL) {
    return 0;
  }
  return m_pFormDict->GetInteger("Q", 0);
}
FX_BOOL CPDF_InterForm::ResetForm(const CFX_PtrArray& fields,
                                  FX_BOOL bIncludeOrExclude,
                                  FX_BOOL bNotify) {
  if (bNotify && m_pFormNotify != NULL) {
    int iRet = m_pFormNotify->BeforeFormReset(this);
    if (iRet < 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 == NULL) {
      continue;
    }
    FX_BOOL bFind = FALSE;
    int iCount = fields.GetSize();
    for (int i = 0; i < iCount; i++) {
      if (pField == (CPDF_FormField*)fields[i]) {
        bFind = TRUE;
        break;
      }
    }
    if ((bIncludeOrExclude && bFind) || (!bIncludeOrExclude && !bFind)) {
      pField->ResetField(bNotify);
    }
  }
  if (bNotify && m_pFormNotify != NULL) {
    m_pFormNotify->AfterFormReset(this);
  }
  return TRUE;
}
FX_BOOL CPDF_InterForm::ResetForm(FX_BOOL bNotify) {
  if (bNotify && m_pFormNotify != NULL) {
    int iRet = m_pFormNotify->BeforeFormReset(this);
    if (iRet < 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 == NULL) {
      continue;
    }
    pField->ResetField(bNotify);
  }
  if (bNotify && m_pFormNotify != NULL) {
    m_pFormNotify->AfterFormReset(this);
  }
  return TRUE;
}
void CPDF_InterForm::ReloadForm() {
  FX_POSITION pos = m_ControlMap.GetStartPosition();
  while (pos) {
    CPDF_Dictionary* pWidgetDict;
    CPDF_FormControl* pControl;
    m_ControlMap.GetNextAssoc(pos, (void*&)pWidgetDict, (void*&)pControl);
    delete pControl;
  }
  m_ControlMap.RemoveAll();
  int nCount = m_pFieldTree->m_Root.CountFields();
  for (int k = 0; k < nCount; k++) {
    CPDF_FormField* pField = m_pFieldTree->m_Root.GetField(k);
    delete pField;
  }
  m_pFieldTree->RemoveAll();
  if (m_pFormDict == NULL) {
    return;
  }
  CPDF_Array* pFields = m_pFormDict->GetArray("Fields");
  if (pFields == NULL) {
    return;
  }
  int iCount = pFields->GetCount();
  for (int i = 0; i < iCount; i++) {
    LoadField(pFields->GetDict(i));
  }
}
void CPDF_InterForm::LoadField(CPDF_Dictionary* pFieldDict, int nLevel) {
  if (nLevel > nMaxRecursion) {
    return;
  }
  if (pFieldDict == NULL) {
    return;
  }
  FX_DWORD dwParentObjNum = pFieldDict->GetObjNum();
  CPDF_Array* pKids = pFieldDict->GetArray("Kids");
  if (!pKids) {
    AddTerminalField(pFieldDict);
    return;
  }
  CPDF_Dictionary* pFirstKid = pKids->GetDict(0);
  if (pFirstKid == NULL) {
    return;
  }
  if (pFirstKid->KeyExist("T") || pFirstKid->KeyExist("Kids")) {
    for (FX_DWORD i = 0; i < pKids->GetCount(); i++) {
      CPDF_Dictionary* pChildDict = pKids->GetDict(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->GetArray(FX_BSTRC("XFA")) != NULL;
}
void CPDF_InterForm::FixPageFields(const CPDF_Page* pPage) {
  ASSERT(pPage != NULL);
  CPDF_Dictionary* pPageDict = pPage->m_pFormDict;
  if (pPageDict == NULL) {
    return;
  }
  CPDF_Array* pAnnots = pPageDict->GetArray(FX_BSTRC("Annots"));
  if (pAnnots == NULL) {
    return;
  }
  int iAnnotCount = pAnnots->GetCount();
  for (int i = 0; i < iAnnotCount; i++) {
    CPDF_Dictionary* pAnnot = pAnnots->GetDict(i);
    if (pAnnot != NULL && pAnnot->GetString(FX_BSTRC("Subtype")) == "Widget") {
      LoadField(pAnnot);
    }
  }
}
CPDF_FormField* CPDF_InterForm::AddTerminalField(
    const CPDF_Dictionary* pFieldDict) {
  if (!pFieldDict->KeyExist(FX_BSTRC("T"))) {
    return NULL;
  }
  CPDF_Dictionary* pDict = (CPDF_Dictionary*)pFieldDict;
  CFX_WideString csWName = GetFullName(pDict);
  if (csWName.IsEmpty()) {
    return NULL;
  }
  CPDF_FormField* pField = NULL;
  pField = m_pFieldTree->GetField(csWName);
  if (pField == NULL) {
    CPDF_Dictionary* pParent = (CPDF_Dictionary*)pFieldDict;
    if (!pFieldDict->KeyExist(FX_BSTRC("T")) &&
        pFieldDict->GetString(FX_BSTRC("Subtype")) == FX_BSTRC("Widget")) {
      pParent = pFieldDict->GetDict(FX_BSTRC("Parent"));
      if (!pParent) {
        pParent = (CPDF_Dictionary*)pFieldDict;
      }
    }
    if (pParent && pParent != pFieldDict &&
        !pParent->KeyExist(FX_BSTRC("FT"))) {
      if (pFieldDict->KeyExist(FX_BSTRC("FT"))) {
        CPDF_Object* pFTValue = pFieldDict->GetElementValue(FX_BSTRC("FT"));
        if (pFTValue) {
          pParent->SetAt(FX_BSTRC("FT"), pFTValue->Clone());
        }
      }
      if (pFieldDict->KeyExist(FX_BSTRC("Ff"))) {
        CPDF_Object* pFfValue = pFieldDict->GetElementValue(FX_BSTRC("Ff"));
        if (pFfValue) {
          pParent->SetAt(FX_BSTRC("Ff"), pFfValue->Clone());
        }
      }
    }
    pField = new CPDF_FormField(this, pParent);
    CPDF_Object* pTObj = pDict->GetElement("T");
    if (pTObj && pTObj->GetType() == PDFOBJ_REFERENCE) {
      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->GetArray("Kids");
  if (pKids == NULL) {
    if (pFieldDict->GetString("Subtype") == "Widget") {
      AddControl(pField, pFieldDict);
    }
  } else {
    for (FX_DWORD i = 0; i < pKids->GetCount(); i++) {
      CPDF_Dictionary* pKid = pKids->GetDict(i);
      if (pKid == NULL) {
        continue;
      }
      if (pKid->GetString("Subtype") != "Widget") {
        continue;
      }
      AddControl(pField, pKid);
    }
  }
  return pField;
}
CPDF_FormControl* CPDF_InterForm::AddControl(
    const CPDF_FormField* pField,
    const CPDF_Dictionary* pWidgetDict) {
  void* rValue = NULL;
  if (m_ControlMap.Lookup((CPDF_Dictionary*)pWidgetDict, rValue)) {
    return (CPDF_FormControl*)rValue;
  }
  CPDF_FormControl* pControl = new CPDF_FormControl(
      (CPDF_FormField*)pField, (CPDF_Dictionary*)pWidgetDict);
  m_ControlMap.SetAt((CPDF_Dictionary*)pWidgetDict, pControl);
  ((CPDF_FormField*)pField)->m_ControlList.Add(pControl);
  return pControl;
}
CPDF_FormField* CPDF_InterForm::CheckRequiredFields(
    const CFX_PtrArray* fields,
    FX_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 == NULL) {
      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();
    if (dwFlags & 0x04) {
      continue;
    }
    FX_BOOL bFind = TRUE;
    if (fields != NULL) {
      bFind = fields->Find(pField, 0) >= 0;
    }
    if ((bIncludeOrExclude && bFind) || (!bIncludeOrExclude && !bFind)) {
      CPDF_Dictionary* pFieldDict = pField->m_pDict;
      if ((dwFlags & 0x02) != 0 && pFieldDict->GetString("V").IsEmpty()) {
        return pField;
      }
    }
  }
  return NULL;
}
CFDF_Document* CPDF_InterForm::ExportToFDF(const CFX_WideStringC& pdf_path,
                                           FX_BOOL bSimpleFileSpec) const {
  CFX_PtrArray fields;
  int nCount = m_pFieldTree->m_Root.CountFields();
  for (int i = 0; i < nCount; i++) {
    CPDF_FormField* pField = m_pFieldTree->m_Root.GetField(i);
    fields.Add(pField);
  }
  return ExportToFDF(pdf_path, fields, TRUE, bSimpleFileSpec);
}
CFX_WideString FILESPEC_EncodeFileName(const CFX_WideStringC& filepath);
CFDF_Document* CPDF_InterForm::ExportToFDF(const CFX_WideStringC& pdf_path,
                                           CFX_PtrArray& fields,
                                           FX_BOOL bIncludeOrExclude,
                                           FX_BOOL bSimpleFileSpec) const {
  CFDF_Document* pDoc = CFDF_Document::CreateNewDoc();
  if (pDoc == NULL) {
    return NULL;
  }
  CPDF_Dictionary* pMainDict = pDoc->GetRoot()->GetDict("FDF");
  if (!pdf_path.IsEmpty()) {
    if (bSimpleFileSpec) {
      CFX_WideString wsFilePath = FILESPEC_EncodeFileName(pdf_path);
      pMainDict->SetAtString(FX_BSTRC("F"),
                             CFX_ByteString::FromUnicode(wsFilePath));
      pMainDict->SetAtString(FX_BSTRC("UF"), PDF_EncodeText(wsFilePath));
    } else {
      CPDF_FileSpec filespec;
      filespec.SetFileName(pdf_path);
      pMainDict->SetAt("F", (CPDF_Object*)filespec);
    }
  }
  CPDF_Array* pFields = CPDF_Array::Create();
  if (pFields == NULL) {
    return NULL;
  }
  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 == NULL || pField->GetType() == CPDF_FormField::PushButton) {
      continue;
    }
    FX_DWORD dwFlags = pField->GetFieldFlags();
    if (dwFlags & 0x04) {
      continue;
    }
    FX_BOOL bFind = fields.Find(pField, 0) >= 0;
    if ((bIncludeOrExclude && bFind) || (!bIncludeOrExclude && !bFind)) {
      if ((dwFlags & 0x02) != 0 && pField->m_pDict->GetString("V").IsEmpty()) {
        continue;
      }
      CFX_WideString fullname = GetFullName(pField->GetFieldDict());
      CPDF_Dictionary* pFieldDict = CPDF_Dictionary::Create();
      if (pFieldDict == NULL) {
        return NULL;
      }
      CPDF_String* pString = CPDF_String::Create(fullname);
      if (pString == NULL) {
        pFieldDict->Release();
        return NULL;
      }
      pFieldDict->SetAt("T", pString);
      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 == NULL) {
          pFieldDict->SetAtName("V", csBExport);
        } else {
          pFieldDict->SetAtString("V", csBExport);
        }
      } else {
        CPDF_Object* pV = FPDF_GetFieldAttr(pField->m_pDict, "V");
        if (pV != NULL) {
          pFieldDict->SetAt("V", pV->Clone(TRUE));
        }
      }
      pFields->Add(pFieldDict);
    }
  }
  return pDoc;
}
const struct _SupportFieldEncoding {
  const FX_CHAR* m_name;
  int32_t m_codePage;
} g_fieldEncoding[] = {
    {"BigFive", 950},
    {"GBK", 936},
    {"Shift-JIS", 932},
    {"UHC", 949},
};
static void FPDFDOC_FDF_GetFieldValue(CPDF_Dictionary* pFieldDict,
                                      CFX_WideString& csValue,
                                      CFX_ByteString& bsEncoding) {
  ASSERT(pFieldDict != NULL);
  CFX_ByteString csBValue = pFieldDict->GetString("V");
  int32_t iCount = sizeof(g_fieldEncoding) / sizeof(g_fieldEncoding[0]);
  int32_t i = 0;
  for (; i < iCount; ++i)
    if (bsEncoding == g_fieldEncoding[i].m_name) {
      break;
    }
  if (i < iCount) {
    CFX_CharMap* pCharMap =
        CFX_CharMap::GetDefaultMapper(g_fieldEncoding[i].m_codePage);
    FXSYS_assert(pCharMap != NULL);
    csValue.ConvertFrom(csBValue, pCharMap);
    return;
  }
  CFX_ByteString csTemp = csBValue.Left(2);
  if (csTemp == "\xFF\xFE" || csTemp == "\xFE\xFF") {
    csValue = PDF_DecodeText(csBValue);
  } else {
    csValue = CFX_WideString::FromLocal(csBValue);
  }
}
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->GetUnicodeText("T");
  CPDF_Array* pKids = pFieldDict->GetArray("Kids");
  if (pKids) {
    for (FX_DWORD i = 0; i < pKids->GetCount(); i++) {
      CPDF_Dictionary* pKid = pKids->GetDict(i);
      if (pKid == NULL) {
        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 == NULL) {
    return;
  }
  CFX_WideString csWValue;
  FPDFDOC_FDF_GetFieldValue(pFieldDict, csWValue, m_bsEncoding);
  int iType = pField->GetFieldType();
  if (bNotify && m_pFormNotify != NULL) {
    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;
    }
  }
  CFX_ByteArray statusArray;
  if (iType == FIELDTYPE_CHECKBOX || iType == FIELDTYPE_RADIOBUTTON) {
    SaveCheckedFieldStatus(pField, statusArray);
  }
  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 != NULL) {
    if (iType == FIELDTYPE_CHECKBOX || iType == FIELDTYPE_RADIOBUTTON) {
      m_pFormNotify->AfterCheckedStatusChange(pField, statusArray);
    } 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 == NULL) {
    return FALSE;
  }
  CPDF_Dictionary* pMainDict = pFDF->GetRoot()->GetDict("FDF");
  if (pMainDict == NULL) {
    return FALSE;
  }
  CPDF_Array* pFields = pMainDict->GetArray("Fields");
  if (pFields == NULL) {
    return FALSE;
  }
  m_bsEncoding = pMainDict->GetString(FX_BSTRC("Encoding"));
  if (bNotify && m_pFormNotify != NULL) {
    int iRet = m_pFormNotify->BeforeFormImportData(this);
    if (iRet < 0) {
      return FALSE;
    }
  }
  for (FX_DWORD i = 0; i < pFields->GetCount(); i++) {
    CPDF_Dictionary* pField = pFields->GetDict(i);
    if (pField == NULL) {
      continue;
    }
    FDF_ImportField(pField, L"", bNotify);
  }
  if (bNotify && m_pFormNotify != NULL) {
    m_pFormNotify->AfterFormImportData(this);
  }
  return TRUE;
}
void CPDF_InterForm::SetFormNotify(const CPDF_FormNotify* pNotify) {
  m_pFormNotify = (CPDF_FormNotify*)pNotify;
}
int CPDF_InterForm::GetPageWithWidget(int iCurPage, FX_BOOL bNext) {
  if (iCurPage < 0) {
    return -1;
  }
  int iPageCount = m_pDocument->GetPageCount();
  if (iCurPage >= iPageCount) {
    return -1;
  }
  int iNewPage = iCurPage;
  do {
    iNewPage += bNext ? 1 : -1;
    if (iNewPage >= iPageCount) {
      iNewPage = 0;
    }
    if (iNewPage < 0) {
      iNewPage = iPageCount - 1;
    }
    if (iNewPage == iCurPage) {
      break;
    }
    CPDF_Dictionary* pPageDict = m_pDocument->GetPage(iNewPage);
    if (pPageDict == NULL) {
      continue;
    }
    CPDF_Array* pAnnots = pPageDict->GetArray("Annots");
    if (pAnnots == NULL) {
      continue;
    }
    FX_DWORD dwCount = pAnnots->GetCount();
    for (FX_DWORD i = 0; i < dwCount; i++) {
      CPDF_Object* pAnnotDict = pAnnots->GetElementValue(i);
      if (pAnnotDict == NULL) {
        continue;
      }
      CPDF_FormControl* pControl = NULL;
      if (m_ControlMap.Lookup(pAnnotDict, (void*&)pControl)) {
        return iNewPage;
      }
    }
  } while (TRUE);
  return -1;
}
