// 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_FPDFAPI_FPDF_OBJECTS_H_
#define CORE_INCLUDE_FPDFAPI_FPDF_OBJECTS_H_

#include <map>
#include <set>

#include "core/include/fxcrt/fx_coordinates.h"
#include "core/include/fxcrt/fx_system.h"

class CPDF_Array;
class CPDF_Boolean;
class CPDF_CryptoHandler;
class CPDF_Dictionary;
class CPDF_Document;
class CPDF_IndirectObjectHolder;
class CPDF_Name;
class CPDF_Null;
class CPDF_Number;
class CPDF_Parser;
class CPDF_Reference;
class CPDF_Stream;
class CPDF_StreamAcc;
class CPDF_StreamFilter;
class CPDF_String;
class IFX_FileRead;
struct PARSE_CONTEXT;

#define PDFOBJ_INVALID 0
#define PDFOBJ_BOOLEAN 1
#define PDFOBJ_NUMBER 2
#define PDFOBJ_STRING 3
#define PDFOBJ_NAME 4
#define PDFOBJ_ARRAY 5
#define PDFOBJ_DICTIONARY 6
#define PDFOBJ_STREAM 7
#define PDFOBJ_NULL 8
#define PDFOBJ_REFERENCE 9

class CPDF_Object {
 public:
  int GetType() const { return m_Type; }

  FX_DWORD GetObjNum() const { return m_ObjNum; }

  FX_DWORD GetGenNum() const { return m_GenNum; }

  FX_BOOL IsIdentical(CPDF_Object* pObj) const;

  CPDF_Object* Clone(FX_BOOL bDirect = FALSE) const;

  CPDF_Object* CloneRef(CPDF_IndirectObjectHolder* pObjs) const;

  CPDF_Object* GetDirect() const;

  void Release();

  CFX_ByteString GetString() const;

  CFX_ByteStringC GetConstString() const;

  CFX_WideString GetUnicodeText(CFX_CharMap* pCharMap = NULL) const;
  FX_FLOAT GetNumber() const;

  FX_FLOAT GetNumber16() const;

  int GetInteger() const;

  CPDF_Dictionary* GetDict() const;

  CPDF_Array* GetArray() const;

  void SetString(const CFX_ByteString& str);

  void SetUnicodeText(const FX_WCHAR* pUnicodes, int len = -1);

  int GetDirectType() const;

  FX_BOOL IsModified() const { return FALSE; }

  bool IsArray() const { return m_Type == PDFOBJ_ARRAY; }
  bool IsBoolean() const { return m_Type == PDFOBJ_BOOLEAN; }
  bool IsDictionary() const { return m_Type == PDFOBJ_DICTIONARY; }
  bool IsName() const { return m_Type == PDFOBJ_NAME; }
  bool IsNumber() const { return m_Type == PDFOBJ_NUMBER; }
  bool IsReference() const { return m_Type == PDFOBJ_REFERENCE; }
  bool IsStream() const { return m_Type == PDFOBJ_STREAM; }
  bool IsString() const { return m_Type == PDFOBJ_STRING; }

  CPDF_Array* AsArray();
  const CPDF_Array* AsArray() const;

  CPDF_Boolean* AsBoolean();
  const CPDF_Boolean* AsBoolean() const;

  CPDF_Dictionary* AsDictionary();
  const CPDF_Dictionary* AsDictionary() const;

  CPDF_Name* AsName();
  const CPDF_Name* AsName() const;

  CPDF_Number* AsNumber();
  const CPDF_Number* AsNumber() const;

  CPDF_Reference* AsReference();
  const CPDF_Reference* AsReference() const;

  CPDF_Stream* AsStream();
  const CPDF_Stream* AsStream() const;

  CPDF_String* AsString();
  const CPDF_String* AsString() const;

 protected:
  explicit CPDF_Object(FX_DWORD type)
      : m_Type(type), m_ObjNum(0), m_GenNum(0) {}
  ~CPDF_Object() {}
  void Destroy();

  static const int kObjectRefMaxDepth = 128;
  static int s_nCurRefDepth;
  FX_DWORD m_Type;
  FX_DWORD m_ObjNum;
  FX_DWORD m_GenNum;

  friend class CPDF_IndirectObjectHolder;
  friend class CPDF_Parser;
  friend class CPDF_SyntaxParser;

