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

#ifndef CORE_INCLUDE_FPDFDOC_FPDF_DOC_H_
#define CORE_INCLUDE_FPDFDOC_FPDF_DOC_H_

#include <map>
#include <vector>

#include "../../../third_party/base/nonstd_unique_ptr.h"
#include "../fpdfapi/fpdf_parser.h"
#include "../fpdfapi/fpdf_render.h"

class CFieldTree;
class CPDF_AAction;
class CPDF_Action;
class CPDF_ActionFields;
class CPDF_Annot;
class CPDF_AnnotList;
class CPDF_ApSettings;
class CPDF_Bookmark;
class CPDF_BookmarkTree;
class CPDF_DefaultAppearance;
class CPDF_Dest;
class CPDF_DocJSActions;
class CPDF_FileSpec;
class CPDF_FormControl;
class CPDF_FormField;
class CPDF_FormNotify;
class CPDF_IconFit;
class CPDF_InterForm;
class CPDF_Link;
class CPDF_LWinParam;
class CPDF_Metadata;
class CPDF_NumberTree;
class CPDF_OCContext;
class CPDF_Page;
class CPDF_RenderOptions;
class CPDF_TextObject;
class CPDF_ViewerPreferences;
class CXML_Element;

class CPDF_NameTree {
 public:
  CPDF_NameTree(CPDF_Dictionary* pRoot) { m_pRoot = pRoot; }

  CPDF_NameTree(CPDF_Document* pDoc, const CFX_ByteStringC& category);

  CPDF_Object* LookupValue(int nIndex, CFX_ByteString& csName) const;

  CPDF_Object* LookupValue(const CFX_ByteString& csName) const;

  CPDF_Array* LookupNamedDest(CPDF_Document* pDoc,
                              const CFX_ByteStringC& sName);

  int GetIndex(const CFX_ByteString& csName) const;

  int GetCount() const;

  CPDF_Dictionary* GetRoot() const { return m_pRoot; }

 protected:
  CPDF_Dictionary* m_pRoot;
};
class CPDF_BookmarkTree {
 public:
  CPDF_BookmarkTree(CPDF_Document* pDoc) : m_pDocument(pDoc) {}

  CPDF_Bookmark GetFirstChild(const CPDF_Bookmark& parent) const;

  CPDF_Bookmark GetNextSibling(const CPDF_Bookmark& bookmark) const;

  CPDF_Document* GetDocument() const { return m_pDocument; }

 protected:
  CPDF_Document* m_pDocument;
};
#define PDFBOOKMARK_ITALIC 1
#define PDFBOOKMARK_BOLD 2
class CPDF_Bookmark {
 public:
  CPDF_Bookmark() : m_pDict(NULL) {}

  explicit CPDF_Bookmark(CPDF_Dictionary* pDict) : m_pDict(pDict) {}

  CPDF_Dictionary* GetDict() const { return m_pDict; }

  operator bool() const { return m_pDict != NULL; }

  FX_DWORD GetColorRef() const;

  FX_DWORD GetFontStyle() const;

  CFX_WideString GetTitle() const;

  CPDF_Dest GetDest(CPDF_Document* pDocument) const;

  CPDF_Action GetAction() const;

  CPDF_Dictionary* m_pDict;
};
#define PDFZOOM_XYZ 1
#define PDFZOOM_FITPAGE 2
#define PDFZOOM_FITHORZ 3
#define PDFZOOM_FITVERT 4
#define PDFZOOM_FITRECT 5
#define PDFZOOM_FITBBOX 6
#define PDFZOOM_FITBHORZ 7
#define PDFZOOM_FITBVERT 8
class CPDF_Dest {
 public:
  CPDF_Dest() : m_pObj(nullptr) {}
  explicit CPDF_Dest(CPDF_Object* pObj) : m_pObj(pObj) {}

  operator bool() const { return m_pObj != NULL; }
  CPDF_Object* GetObject() const { return m_pObj; }

  CFX_ByteString GetRemoteName();
  int GetPageIndex(CPDF_Document* pDoc);
  FX_DWORD GetPageObjNum();
  int GetZoomMode();
  FX_FLOAT GetParam(int index);

 protected:
  CPDF_Object* m_pObj;
};
class CPDF_OCContext : public IPDF_OCContext {
 public:
  enum UsageType { View = 0, Design, Print, Export };

  CPDF_OCContext(CPDF_Document* pDoc, UsageType eUsageType = View);
  ~CPDF_OCContext() override;

  CPDF_Document* GetDocument() const { return m_pDocument; }

  UsageType GetUsageType() const { return m_eUsageType; }

  FX_BOOL CheckOCGVisible(const CPDF_Dictionary* pOCGDict) override;

  void ResetOCContext();

 protected:
  FX_BOOL LoadOCGStateFromConfig(const CFX_ByteStringC& csConfig,
                                 const CPDF_Dictionary* pOCGDict,
                                 FX_BOOL& bValidConfig) const;

  FX_BOOL LoadOCGState(const CPDF_Dictionary* pOCGDict) const;

  FX_BOOL GetOCGVisible(const CPDF_Dictionary* pOCGDict);

  FX_BOOL GetOCGVE(CPDF_Array* pExpression,
                   FX_BOOL bFromConfig,
                   int nLevel = 0);

