// 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 <memory>
#include <vector>

#include "core/include/fpdfapi/fpdf_parser.h"
#include "core/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_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(CPDF_Page* pPage,
                         CFX_RenderDevice* pDevice,
                         const CFX_Matrix* pUser2Device,
                         AppearanceMode mode,
                         const CPDF_RenderOptions* pOptions);

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

  void ClearCachedAP();

  void DrawBorder(CFX_RenderDevice* pDevice,
                  const CFX_Matrix* 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;
  std::map<CPDF_Stream*, CPDF_Form*> m_APMap;
};

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

  void DisplayAnnots(CPDF_Page* pPage,
                     CPDF_RenderContext* pContext,
                     FX_BOOL bPrinting,
                     CFX_Matrix* pMatrix,
                     FX_BOOL bShowWidget,
                     CPDF_RenderOptions* pOptions) {
    DisplayAnnots(pPage, nullptr, pContext, bPrinting, pMatrix,
                  bShowWidget ? 3 : 1, pOptions, nullptr);
  }
  void DisplayAnnots(CPDF_Page* pPage,
                     CFX_RenderDevice* pDevice,
                     CPDF_RenderContext* pContext,
                     FX_BOOL bPrinting,
                     CFX_Matrix* 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(CPDF_Page* pPage,
                   CFX_RenderDevice* pDevice,
                   CPDF_RenderContext* pContext,
                   FX_BOOL bPrinting,
                   CFX_Matrix* 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_Matrix 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;

  std::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 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();

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

  CPDF_FormField::Type m_Type;
  FX_DWORD m_Flags;
  CPDF_InterForm* m_pForm;
  CPDF_Dictionary* m_pDict;
  CFX_ArrayTemplate<CPDF_FormControl*> m_ControlList;
  FX_FLOAT m_FontSize;
  CPDF_Font* m_pFont;

  friend class CPDF_InterForm;
  friend class CPDF_FormControl;
};
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_Matrix* 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:
  std::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, "BC");
  }

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

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

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

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

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

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

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

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

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

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

  CPDF_Stream* GetDownIcon() const { return GetIcon("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_