 private:
  CPDF_Object(const CPDF_Object& src) {}
  CPDF_Object* CloneInternal(FX_BOOL bDirect,
                             std::set<FX_DWORD>* visited) const;
};
class CPDF_Boolean : public CPDF_Object {
 public:
  CPDF_Boolean() : CPDF_Object(PDFOBJ_BOOLEAN), m_bValue(false) {}
  explicit CPDF_Boolean(FX_BOOL value)
      : CPDF_Object(PDFOBJ_BOOLEAN), m_bValue(value) {}

  FX_BOOL Identical(CPDF_Boolean* pOther) const {
    return m_bValue == pOther->m_bValue;
  }

 protected:
  FX_BOOL m_bValue;
  friend class CPDF_Object;
};
inline CPDF_Boolean* ToBoolean(CPDF_Object* obj) {
  return obj ? obj->AsBoolean() : nullptr;
}
inline const CPDF_Boolean* ToBoolean(const CPDF_Object* obj) {
  return obj ? obj->AsBoolean() : nullptr;
}

class CPDF_Number : public CPDF_Object {
 public:
  CPDF_Number() : CPDF_Object(PDFOBJ_NUMBER), m_bInteger(TRUE), m_Integer(0) {}

  explicit CPDF_Number(int value);

  explicit CPDF_Number(FX_FLOAT value);

  explicit CPDF_Number(const CFX_ByteStringC& str);

  FX_BOOL Identical(CPDF_Number* pOther) const;

  CFX_ByteString GetString() const;

  void SetString(const CFX_ByteStringC& str);

  FX_BOOL IsInteger() const { return m_bInteger; }

  int GetInteger() const { return m_bInteger ? m_Integer : (int)m_Float; }

  FX_FLOAT GetNumber() const {
    return m_bInteger ? (FX_FLOAT)m_Integer : m_Float;
  }

  void SetNumber(FX_FLOAT value);

  FX_FLOAT GetNumber16() const { return GetNumber(); }

  FX_FLOAT GetFloat() const {
    return m_bInteger ? (FX_FLOAT)m_Integer : m_Float;
  }

 protected:
  FX_BOOL m_bInteger;

  union {
    int m_Integer;

    FX_FLOAT m_Float;
  };
  friend class CPDF_Object;
};
inline CPDF_Number* ToNumber(CPDF_Object* obj) {
  return obj ? obj->AsNumber() : nullptr;
}
inline const CPDF_Number* ToNumber(const CPDF_Object* obj) {
  return obj ? obj->AsNumber() : nullptr;
}

class CPDF_String : public CPDF_Object {
 public:
  CPDF_String() : CPDF_Object(PDFOBJ_STRING), m_bHex(FALSE) {}

  CPDF_String(const CFX_ByteString& str, FX_BOOL bHex)
      : CPDF_Object(PDFOBJ_STRING), m_String(str), m_bHex(bHex) {}

  explicit CPDF_String(const CFX_WideString& str);

  CFX_ByteString& GetString() { return m_String; }

  FX_BOOL Identical(CPDF_String* pOther) const {
    return m_String == pOther->m_String;
  }

  FX_BOOL IsHex() const { return m_bHex; }

 protected:
  CFX_ByteString m_String;

  FX_BOOL m_bHex;
  friend class CPDF_Object;
};
inline CPDF_String* ToString(CPDF_Object* obj) {
  return obj ? obj->AsString() : nullptr;
}
inline const CPDF_String* ToString(const CPDF_Object* obj) {
  return obj ? obj->AsString() : nullptr;
}

class CPDF_Name : public CPDF_Object {
 public:
  explicit CPDF_Name(const CFX_ByteString& str)
      : CPDF_Object(PDFOBJ_NAME), m_Name(str) {}
  explicit CPDF_Name(const CFX_ByteStringC& str)
      : CPDF_Object(PDFOBJ_NAME), m_Name(str) {}
  explicit CPDF_Name(const FX_CHAR* str)
      : CPDF_Object(PDFOBJ_NAME), m_Name(str) {}

  CFX_ByteString& GetString() { return m_Name; }

  FX_BOOL Identical(CPDF_Name* pOther) const {
    return m_Name == pOther->m_Name;
  }