  FX_BOOL LoadOCMDState(const CPDF_Dictionary* pOCMDDict, FX_BOOL bFromConfig);

  CPDF_Document* m_pDocument;

  UsageType m_eUsageType;

  std::map<const CPDF_Dictionary*, FX_BOOL> m_OCGStates;
};
class CPDF_LWinParam {
 public:
  CPDF_LWinParam(CPDF_Dictionary* pDict) { m_pDict = pDict; }

  operator CPDF_Dictionary*() const { return m_pDict; }

  inline CFX_ByteString GetFileName() { return m_pDict->GetString("F"); }

  inline CFX_ByteString GetDefaultDirectory() {
    return m_pDict->GetString("D");
  }

  inline CFX_ByteString GetOperation() { return m_pDict->GetString("O"); }

  inline CFX_ByteString GetParameter() { return m_pDict->GetString("P"); }

  CPDF_Dictionary* m_pDict;
};
class CPDF_ActionFields {
 public:
  CPDF_ActionFields(const CPDF_Action* pAction) {
    m_pAction = (CPDF_Action*)pAction;
  }

  operator CPDF_Action*() const { return m_pAction; }

  FX_DWORD GetFieldsCount() const;

  void GetAllFields(CFX_PtrArray& fieldObjects) const;

  CPDF_Object* GetField(FX_DWORD iIndex) const;

  CPDF_Action* m_pAction;
};

#define PDFNAMED_NEXTPAGE 1
#define PDFNAMED_PREVPAGE 2
#define PDFNAMED_FIRSTPAGE 3
#define PDFNAMED_LASTPAGE 4
#define PDFJS_MAXLENGTH 64
class CPDF_Action {
 public:
  enum ActionType {
    Unknown = 0,
    GoTo,
    GoToR,
    GoToE,
    Launch,
    Thread,
    URI,
    Sound,
    Movie,
    Hide,
    Named,
    SubmitForm,
    ResetForm,
    ImportData,
    JavaScript,
    SetOCGState,
    Rendition,
    Trans,
    GoTo3DView
  };

  CPDF_Action() : m_pDict(nullptr) {}
  explicit CPDF_Action(CPDF_Dictionary* pDict) : m_pDict(pDict) {}

  operator bool() const { return m_pDict != NULL; }

  CPDF_Dictionary* GetDict() const { return m_pDict; }

  CFX_ByteString GetTypeName() const { return m_pDict->GetString("S"); }

  ActionType GetType() const;

  CPDF_Dest GetDest(CPDF_Document* pDoc) const;

  CFX_WideString GetFilePath() const;

  FX_BOOL GetNewWindow() const { return m_pDict->GetBoolean("NewWindow"); }

  CPDF_LWinParam GetWinParam() const;

  CFX_ByteString GetURI(CPDF_Document* pDoc) const;

  FX_BOOL GetMouseMap() const { return m_pDict->GetBoolean("IsMap"); }

  CPDF_ActionFields GetWidgets() const { return this; }

  FX_BOOL GetHideStatus() const { return m_pDict->GetBoolean("H", TRUE); }

  CFX_ByteString GetNamedAction() const { return m_pDict->GetString("N"); }

  FX_DWORD GetFlags() const { return m_pDict->GetInteger("Flags"); }

  CFX_WideString GetJavaScript() const;

  CPDF_Dictionary* GetAnnot() const;

  int32_t GetOperationType() const;

  CPDF_Stream* GetSoundStream() const { return m_pDict->GetStream("Sound"); }

  FX_FLOAT GetVolume() const { return m_pDict->GetNumber("Volume"); }

  FX_BOOL IsSynchronous() const { return m_pDict->GetBoolean("Synchronous"); }

  FX_BOOL IsRepeat() const { return m_pDict->GetBoolean("Repeat"); }

  FX_BOOL IsMixPlay() const { return m_pDict->GetBoolean("Mix"); }

  FX_DWORD GetSubActionsCount() const;

  CPDF_Action GetSubAction(FX_DWORD iIndex) const;

 protected:
  CPDF_Dictionary* m_pDict;
};
class CPDF_AAction {
 public:
  CPDF_AAction(CPDF_Dictionary* pDict = NULL) { m_pDict = pDict; }

  operator CPDF_Dictionary*() const { return m_pDict; }

  enum AActionType {
    CursorEnter = 0,
    CursorExit,
    ButtonDown,
    ButtonUp,
    GetFocus,
    LoseFocus,
    PageOpen,
    PageClose,
    PageVisible,
    PageInvisible,
    OpenPage,
    ClosePage,
    KeyStroke,
    Format,
    Validate,
    Calculate,
    CloseDocument,
    SaveDocument,
    DocumentSaved,
    PrintDocument,
    DocumentPrinted
  };

  FX_BOOL ActionExist(AActionType eType) const;

  CPDF_Action GetAction(AActionType eType) const;

  FX_POSITION GetStartPos() const;

  CPDF_Action GetNextAction(FX_POSITION& pos, AActionType& eType) const;

  CPDF_Dictionary* m_pDict;
};
class CPDF_DocJSActions {
 public:
  CPDF_DocJSActions(CPDF_Document* pDoc);

