// 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 _FPDF_OBJECTS_
#define _FPDF_OBJECTS_
#ifndef _FXCRT_EXTENSION_
#include "../fxcrt/fx_ext.h"
#endif
class CPDF_Document;
class CPDF_IndirectObjects;
class CPDF_Null;
class CPDF_Boolean;
class CPDF_Number;
class CPDF_String;
class CPDF_Stream;
class CPDF_StreamAcc;
class CPDF_StreamFilter;
class CPDF_Array;
class CPDF_Dictionary;
class CPDF_Reference;
class IPDF_DocParser;
class IFX_FileRead;
class CPDF_CryptoHandler;
#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
typedef IFX_FileStream* (*FPDF_LPFCloneStreamCallback)(CPDF_Stream *pStream, FX_LPVOID pUserData);
class CPDF_Object : public CFX_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_IndirectObjects* 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(FX_LPCWSTR pUnicodes, int len = -1);

    int						GetDirectType() const;

    FX_BOOL					IsModified() const
    {
        return FALSE;
    }
protected:
    FX_DWORD				m_Type;
    CPDF_Object()
    {
        m_ObjNum = 0;
        m_GenNum = 0;
    }

    FX_DWORD 				m_ObjNum;
    FX_DWORD				m_GenNum;

    void					Destroy();


    ~CPDF_Object() {}
    friend class			CPDF_IndirectObjects;
    friend class			CPDF_Parser;
    friend class			CPDF_SyntaxParser;
private:
    CPDF_Object(const CPDF_Object& src) {}
    CPDF_Object* CloneInternal(FX_BOOL bDirect, CFX_MapPtrToPtr* visited) const;
};
class CPDF_Boolean : public CPDF_Object
{
public:

    static CPDF_Boolean*	Create(FX_BOOL value)
    {
        return FX_NEW CPDF_Boolean(value);
    }

    CPDF_Boolean()
    {
        m_Type = PDFOBJ_BOOLEAN;
    }

    CPDF_Boolean(FX_BOOL value)
    {
        m_Type = 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;
};
class CPDF_Number : public CPDF_Object
{
public:

    static CPDF_Number*		Create(int value)
    {
        return FX_NEW CPDF_Number(value);
    }

    static CPDF_Number*		Create(FX_FLOAT value)
    {
        return FX_NEW CPDF_Number(value);
    }

    static CPDF_Number*		Create(FX_BSTR str)
    {
        return FX_NEW CPDF_Number(str);
    }

    static CPDF_Number*		Create(FX_BOOL bInteger, void* pData)
    {
        return FX_NEW CPDF_Number(bInteger, pData);
    }

    CPDF_Number(): m_Integer(0) 
    {
        m_Type = PDFOBJ_NUMBER;
    } 

    CPDF_Number(FX_BOOL bInteger, void* pData);

    CPDF_Number(int value);

    CPDF_Number(FX_FLOAT value);

    CPDF_Number(FX_BSTR str);

    FX_BOOL					Identical(CPDF_Number* pOther) const;

    CFX_ByteString			GetString() const;

    void					SetString(FX_BSTR 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;
};
class CPDF_String : public CPDF_Object
{
public:

    static CPDF_String*		Create(const CFX_ByteString& str, FX_BOOL bHex = FALSE)
    {
        return FX_NEW CPDF_String(str, bHex);
    }

    static CPDF_String*		Create(const CFX_WideString& str)
    {
        return FX_NEW CPDF_String(str);
    }

    CPDF_String()
    {
        m_Type = PDFOBJ_STRING;
        m_bHex = FALSE;
    }

    CPDF_String(const CFX_ByteString& str, FX_BOOL bHex = FALSE) : m_String(str)
    {
        m_Type = PDFOBJ_STRING;
        m_bHex = bHex;
    }

    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;
};
class CPDF_Name : public CPDF_Object
{
public:

    static CPDF_Name*		Create(const CFX_ByteString& str)
    {
        return FX_NEW CPDF_Name(str);
    }

    static CPDF_Name*		Create(FX_BSTR str)
    {
        return FX_NEW CPDF_Name(str);
    }

    static CPDF_Name*		Create(FX_LPCSTR str)
    {
        return FX_NEW CPDF_Name(str);
    }

    CPDF_Name(const CFX_ByteString& str) : m_Name(str)
    {
        m_Type = PDFOBJ_NAME;
    }

    CPDF_Name(FX_BSTR str) : m_Name(str)
    {
        m_Type = PDFOBJ_NAME;
    }

    CPDF_Name(FX_LPCSTR str) : m_Name(str)
    {
        m_Type = PDFOBJ_NAME;
    }

    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;
};
class CPDF_Array : public CPDF_Object
{
public:

    static CPDF_Array*		Create()
    {
        return FX_NEW CPDF_Array();
    }

    CPDF_Array()
    {
        m_Type = 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_AffineMatrix		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_IndirectObjects* pObjs = NULL);


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