 protected:
  CFX_ByteString m_Name;
  friend class CPDF_Object;
};
inline CPDF_Name* ToName(CPDF_Object* obj) {
  return obj ? obj->AsName() : nullptr;
}
inline const CPDF_Name* ToName(const CPDF_Object* obj) {
  return obj ? obj->AsName() : nullptr;
}

class CPDF_Array : public CPDF_Object {
 public:
  CPDF_Array() : CPDF_Object(PDFOBJ_ARRAY) {}

  FX_DWORD GetCount() const { return m_Objects.GetSize(); }

  CPDF_Object* GetElement(FX_DWORD index) const;

  CPDF_Object* GetElementValue(FX_DWORD index) const;

  CFX_Matrix GetMatrix();

  CFX_FloatRect GetRect();

  CFX_ByteString GetString(FX_DWORD index) const;

  CFX_ByteStringC GetConstString(FX_DWORD index) const;

  int GetInteger(FX_DWORD index) const;

  FX_FLOAT GetNumber(FX_DWORD index) const;

  CPDF_Dictionary* GetDict(FX_DWORD index) const;

  CPDF_Stream* GetStream(FX_DWORD index) const;

  CPDF_Array* GetArray(FX_DWORD index) const;

  FX_FLOAT GetFloat(FX_DWORD index) const { return GetNumber(index); }

  void SetAt(FX_DWORD index,
             CPDF_Object* pObj,
             CPDF_IndirectObjectHolder* pObjs = NULL);

  void InsertAt(FX_DWORD index,
                CPDF_Object* pObj,
                CPDF_IndirectObjectHolder* pObjs = NULL);

  void RemoveAt(FX_DWORD index, int nCount = 1);

  void Add(CPDF_Object* pObj, CPDF_IndirectObjectHolder* pObjs = NULL);

  void AddNumber(FX_FLOAT f);

  void AddInteger(int i);

  void AddString(const CFX_ByteString& str);

  void AddName(const CFX_ByteString& str);

  void AddReference(CPDF_IndirectObjectHolder* pDoc, FX_DWORD objnum);

  void AddReference(CPDF_IndirectObjectHolder* pDoc, CPDF_Object* obj) {
    AddReference(pDoc, obj->GetObjNum());
  }

  FX_FLOAT GetNumber16(FX_DWORD index) const { return GetNumber(index); }

  void AddNumber16(FX_FLOAT value) { AddNumber(value); }

  FX_BOOL Identical(CPDF_Array* pOther) const;

 protected:
  ~CPDF_Array();

  CFX_ArrayTemplate<CPDF_Object*> m_Objects;
  friend class CPDF_Object;
};
inline CPDF_Array* ToArray(CPDF_Object* obj) {
  return obj ? obj->AsArray() : nullptr;
}
inline const CPDF_Array* ToArray(const CPDF_Object* obj) {
  return obj ? obj->AsArray() : nullptr;
}

class CPDF_Dictionary : public CPDF_Object {
 public:
  using iterator = std::map<CFX_ByteString, CPDF_Object*>::iterator;
  using const_iterator = std::map<CFX_ByteString, CPDF_Object*>::const_iterator;

  CPDF_Dictionary() : CPDF_Object(PDFOBJ_DICTIONARY) {}

  CPDF_Object* GetElement(const CFX_ByteStringC& key) const;

  CPDF_Object* GetElementValue(const CFX_ByteStringC& key) const;

  CFX_ByteString GetString(const CFX_ByteStringC& key) const;

  CFX_ByteStringC GetConstString(const CFX_ByteStringC& key) const;

  CFX_ByteString GetString(const CFX_ByteStringC& key,
                           const CFX_ByteStringC& default_str) const;

  CFX_ByteStringC GetConstString(const CFX_ByteStringC& key,
                                 const CFX_ByteStringC& default_str) const;

  CFX_WideString GetUnicodeText(const CFX_ByteStringC& key,
                                CFX_CharMap* pCharMap = NULL) const;

  int GetInteger(const CFX_ByteStringC& key) const;

  int GetInteger(const CFX_ByteStringC& key, int default_int) const;

  FX_BOOL GetBoolean(const CFX_ByteStringC& key,
                     FX_BOOL bDefault = FALSE) const;