  int CountJSActions() const;

  CPDF_Action GetJSAction(int index, CFX_ByteString& csName) const;

  CPDF_Action GetJSAction(const CFX_ByteString& csName) const;

  int FindJSAction(const CFX_ByteString& csName) const;

  CPDF_Document* GetDocument() const { return m_pDocument; }

 protected:
  CPDF_Document* m_pDocument;
};
class CPDF_FileSpec {
 public:
  CPDF_FileSpec();

  CPDF_FileSpec(CPDF_Object* pObj) { m_pObj = pObj; }

  operator CPDF_Object*() const { return m_pObj; }

  FX_BOOL IsURL() const;

  FX_BOOL GetFileName(CFX_WideString& wsFileName) const;

  CPDF_Stream* GetFileStream() const;

  void SetFileName(const CFX_WideStringC& wsFileName, FX_BOOL bURL = FALSE);

 protected:
  CPDF_Object* m_pObj;
};

class CPDF_LinkList {
 public:
  CPDF_LinkList();
  ~CPDF_LinkList();

  CPDF_Link GetLinkAtPoint(CPDF_Page* pPage,
                           FX_FLOAT pdf_x,
                           FX_FLOAT pdf_y,
                           int* z_order);

 private:
  const std::vector<CPDF_Dictionary*>* GetPageLinks(CPDF_Page* pPage);

  void LoadPageLinks(CPDF_Page* pPage, std::vector<CPDF_Dictionary*>* pList);

  std::map<FX_DWORD, std::vector<CPDF_Dictionary*>> m_PageMap;
};

class CPDF_Link {
 public:
  CPDF_Link() : m_pDict(nullptr) {}
  explicit CPDF_Link(CPDF_Dictionary* pDict) : m_pDict(pDict) {}

  CPDF_Dictionary* GetDict() const { return m_pDict; }

  CFX_FloatRect GetRect();
  CPDF_Dest GetDest(CPDF_Document* pDoc);
  CPDF_Action GetAction();

 protected:
  CPDF_Dictionary* m_pDict;
};

#define ANNOTFLAG_INVISIBLE 0x0001
#define ANNOTFLAG_HIDDEN 0x0002
#define ANNOTFLAG_PRINT 0x0004
#define ANNOTFLAG_NOZOOM 0x0008
#define ANNOTFLAG_NOROTATE 0x0010
#define ANNOTFLAG_NOVIEW 0x0020
#define ANNOTFLAG_READONLY 0x0040
#define ANNOTFLAG_LOCKED 0x0080
#define ANNOTFLAG_TOGGLENOVIEW 0x0100

class CPDF_Annot : public CFX_PrivateData {
 public:
  enum AppearanceMode { Normal, Rollover, Down };

  CPDF_Annot(CPDF_Dictionary* pDict, CPDF_AnnotList* pList);
  ~CPDF_Annot();

  CFX_ByteString GetSubType() const;

  FX_DWORD GetFlags() const;

  void GetRect(CFX_FloatRect& rect) const;

  CPDF_Dictionary* GetAnnotDict();

  FX_BOOL DrawAppearance(const CPDF_Page* pPage,
                         CFX_RenderDevice* pDevice,
                         const CFX_AffineMatrix* pUser2Device,
                         AppearanceMode mode,
                         const CPDF_RenderOptions* pOptions);

  FX_BOOL DrawInContext(const CPDF_Page* pPage,
                        const CPDF_RenderContext* pContext,
                        const CFX_AffineMatrix* pUser2Device,
                        AppearanceMode mode);

  void ClearCachedAP();

  void DrawBorder(CFX_RenderDevice* pDevice,
                  const CFX_AffineMatrix* pUser2Device,
                  const CPDF_RenderOptions* pOptions);

  CPDF_Form* GetAPForm(const CPDF_Page* pPage, AppearanceMode mode);

 private:
  CPDF_Dictionary* const m_pAnnotDict;

  CPDF_AnnotList* const m_pList;

  const CFX_ByteString m_sSubtype;

  CFX_MapPtrToPtr m_APMap;
};

class CPDF_AnnotList {
 public:
  CPDF_AnnotList(CPDF_Page* pPage);

  ~CPDF_AnnotList();

  void GetAnnotMatrix(const CPDF_Dictionary* pAnnotDict,
                      const CFX_Matrix* pUser2Device,
                      CFX_Matrix& matrix) const;

  void GetAnnotRect(const CPDF_Dictionary* pAnnotDict,
                    const CFX_Matrix* pUser2Device,
                    CPDF_Rect& rtAnnot) const;

  void DisplayAnnots(const CPDF_Page* pPage,
                     CFX_RenderDevice* pDevice,
                     CFX_AffineMatrix* pMatrix,
                     FX_BOOL bShowWidget,
                     CPDF_RenderOptions* pOptions);

  void DisplayAnnots(const CPDF_Page* pPage,
                     CPDF_RenderContext* pContext,
                     FX_BOOL bPrinting,
                     CFX_AffineMatrix* pMatrix,
                     FX_BOOL bShowWidget,
                     CPDF_RenderOptions* pOptions) {
    DisplayAnnots(pPage, NULL, pContext, bPrinting, pMatrix,
                  bShowWidget ? 3 : 1, pOptions, NULL);
  }

