// 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 "core/include/fpdfapi/fpdf_parser.h"
#include "core/include/fpdfapi/fpdf_render.h"
#include "third_party/base/nonstd_unique_ptr.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_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:
  explicit 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:
  explicit 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 };

  explicit 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_ActionFields {
 public:
  // TODO(thestig): Examine why this cannot be explicit.
  CPDF_ActionFields(const CPDF_Action* pAction) {
    m_pAction = (CPDF_Action*)pAction;
  }

  // TODO(thestig): Replace this.
  operator CPDF_Action*() const { return m_pAction; }

  FX_DWORD GetFieldsCount() const;

  std::vector<CPDF_Object*> GetAllFields() 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"); }

  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:
  // TODO(thestig): Examine why this cannot be explicit.
  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:
  explicit 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* const m_pDocument;
};
class CPDF_FileSpec {
 public:
  CPDF_FileSpec();

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

  const CPDF_Dictionary* GetAnnotDict() const { return m_pAnnotDict; }
  CPDF_Dictionary* GetAnnotDict() { return m_pAnnotDict; }

  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:
  explicit CPDF_AnnotList(CPDF_Page* pPage);
  ~CPDF_AnnotList();

  void DisplayAnnots(const CPDF_Page* pPage,
                     CPDF_RenderContext* pContext,
                     FX_BOOL bPrinting,
                     CFX_AffineMatrix* pMatrix,
                     FX_BOOL bShowWidget,
                     CPDF_RenderOptions* pOptions) {
    DisplayAnnots(pPage, nullptr, pContext, bPrinting, pMatrix,
                  bShowWidget ? 3 : 1, pOptions, nullptr);
  }
  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);
  size_t Count() const { return m_AnnotList.size(); }
  CPDF_Annot* GetAt(size_t index) const { return m_AnnotList[index]; }
  const std::vector<CPDF_Annot*>& All() const { return m_AnnotList; }
  CPDF_Document* GetDocument() const { return m_pDocument; }

 protected:
  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);

  CPDF_Document* const m_pDocument;
  std::vector<CPDF_Annot*> m_AnnotList;
};

#define COLORTYPE_TRANSPARENT 0
#define COLORTYPE_GRAY 1
#define COLORTYPE_RGB 2
#define COLORTYPE_CMYK 3
class CPDF_DefaultAppearance {
 public:
  // TODO(thestig): Examine why this cannot be explicit.
  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* AddStandardFont(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, CPDF_Document* pDocument);

  static CPDF_Font* AddNativeFont(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);

  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(const 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 std::vector<CPDF_FormField*>* fields,
      bool bIncludeOrExclude) const;

  CFDF_Document* ExportToFDF(const CFX_WideStringC& pdf_path,
                             bool bSimpleFileSpec = false) const;

  CFDF_Document* ExportToFDF(const CFX_WideStringC& pdf_path,
                             const std::vector<CPDF_FormField*>& fields,
                             bool bIncludeOrExclude = true,
                             bool bSimpleFileSpec = false) const;

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

  bool ResetForm(const std::vector<CPDF_FormField*>& fields,
                 bool bIncludeOrExclude = true,
                 bool bNotify = false);

  bool ResetForm(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(CPDF_Dictionary* pFieldDict);

  CPDF_FormControl* AddControl(const CPDF_FormField* pField,
                               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* const m_pDocument;

  FX_BOOL m_bGenerateAP;

  CPDF_Dictionary* m_pFormDict;

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

  nonstd::unique_ptr<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:
  // TODO(thestig): Examine why this cannot be explicit.
  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();

  bool HasMKEntry(CFX_ByteString csEntry) const;

  int GetRotation();

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

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

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

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

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

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

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

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

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

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

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

  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() const;

  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:
  explicit 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:
  explicit 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* const m_pDoc;
};

class CPDF_ApSettings {
 public:
  explicit CPDF_ApSettings(CPDF_Dictionary* pDict);

  bool HasMKEntry(const CFX_ByteStringC& csEntry) const;
  int GetRotation() const;

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

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

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

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

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

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

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

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

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

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

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

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

  CPDF_IconFit GetIconFit() const;

  int GetTextPosition() const;

 protected:
  friend class CPDF_FormControl;

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

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

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

  CFX_WideString GetCaption(const CFX_ByteStringC& csEntry) const;

  CPDF_Stream* GetIcon(const CFX_ByteStringC& csEntry) const;

  CPDF_Dictionary* const m_pDict;
};

CFX_WideString FILESPEC_EncodeFileName(const CFX_WideStringC& filepath);

#endif  // CORE_INCLUDE_FPDFDOC_FPDF_DOC_H_