  FX_FLOAT GetNumber(const CFX_ByteStringC& key) const;

  CPDF_Dictionary* GetDict(const CFX_ByteStringC& key) const;

  CPDF_Stream* GetStream(const CFX_ByteStringC& key) const;

  CPDF_Array* GetArray(const CFX_ByteStringC& key) const;

  CFX_FloatRect GetRect(const CFX_ByteStringC& key) const;

  CFX_Matrix GetMatrix(const CFX_ByteStringC& key) const;

  FX_FLOAT GetFloat(const CFX_ByteStringC& key) const { return GetNumber(key); }

  FX_BOOL KeyExist(const CFX_ByteStringC& key) const;

  void SetAt(const CFX_ByteStringC& key, CPDF_Object* pObj);

  void SetAtName(const CFX_ByteStringC& key, const CFX_ByteString& name);

  void SetAtString(const CFX_ByteStringC& key, const CFX_ByteString& string);

  void SetAtInteger(const CFX_ByteStringC& key, int i);

  void SetAtNumber(const CFX_ByteStringC& key, FX_FLOAT f);

  void SetAtReference(const CFX_ByteStringC& key,
                      CPDF_IndirectObjectHolder* pDoc,
                      FX_DWORD objnum);

  void SetAtReference(const CFX_ByteStringC& key,
                      CPDF_IndirectObjectHolder* pDoc,
                      CPDF_Object* obj) {
    SetAtReference(key, pDoc, obj->GetObjNum());
  }

  void AddReference(const CFX_ByteStringC& key,
                    CPDF_IndirectObjectHolder* pDoc,
                    FX_DWORD objnum);

  void SetAtRect(const CFX_ByteStringC& key, const CFX_FloatRect& rect);

  void SetAtMatrix(const CFX_ByteStringC& key, const CFX_Matrix& matrix);

  void SetAtBoolean(const CFX_ByteStringC& key, FX_BOOL bValue);

  void RemoveAt(const CFX_ByteStringC& key);

  void ReplaceKey(const CFX_ByteStringC& oldkey, const CFX_ByteStringC& newkey);

  FX_BOOL Identical(CPDF_Dictionary* pDict) const;

  size_t GetCount() const { return m_Map.size(); }

  iterator begin() { return m_Map.begin(); }

  iterator end() { return m_Map.end(); }

  const_iterator begin() const { return m_Map.begin(); }

  const_iterator end() const { return m_Map.end(); }

 protected:
  ~CPDF_Dictionary();

  std::map<CFX_ByteString, CPDF_Object*> m_Map;

  friend class CPDF_Object;
};
inline CPDF_Dictionary* ToDictionary(CPDF_Object* obj) {
  return obj ? obj->AsDictionary() : nullptr;
}
inline const CPDF_Dictionary* ToDictionary(const CPDF_Object* obj) {
  return obj ? obj->AsDictionary() : nullptr;
}

class CPDF_Stream : public CPDF_Object {
 public:
  CPDF_Stream(uint8_t* pData, FX_DWORD size, CPDF_Dictionary* pDict);

  CPDF_Dictionary* GetDict() const { return m_pDict; }

  void SetData(const uint8_t* pData,
               FX_DWORD size,
               FX_BOOL bCompressed,
               FX_BOOL bKeepBuf);

  void InitStream(uint8_t* pData, FX_DWORD size, CPDF_Dictionary* pDict);

  void InitStreamFromFile(IFX_FileRead* pFile, CPDF_Dictionary* pDict);

  FX_BOOL Identical(CPDF_Stream* pOther) const;

  FX_DWORD GetRawSize() const { return m_dwSize; }

  FX_BOOL ReadRawData(FX_FILESIZE start_pos,
                      uint8_t* pBuf,
                      FX_DWORD buf_size) const;

  FX_BOOL IsMemoryBased() const { return m_GenNum == kMemoryBasedGenNum; }

 protected:
  friend class CPDF_Object;
  friend class CPDF_StreamAcc;

  static const FX_DWORD kMemoryBasedGenNum = (FX_DWORD)-1;
  ~CPDF_Stream();

  void InitStreamInternal(CPDF_Dictionary* pDict);

  CPDF_Dictionary* m_pDict;

  FX_DWORD m_dwSize;