  void DisplayAnnots(const CPDF_Page* pPage,
                     CPDF_RenderContext* pContext,
                     FX_BOOL bPrinting,
                     CFX_AffineMatrix* pMatrix,
                     FX_BOOL bShowWidget,
                     CPDF_RenderOptions* pOptions,
                     FX_RECT* pClipRect) {
    DisplayAnnots(pPage, NULL, pContext, bPrinting, pMatrix,
                  bShowWidget ? 3 : 1, pOptions, pClipRect);
  }

  void DisplayAnnots(const CPDF_Page* pPage,
                     CFX_RenderDevice* pDevice,
                     CPDF_RenderContext* pContext,
                     FX_BOOL bPrinting,
                     CFX_AffineMatrix* pMatrix,
                     FX_DWORD dwAnnotFlags,
                     CPDF_RenderOptions* pOptions,
                     FX_RECT* pClipRect);

  CPDF_Annot* GetAt(int index) { return (CPDF_Annot*)m_AnnotList.GetAt(index); }

  int Count() { return m_AnnotList.GetSize(); }

  int GetIndex(CPDF_Annot* pAnnot);

  CPDF_Document* GetDocument() const { return m_pDocument; }

 protected:
  CFX_PtrArray m_AnnotList;

  CPDF_Dictionary* m_pPageDict;

  CPDF_Document* m_pDocument;

  CFX_PtrArray m_Borders;

  void DisplayPass(const CPDF_Page* pPage,
                   CFX_RenderDevice* pDevice,
                   CPDF_RenderContext* pContext,
                   FX_BOOL bPrinting,
                   CFX_AffineMatrix* pMatrix,
                   FX_BOOL bWidget,
                   CPDF_RenderOptions* pOptions,
                   FX_RECT* clip_rect);
  friend class CPDF_Annot;
};
#define COLORTYPE_TRANSPARENT 0
#define COLORTYPE_GRAY 1
#define COLORTYPE_RGB 2
#define COLORTYPE_CMYK 3
class CPDF_DefaultAppearance {
 public:
  CPDF_DefaultAppearance(const CFX_ByteString& csDA = "") { m_csDA = csDA; }

  CPDF_DefaultAppearance(const CPDF_DefaultAppearance& cDA) {
    m_csDA = (CFX_ByteString)(CPDF_DefaultAppearance&)cDA;
  }

  operator CFX_ByteString() const { return m_csDA; }

  const CPDF_DefaultAppearance& operator=(const CFX_ByteString& csDA) {
    m_csDA = csDA;
    return *this;
  }

  const CPDF_DefaultAppearance& operator=(const CPDF_DefaultAppearance& cDA) {
    m_csDA = (CFX_ByteString)(CPDF_DefaultAppearance&)cDA;
    return *this;
  }

  FX_BOOL HasFont();

  CFX_ByteString GetFontString();

  void GetFont(CFX_ByteString& csFontNameTag, FX_FLOAT& fFontSize);

  FX_BOOL HasColor(FX_BOOL bStrokingOperation = FALSE);

  CFX_ByteString GetColorString(FX_BOOL bStrokingOperation = FALSE);

  void GetColor(int& iColorType,
                FX_FLOAT fc[4],
                FX_BOOL bStrokingOperation = FALSE);

  void GetColor(FX_ARGB& color,
                int& iColorType,
                FX_BOOL bStrokingOperation = FALSE);

  FX_BOOL HasTextMatrix();

  CFX_ByteString GetTextMatrixString();

  CFX_AffineMatrix GetTextMatrix();

 protected:
  CFX_ByteString m_csDA;
};
#define FIELDTYPE_UNKNOWN 0
#define FIELDTYPE_PUSHBUTTON 1
#define FIELDTYPE_CHECKBOX 2
#define FIELDTYPE_RADIOBUTTON 3
#define FIELDTYPE_COMBOBOX 4
#define FIELDTYPE_LISTBOX 5
#define FIELDTYPE_TEXTFIELD 6
#define FIELDTYPE_SIGNATURE 7
class CPDF_InterForm : public CFX_PrivateData {
 public:
  CPDF_InterForm(CPDF_Document* pDocument, FX_BOOL bUpdateAP);
  ~CPDF_InterForm();

  static void EnableUpdateAP(FX_BOOL bUpdateAP);

  static FX_BOOL UpdatingAPEnabled();

  static CFX_ByteString GenerateNewResourceName(const CPDF_Dictionary* pResDict,
                                                const FX_CHAR* csType,
                                                int iMinLen = 2,
                                                const FX_CHAR* csPrefix = "");

  static CPDF_Font* AddSystemDefaultFont(const CPDF_Document* pDocument);

  static CPDF_Font* AddSystemFont(const CPDF_Document* pDocument,
                                  CFX_ByteString csFontName,
                                  uint8_t iCharSet = 1);

  static CPDF_Font* AddSystemFont(const CPDF_Document* pDocument,
                                  CFX_WideString csFontName,
                                  uint8_t iCharSet = 1);

  static CPDF_Font* AddStandardFont(const CPDF_Document* pDocument,
                                    CFX_ByteString csFontName);

  static CFX_ByteString GetNativeFont(uint8_t iCharSet, void* pLogFont = NULL);