    void					RemoveAt(FX_DWORD index);


    void					Add(CPDF_Object* pObj, CPDF_IndirectObjects* 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_IndirectObjects* pDoc, FX_DWORD objnum);

    void					AddReference(CPDF_IndirectObjects* 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_PtrArray			m_Objects;
    friend class			CPDF_Object;
};
class CPDF_Dictionary : public CPDF_Object
{
public:

    static CPDF_Dictionary*	Create()
    {
        return FX_NEW CPDF_Dictionary();
    }

    CPDF_Dictionary()
    {
        m_Type = PDFOBJ_DICTIONARY;
    }



    CPDF_Object*			GetElement(FX_BSTR key) const;

    CPDF_Object*			GetElementValue(FX_BSTR key) const;





    CFX_ByteString			GetString(FX_BSTR key) const;

    CFX_ByteStringC			GetConstString(FX_BSTR key) const;

    CFX_ByteString			GetString(FX_BSTR key, FX_BSTR default_str) const;

    CFX_ByteStringC			GetConstString(FX_BSTR key, FX_BSTR default_str) const;

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

    int						GetInteger(FX_BSTR key) const;

    int						GetInteger(FX_BSTR key, int default_int) const;

    FX_BOOL					GetBoolean(FX_BSTR key, FX_BOOL bDefault = FALSE) const;

    FX_FLOAT				GetNumber(FX_BSTR key) const;

    CPDF_Dictionary*		GetDict(FX_BSTR key) const;

    CPDF_Stream*			GetStream(FX_BSTR key) const;

    CPDF_Array*				GetArray(FX_BSTR key) const;

    CFX_FloatRect			GetRect(FX_BSTR key) const;

    CFX_AffineMatrix		GetMatrix(FX_BSTR key) const;

    FX_FLOAT				GetFloat(FX_BSTR key) const
    {
        return GetNumber(key);
    }


    FX_BOOL					KeyExist(FX_BSTR key) const;

    FX_POSITION				GetStartPos() const;

    CPDF_Object*			GetNextElement(FX_POSITION& pos, CFX_ByteString& key) const;

    void					SetAt(FX_BSTR key, CPDF_Object* pObj, CPDF_IndirectObjects* pObjs = NULL);



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


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


    void					SetAtInteger(FX_BSTR key, int i);


    void					SetAtNumber(FX_BSTR key, FX_FLOAT f);

    void					SetAtReference(FX_BSTR key, CPDF_IndirectObjects* pDoc, FX_DWORD objnum);

    void					SetAtReference(FX_BSTR key, CPDF_IndirectObjects* pDoc, CPDF_Object* obj)
    {
        SetAtReference(key, pDoc, obj->GetObjNum());
    }

    void					AddReference(FX_BSTR key, CPDF_IndirectObjects* pDoc, FX_DWORD objnum);

    void					AddReference(FX_BSTR key, CPDF_IndirectObjects* pDoc, CPDF_Object* obj)
    {
        AddReference(key, pDoc, obj->GetObjNum());
    }

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

    void					SetAtMatrix(FX_BSTR key, const CFX_AffineMatrix& matrix);

    void					SetAtBoolean(FX_BSTR key, FX_BOOL bValue);



    void					RemoveAt(FX_BSTR key);


    void					ReplaceKey(FX_BSTR oldkey, FX_BSTR newkey);

    FX_BOOL					Identical(CPDF_Dictionary* pDict) const;

    int						GetCount() const
    {
        return m_Map.GetCount();
    }

    void					AddValue(FX_BSTR key, CPDF_Object* pObj);
protected:

    ~CPDF_Dictionary();

    CFX_CMapByteStringToPtr	m_Map;

    friend class			CPDF_Object;
};
class CPDF_Stream : public CPDF_Object
{
public:

    static CPDF_Stream*		Create(FX_LPBYTE pData, FX_DWORD size, CPDF_Dictionary* pDict)
    {
        return FX_NEW CPDF_Stream(pData, size, pDict);
    }

    CPDF_Stream(FX_LPBYTE pData, FX_DWORD size, CPDF_Dictionary* pDict);

    CPDF_Dictionary*		GetDict() const
    {
        return m_pDict;
    }

    void					SetData(FX_LPCBYTE pData, FX_DWORD size, FX_BOOL bCompressed, FX_BOOL bKeepBuf);

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

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

    FX_BOOL					Identical(CPDF_Stream* pOther) const;

    CPDF_StreamFilter*		GetStreamFilter(FX_BOOL bRaw = FALSE) const;



    FX_DWORD				GetRawSize() const
    {
        return m_dwSize;
    }

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


    FX_BOOL					IsMemoryBased() const
    {
        return m_GenNum == (FX_DWORD) - 1;
    }

    CPDF_Stream*			Clone(FX_BOOL bDirect, FPDF_LPFCloneStreamCallback lpfCallback, FX_LPVOID pUserData) const;
protected:

    ~CPDF_Stream();

    CPDF_Dictionary*		m_pDict;

    FX_DWORD				m_dwSize;

    FX_DWORD				m_GenNum;

    union {

        FX_LPBYTE			m_pDataBuf;

        IFX_FileRead*		m_pFile;
    };

    FX_FILESIZE				m_FileOffset;

    CPDF_CryptoHandler*		m_pCryptoHandler;

    void					InitStream(CPDF_Dictionary* pDict);
    friend class			CPDF_Object;
    friend class			CPDF_StreamAcc;
    friend class			CPDF_AttachmentAcc;
};
class CPDF_StreamAcc : public CFX_Object
{
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() : NULL;
    }

    FX_LPCBYTE				GetData() const;

    FX_DWORD				GetSize() const;

    FX_LPBYTE				DetachData();

    const CFX_ByteString&	GetImageDecoder()
    {
        return m_ImageDecoder;
    }

    const CPDF_Dictionary*	GetImageParam()
    {
        return m_pImageParam;
    }
protected:

    FX_LPBYTE				m_pData;

    FX_DWORD				m_dwSize;

    FX_BOOL					m_bNewBuf;

    CFX_ByteString			m_ImageDecoder;

    CPDF_Dictionary*		m_pImageParam;

    const CPDF_Stream*		m_pStream;

    FX_LPBYTE				m_pSrcData;
};
CFX_DataFilter* FPDF_CreateFilter(FX_BSTR name, const CPDF_Dictionary* pParam, int width = 0, int height = 0);
#define FPDF_FILTER_BUFFER_SIZE		20480
class CPDF_StreamFilter : public CFX_Object
{
public:

    ~CPDF_StreamFilter();

    FX_DWORD			ReadBlock(FX_LPBYTE buffer, FX_DWORD size);

    FX_DWORD			GetSrcPos()
    {
        return m_SrcOffset;
    }

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

    CPDF_StreamFilter() {}

    FX_DWORD			ReadLeftOver(FX_LPBYTE buffer, FX_DWORD buf_size);

    const CPDF_Stream*	m_pStream;

    CFX_DataFilter*		m_pFilter;

    CFX_BinaryBuf*		m_pBuffer;

    FX_DWORD			m_BufOffset;

    FX_DWORD			m_SrcOffset;

    FX_BYTE				m_SrcBuffer[FPDF_FILTER_BUFFER_SIZE];
    friend class CPDF_Stream;
};
class CPDF_Null : public CPDF_Object
{
public:

    static CPDF_Null*		Create()
    {
        return FX_NEW CPDF_Null();
    }

    CPDF_Null()
    {
        m_Type = PDFOBJ_NULL;
    }
};
class CPDF_Reference : public CPDF_Object
{
public:

    static CPDF_Reference*	Create(CPDF_IndirectObjects* pDoc, int objnum)
    {
        return FX_NEW CPDF_Reference(pDoc, objnum);
    }

    CPDF_Reference(CPDF_IndirectObjects* pDoc, int objnum)
    {
        m_Type = PDFOBJ_REFERENCE;
        m_pObjList = pDoc;
        m_RefObjNum = objnum;
    }

    CPDF_IndirectObjects*	GetObjList() const
    {
        return m_pObjList;
    }

    FX_DWORD				GetRefObjNum() const
    {
        return m_RefObjNum;
    }

    void					SetRef(CPDF_IndirectObjects* pDoc, FX_DWORD objnum);

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

    CPDF_IndirectObjects*	m_pObjList;

    FX_DWORD				m_RefObjNum;
    friend class			CPDF_Object;
};
class CPDF_IndirectObjects : public CFX_Object
{
public:

    CPDF_IndirectObjects(IPDF_DocParser* pParser);

    ~CPDF_IndirectObjects();

    CPDF_Object*			GetIndirectObject(FX_DWORD objnum, struct PARSE_CONTEXT* pContext = NULL);

    int						GetIndirectType(FX_DWORD objnum);

    FX_DWORD				AddIndirectObject(CPDF_Object* pObj);

    void					ReleaseIndirectObject(FX_DWORD objnum);

    void					InsertIndirectObject(FX_DWORD objnum, CPDF_Object* pObj);

    FX_DWORD				GetLastObjNum() const;

    FX_POSITION				GetStartPosition() const
    {
        return m_IndirectObjs.GetStartPosition();
    }

    void					GetNextAssoc(FX_POSITION& rPos, FX_DWORD& objnum, CPDF_Object*& pObject) const
    {
        m_IndirectObjs.GetNextAssoc(rPos, (void*&)objnum, (void*&)pObject);
    }
protected:

    CFX_MapPtrToPtr			m_IndirectObjs;

    IPDF_DocParser*			m_pParser;

    FX_DWORD				m_LastObjNum;
};
#endif