  FX_DWORD m_GenNum;

  union {
    uint8_t* m_pDataBuf;

    IFX_FileRead* m_pFile;
  };
};
inline CPDF_Stream* ToStream(CPDF_Object* obj) {
  return obj ? obj->AsStream() : nullptr;
}
inline const CPDF_Stream* ToStream(const CPDF_Object* obj) {
  return obj ? obj->AsStream() : nullptr;
}

class CPDF_StreamAcc {
 public:
  CPDF_StreamAcc();

  ~CPDF_StreamAcc();

  void LoadAllData(const CPDF_Stream* pStream,
                   FX_BOOL bRawAccess = FALSE,
                   FX_DWORD estimated_size = 0,
                   FX_BOOL bImageAcc = FALSE);

  const CPDF_Stream* GetStream() const { return m_pStream; }

  CPDF_Dictionary* GetDict() const {
    return m_pStream ? m_pStream->GetDict() : nullptr;
  }

  const uint8_t* GetData() const;

  FX_DWORD GetSize() const;

  uint8_t* DetachData();

  const CFX_ByteString& GetImageDecoder() { return m_ImageDecoder; }

  const CPDF_Dictionary* GetImageParam() { return m_pImageParam; }

 protected:
  uint8_t* m_pData;

  FX_DWORD m_dwSize;

  FX_BOOL m_bNewBuf;

  CFX_ByteString m_ImageDecoder;

  CPDF_Dictionary* m_pImageParam;

  const CPDF_Stream* m_pStream;

  uint8_t* m_pSrcData;
};

class CPDF_Null : public CPDF_Object {
 public:
  CPDF_Null() : CPDF_Object(PDFOBJ_NULL) {}
};

class CPDF_Reference : public CPDF_Object {
 public:
  CPDF_Reference(CPDF_IndirectObjectHolder* pDoc, int objnum)
      : CPDF_Object(PDFOBJ_REFERENCE), m_pObjList(pDoc), m_RefObjNum(objnum) {}

  CPDF_IndirectObjectHolder* GetObjList() const { return m_pObjList; }

  FX_DWORD GetRefObjNum() const { return m_RefObjNum; }

  void SetRef(CPDF_IndirectObjectHolder* pDoc, FX_DWORD objnum);

  FX_BOOL Identical(CPDF_Reference* pOther) const {
    return m_RefObjNum == pOther->m_RefObjNum;
  }

 protected:
  CPDF_IndirectObjectHolder* m_pObjList;

  FX_DWORD m_RefObjNum;
  friend class CPDF_Object;
};
inline CPDF_Reference* ToReference(CPDF_Object* obj) {
  return obj ? obj->AsReference() : nullptr;
}
inline const CPDF_Reference* ToReference(const CPDF_Object* obj) {
  return obj ? obj->AsReference() : nullptr;
}

class CPDF_IndirectObjectHolder {
 public:
  using iterator = std::map<FX_DWORD, CPDF_Object*>::iterator;
  using const_iterator = std::map<FX_DWORD, CPDF_Object*>::const_iterator;

  explicit CPDF_IndirectObjectHolder(CPDF_Parser* pParser);
  ~CPDF_IndirectObjectHolder();

  int GetIndirectType(FX_DWORD objnum);
  CPDF_Object* GetIndirectObject(FX_DWORD objnum, PARSE_CONTEXT* pContext);
  FX_DWORD AddIndirectObject(CPDF_Object* pObj);
  void ReleaseIndirectObject(FX_DWORD objnum);

  // Takes ownership of |pObj|.
  FX_BOOL InsertIndirectObject(FX_DWORD objnum, CPDF_Object* pObj);

  FX_DWORD GetLastObjNum() const { return m_LastObjNum; }
  iterator begin() { return m_IndirectObjs.begin(); }
  const_iterator begin() const { return m_IndirectObjs.cbegin(); }
  iterator end() { return m_IndirectObjs.end(); }
  const_iterator end() const { return m_IndirectObjs.end(); }

 protected:
  CPDF_Parser* m_pParser;
  FX_DWORD m_LastObjNum;
  std::map<FX_DWORD, CPDF_Object*> m_IndirectObjs;
};

#endif  // CORE_INCLUDE_FPDFAPI_FPDF_OBJECTS_H_