  static CFX_ByteString GetNativeFont(void* pLogFont = NULL);

  static uint8_t GetNativeCharSet();

  static CPDF_Font* AddNativeFont(uint8_t iCharSet,
                                  const CPDF_Document* pDocument);

  static CPDF_Font* AddNativeFont(const CPDF_Document* pDocument);

  FX_BOOL ValidateFieldName(CFX_WideString& csNewFieldName, int iType);

  FX_BOOL ValidateFieldName(const CPDF_FormField* pField,
                            CFX_WideString& csNewFieldName);

  FX_BOOL ValidateFieldName(const CPDF_FormControl* pControl,
                            CFX_WideString& csNewFieldName);

  FX_DWORD CountFields(const CFX_WideString& csFieldName = L"");

  CPDF_FormField* GetField(FX_DWORD index,
                           const CFX_WideString& csFieldName = L"");

  void GetAllFieldNames(CFX_WideStringArray& allFieldNames);

  FX_BOOL IsValidFormField(const void* pField);

  CPDF_FormField* GetFieldByDict(CPDF_Dictionary* pFieldDict) const;

  CPDF_FormControl* GetControlAtPoint(CPDF_Page* pPage,
                                      FX_FLOAT pdf_x,
                                      FX_FLOAT pdf_y,
                                      int* z_order) const;

  CPDF_FormControl* GetControlByDict(CPDF_Dictionary* pWidgetDict) const;

  CPDF_Document* GetDocument() const { return m_pDocument; }

  CPDF_Dictionary* GetFormDict() const { return m_pFormDict; }

  FX_BOOL NeedConstructAP();

  void NeedConstructAP(FX_BOOL bNeedAP);

  int CountFieldsInCalculationOrder();

  CPDF_FormField* GetFieldInCalculationOrder(int index);

  int FindFieldInCalculationOrder(const CPDF_FormField* pField);

  FX_DWORD CountFormFonts();

  CPDF_Font* GetFormFont(FX_DWORD index, CFX_ByteString& csNameTag);

  CPDF_Font* GetFormFont(CFX_ByteString csNameTag);

  CPDF_Font* GetFormFont(CFX_ByteString csFontName, CFX_ByteString& csNameTag);

  CPDF_Font* GetNativeFormFont(uint8_t iCharSet, CFX_ByteString& csNameTag);

  CPDF_Font* GetNativeFormFont(CFX_ByteString& csNameTag);

  FX_BOOL FindFormFont(const CPDF_Font* pFont, CFX_ByteString& csNameTag);

  FX_BOOL FindFormFont(CFX_ByteString csFontName,
                       CPDF_Font*& pFont,
                       CFX_ByteString& csNameTag);

  inline FX_BOOL FindFormFont(CFX_WideString csFontName,
                              CPDF_Font*& pFont,
                              CFX_ByteString& csNameTag) {
    return FindFormFont(PDF_EncodeText(csFontName), pFont, csNameTag);
  }

  void AddFormFont(const CPDF_Font* pFont, CFX_ByteString& csNameTag);

  CPDF_Font* AddNativeFormFont(uint8_t iCharSet, CFX_ByteString& csNameTag);

  CPDF_Font* AddNativeFormFont(CFX_ByteString& csNameTag);

  void RemoveFormFont(const CPDF_Font* pFont);

  void RemoveFormFont(CFX_ByteString csNameTag);

  CPDF_DefaultAppearance GetDefaultAppearance();

  CPDF_Font* GetDefaultFormFont();

  int GetFormAlignment();

  CPDF_FormField* CheckRequiredFields(const CFX_PtrArray* fields = NULL,
                                      FX_BOOL bIncludeOrExclude = TRUE) const;

  CFDF_Document* ExportToFDF(const CFX_WideStringC& pdf_path,
                             FX_BOOL bSimpleFileSpec = FALSE) const;

  CFDF_Document* ExportToFDF(const CFX_WideStringC& pdf_path,
                             CFX_PtrArray& fields,
                             FX_BOOL bIncludeOrExclude = TRUE,
                             FX_BOOL bSimpleFileSpec = FALSE) const;

  FX_BOOL ImportFromFDF(const CFDF_Document* pFDFDoc, FX_BOOL bNotify = FALSE);

  FX_BOOL ResetForm(const CFX_PtrArray& fields,
                    FX_BOOL bIncludeOrExclude = TRUE,
                    FX_BOOL bNotify = FALSE);

  FX_BOOL ResetForm(FX_BOOL bNotify = FALSE);

  CPDF_FormNotify* GetFormNotify() const { return m_pFormNotify; }

  void SetFormNotify(const CPDF_FormNotify* pNotify);

  FX_BOOL IsUpdated() { return m_bUpdated; }

  void ClearUpdatedFlag() { m_bUpdated = FALSE; }

  FX_BOOL HasXFAForm() const;

  void FixPageFields(const CPDF_Page* pPage);

 protected:
  static FX_BOOL m_bUpdateAP;

  void LoadField(CPDF_Dictionary* pFieldDict, int nLevel = 0);

  CPDF_Object* GetFieldAttr(CPDF_Dictionary* pFieldDict, const FX_CHAR* name);

  CPDF_FormField* AddTerminalField(const CPDF_Dictionary* pFieldDict);

  CPDF_FormControl* AddControl(const CPDF_FormField* pField,
                               const CPDF_Dictionary* pWidgetDict);

  void FDF_ImportField(CPDF_Dictionary* pField,
                       const CFX_WideString& parent_name,
                       FX_BOOL bNotify = FALSE,
                       int nLevel = 0);

  FX_BOOL ValidateFieldName(CFX_WideString& csNewFieldName,
                            int iType,
                            const CPDF_FormField* pExcludedField,
                            const CPDF_FormControl* pExcludedControl);

  int CompareFieldName(const CFX_WideString& name1,
                       const CFX_WideString& name2);

  int CompareFieldName(const CFX_ByteString& name1,
                       const CFX_ByteString& name2);

  CPDF_Document* m_pDocument;

  FX_BOOL m_bGenerateAP;

  CPDF_Dictionary* m_pFormDict;

  std::map<const CPDF_Dictionary*, CPDF_FormControl*> m_ControlMap;

  CFieldTree* m_pFieldTree;

  CFX_ByteString m_bsEncoding;

  CPDF_FormNotify* m_pFormNotify;

  FX_BOOL m_bUpdated;
  friend class CPDF_FormControl;
  friend class CPDF_FormField;
};
#define FORMFIELD_READONLY 0x01
#define FORMFIELD_REQUIRED 0x02
#define FORMFIELD_NOEXPORT 0x04
#define FORMRADIO_NOTOGGLEOFF 0x100
#define FORMRADIO_UNISON 0x200
#define FORMTEXT_MULTILINE 0x100
#define FORMTEXT_PASSWORD 0x200
#define FORMTEXT_NOSCROLL 0x400
#define FORMTEXT_COMB 0x800
#define FORMCOMBO_EDIT 0x100
#define FORMLIST_MULTISELECT 0x100
class CPDF_FormField {
 public:
  enum Type {
    Unknown,
    PushButton,
    RadioButton,
    CheckBox,
    Text,
    RichText,
    File,
    ListBox,
    ComboBox,
    Sign
  };

  CFX_WideString GetFullName();

  Type GetType() { return m_Type; }

  FX_DWORD GetFlags() { return m_Flags; }

  CPDF_Dictionary* GetFieldDict() const { return m_pDict; }

  void SetFieldDict(CPDF_Dictionary* pDict) { m_pDict = pDict; }

  FX_BOOL ResetField(FX_BOOL bNotify = FALSE);

  int CountControls() { return m_ControlList.GetSize(); }

  CPDF_FormControl* GetControl(int index) {
    return (CPDF_FormControl*)m_ControlList.GetAt(index);
  }

  int GetControlIndex(const CPDF_FormControl* pControl);

  int GetFieldType();

  CPDF_AAction GetAdditionalAction();

  CFX_WideString GetAlternateName();

  CFX_WideString GetMappingName();

  FX_DWORD GetFieldFlags();

  CFX_ByteString GetDefaultStyle();

  CFX_WideString GetRichTextString();

  CFX_WideString GetValue();

  CFX_WideString GetDefaultValue();

  FX_BOOL SetValue(const CFX_WideString& value, FX_BOOL bNotify = FALSE);

  int GetMaxLen();

  int CountSelectedItems();

  int GetSelectedIndex(int index);

  FX_BOOL ClearSelection(FX_BOOL bNotify = FALSE);

  FX_BOOL IsItemSelected(int index);

  FX_BOOL SetItemSelection(int index,
                           FX_BOOL bSelected,
                           FX_BOOL bNotify = FALSE);

  FX_BOOL IsItemDefaultSelected(int index);

  int GetDefaultSelectedItem();

  int CountOptions();

  CFX_WideString GetOptionLabel(int index);

  CFX_WideString GetOptionValue(int index);

  int FindOption(CFX_WideString csOptLabel);

  int FindOptionValue(const CFX_WideString& csOptValue, int iStartIndex = 0);

  FX_BOOL CheckControl(int iControlIndex,
                       FX_BOOL bChecked,
                       FX_BOOL bNotify = FALSE);

  int GetTopVisibleIndex();

  int CountSelectedOptions();

  int GetSelectedOptionIndex(int index);

  FX_BOOL IsOptionSelected(int iOptIndex);

  FX_BOOL SelectOption(int iOptIndex,
                       FX_BOOL bSelected,
                       FX_BOOL bNotify = FALSE);

  FX_BOOL ClearSelectedOptions(FX_BOOL bNotify = FALSE);

  FX_FLOAT GetFontSize() { return m_FontSize; }

  CPDF_Font* GetFont() { return m_pFont; }

 protected:
  CPDF_FormField(CPDF_InterForm* pForm, CPDF_Dictionary* pDict);

  ~CPDF_FormField();

  CPDF_FormField::Type m_Type;

  FX_DWORD m_Flags;

  CPDF_InterForm* m_pForm;

  CPDF_Dictionary* m_pDict;

  CFX_PtrArray m_ControlList;
  friend class CPDF_InterForm;
  friend class CPDF_FormControl;

  CFX_WideString GetValue(FX_BOOL bDefault);

  FX_BOOL SetValue(const CFX_WideString& value,
                   FX_BOOL bDefault,
                   FX_BOOL bNotify);

  void SyncFieldFlags();

  int FindListSel(CPDF_String* str);

  CFX_WideString GetOptionText(int index, int sub_index);

  void LoadDA();

  void UpdateAP(CPDF_FormControl* pControl);

  CFX_WideString GetCheckValue(FX_BOOL bDefault);

  FX_BOOL SetCheckValue(const CFX_WideString& value,
                        FX_BOOL bDefault,
                        FX_BOOL bNotify);

  FX_FLOAT m_FontSize;

  CPDF_Font* m_pFont;
};
CPDF_Object* FPDF_GetFieldAttr(CPDF_Dictionary* pFieldDict,
                               const FX_CHAR* name,
                               int nLevel = 0);
class CPDF_IconFit {
 public:
  CPDF_IconFit(CPDF_Dictionary* pDict = NULL) { m_pDict = pDict; }

  operator CPDF_Dictionary*() const { return m_pDict; }

  enum ScaleMethod { Always = 0, Bigger, Smaller, Never };

  ScaleMethod GetScaleMethod();

  FX_BOOL IsProportionalScale();

  void GetIconPosition(FX_FLOAT& fLeft, FX_FLOAT& fBottom);

  FX_BOOL GetFittingBounds();

  CPDF_Dictionary* m_pDict;
};

#define TEXTPOS_CAPTION 0
#define TEXTPOS_ICON 1
#define TEXTPOS_BELOW 2
#define TEXTPOS_ABOVE 3
#define TEXTPOS_RIGHT 4
#define TEXTPOS_LEFT 5
#define TEXTPOS_OVERLAID 6
class CPDF_FormControl {
 public:
  CPDF_FormField::Type GetType() { return m_pField->GetType(); }

  CPDF_InterForm* GetInterForm() const { return m_pForm; }

  CPDF_FormField* GetField() const { return m_pField; }

  CPDF_Dictionary* GetWidget() const { return m_pWidgetDict; }

  CFX_FloatRect GetRect() const;

  void DrawControl(CFX_RenderDevice* pDevice,
                   CFX_AffineMatrix* pMatrix,
                   CPDF_Page* pPage,
                   CPDF_Annot::AppearanceMode mode,
                   const CPDF_RenderOptions* pOptions = NULL);

  CFX_ByteString GetCheckedAPState();

  CFX_WideString GetExportValue();

  FX_BOOL IsChecked();

  FX_BOOL IsDefaultChecked();

  enum HighlightingMode { None = 0, Invert, Outline, Push, Toggle };

  HighlightingMode GetHighlightingMode();

  FX_BOOL HasMKEntry(CFX_ByteString csEntry);

  int GetRotation();

  inline FX_ARGB GetBorderColor(int& iColorType) {
    return GetColor(iColorType, "BC");
  }

  inline FX_FLOAT GetOriginalBorderColor(int index) {
    return GetOriginalColor(index, "BC");
  }

  inline void GetOriginalBorderColor(int& iColorType, FX_FLOAT fc[4]) {
    GetOriginalColor(iColorType, fc, "BC");
  }

  inline FX_ARGB GetBackgroundColor(int& iColorType) {
    return GetColor(iColorType, "BG");
  }

  inline FX_FLOAT GetOriginalBackgroundColor(int index) {
    return GetOriginalColor(index, "BG");
  }

  inline void GetOriginalBackgroundColor(int& iColorType, FX_FLOAT fc[4]) {
    GetOriginalColor(iColorType, fc, "BG");
  }

  inline CFX_WideString GetNormalCaption() { return GetCaption("CA"); }

  inline CFX_WideString GetRolloverCaption() { return GetCaption("RC"); }

  inline CFX_WideString GetDownCaption() { return GetCaption("AC"); }

  inline CPDF_Stream* GetNormalIcon() { return GetIcon("I"); }

  inline CPDF_Stream* GetRolloverIcon() { return GetIcon("RI"); }

  inline CPDF_Stream* GetDownIcon() { return GetIcon("IX"); }

  CPDF_IconFit GetIconFit();

  int GetTextPosition();

  CPDF_Action GetAction();

  CPDF_AAction GetAdditionalAction();

  CPDF_DefaultAppearance GetDefaultAppearance();

  CPDF_Font* GetDefaultControlFont();

  int GetControlAlignment();

 protected:
  CPDF_FormControl(CPDF_FormField* pField, CPDF_Dictionary* pWidgetDict);

  CFX_ByteString GetOnStateName();

  void SetOnStateName(const CFX_ByteString& csOn);

  void CheckControl(FX_BOOL bChecked);

  FX_ARGB GetColor(int& iColorType, CFX_ByteString csEntry);

  FX_FLOAT GetOriginalColor(int index, CFX_ByteString csEntry);

  void GetOriginalColor(int& iColorType,
                        FX_FLOAT fc[4],
                        CFX_ByteString csEntry);

  CFX_WideString GetCaption(CFX_ByteString csEntry);

  CPDF_Stream* GetIcon(CFX_ByteString csEntry);

  CPDF_ApSettings GetMK(FX_BOOL bCreate);

  CPDF_InterForm* m_pForm;

  CPDF_FormField* m_pField;

  CPDF_Dictionary* m_pWidgetDict;
  friend class CPDF_InterForm;
  friend class CPDF_FormField;
};
class CPDF_FormNotify {
 public:
  virtual ~CPDF_FormNotify() {}

  virtual int BeforeValueChange(const CPDF_FormField* pField,
                                CFX_WideString& csValue) {
    return 0;
  }

  virtual int AfterValueChange(const CPDF_FormField* pField) { return 0; }

  virtual int BeforeSelectionChange(const CPDF_FormField* pField,
                                    CFX_WideString& csValue) {
    return 0;
  }

  virtual int AfterSelectionChange(const CPDF_FormField* pField) { return 0; }

  virtual int AfterCheckedStatusChange(const CPDF_FormField* pField,
                                       const CFX_ByteArray& statusArray) {
    return 0;
  }

  virtual int BeforeFormReset(const CPDF_InterForm* pForm) { return 0; }

  virtual int AfterFormReset(const CPDF_InterForm* pForm) { return 0; }

  virtual int BeforeFormImportData(const CPDF_InterForm* pForm) { return 0; }

  virtual int AfterFormImportData(const CPDF_InterForm* pForm) { return 0; }
};
FX_BOOL FPDF_GenerateAP(CPDF_Document* pDoc, CPDF_Dictionary* pAnnotDict);
class CPDF_PageLabel {
 public:
  CPDF_PageLabel(CPDF_Document* pDocument) { m_pDocument = pDocument; }

  CFX_WideString GetLabel(int nPage) const;

  int32_t GetPageByLabel(const CFX_ByteStringC& bsLabel) const;

  int32_t GetPageByLabel(const CFX_WideStringC& wsLabel) const;

 protected:
  CPDF_Document* m_pDocument;
};

class CPDF_Metadata {
 public:
  explicit CPDF_Metadata(CPDF_Document* pDoc);
  ~CPDF_Metadata();

  const CXML_Element* GetRoot() const;

 private:
  nonstd::unique_ptr<CXML_Element> m_pXmlElement;
};

class CPDF_ViewerPreferences {
 public:
  CPDF_ViewerPreferences(CPDF_Document* pDoc);

  ~CPDF_ViewerPreferences();

  FX_BOOL IsDirectionR2L() const;

  FX_BOOL PrintScaling() const;

  int32_t NumCopies() const;

  CPDF_Array* PrintPageRange() const;

  CFX_ByteString Duplex() const;

 protected:
  CPDF_Document* m_pDoc;
};
class CPDF_ApSettings {
 public:
  CPDF_ApSettings(CPDF_Dictionary* pDict = NULL) { m_pDict = pDict; }

  operator CPDF_Dictionary*() const { return m_pDict; }

  FX_BOOL HasMKEntry(const CFX_ByteStringC& csEntry);

  int GetRotation();

  inline FX_ARGB GetBorderColor(int& iColorType) {
    return GetColor(iColorType, FX_BSTRC("BC"));
  }

  inline FX_FLOAT GetOriginalBorderColor(int index) {
    return GetOriginalColor(index, FX_BSTRC("BC"));
  }

  inline void GetOriginalBorderColor(int& iColorType, FX_FLOAT fc[4]) {
    GetOriginalColor(iColorType, fc, FX_BSTRC("BC"));
  }

  inline FX_ARGB GetBackgroundColor(int& iColorType) {
    return GetColor(iColorType, FX_BSTRC("BG"));
  }

  inline FX_FLOAT GetOriginalBackgroundColor(int index) {
    return GetOriginalColor(index, FX_BSTRC("BG"));
  }

  inline void GetOriginalBackgroundColor(int& iColorType, FX_FLOAT fc[4]) {
    GetOriginalColor(iColorType, fc, FX_BSTRC("BG"));
  }

  inline CFX_WideString GetNormalCaption() {
    return GetCaption(FX_BSTRC("CA"));
  }

  inline CFX_WideString GetRolloverCaption() {
    return GetCaption(FX_BSTRC("RC"));
  }

  inline CFX_WideString GetDownCaption() { return GetCaption(FX_BSTRC("AC")); }

  inline CPDF_Stream* GetNormalIcon() { return GetIcon(FX_BSTRC("I")); }

  inline CPDF_Stream* GetRolloverIcon() { return GetIcon(FX_BSTRC("RI")); }

  inline CPDF_Stream* GetDownIcon() { return GetIcon(FX_BSTRC("IX")); }

  CPDF_IconFit GetIconFit();

  int GetTextPosition();

  CPDF_Dictionary* m_pDict;

 protected:
  FX_ARGB GetColor(int& iColorType, const CFX_ByteStringC& csEntry);

  FX_FLOAT GetOriginalColor(int index, const CFX_ByteStringC& csEntry);

  void GetOriginalColor(int& iColorType,
                        FX_FLOAT fc[4],
                        const CFX_ByteStringC& csEntry);

  CFX_WideString GetCaption(const CFX_ByteStringC& csEntry);

  CPDF_Stream* GetIcon(const CFX_ByteStringC& csEntry);
  friend class CPDF_FormControl;
};

#endif  // CORE_INCLUDE_FPDFDOC_FPDF_DOC_H_
