// 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_TAGGED_INT_H_
#define _FPDF_TAGGED_INT_H_
class CPDF_StructTreeImpl;
class CPDF_StructElementImpl;
class CPDF_StructTreeImpl : public CPDF_StructTree
{
public:
    CPDF_StructTreeImpl(const CPDF_Document* pDoc);
    ~CPDF_StructTreeImpl();
    int			CountTopElements() const
    {
        return m_Kids.GetSize();
    }
    CPDF_StructElement*	GetTopElement(int i) const
    {
        return (CPDF_StructElement*)m_Kids.GetAt(i);
    }
    void		LoadDocTree();
    void		LoadPageTree(const CPDF_Dictionary* pPageDict);
    CPDF_StructElementImpl* AddPageNode(CPDF_Dictionary* pElement, CFX_MapPtrToPtr& map, int nLevel = 0);
    FX_BOOL		AddTopLevelNode(CPDF_Dictionary* pDict, CPDF_StructElementImpl* pElement);
protected:
    const CPDF_Dictionary*	m_pTreeRoot;
    const CPDF_Dictionary*	m_pRoleMap;
    const CPDF_Dictionary*	m_pPage;
    CFX_ArrayTemplate<CPDF_StructElementImpl*>	m_Kids;
    friend class CPDF_StructElementImpl;
};
class CPDF_StructElementImpl : public CPDF_StructElement
{
public:
    CPDF_StructElementImpl(CPDF_StructTreeImpl* pTree, CPDF_StructElementImpl* pParent, CPDF_Dictionary* pDict);
    ~CPDF_StructElementImpl();
    CPDF_StructTree*		GetTree() const
    {
        return m_pTree;
    }
    const CFX_ByteString&	GetType() const
    {
        return m_Type;
    }
    CPDF_StructElement*		GetParent() const
    {
        return m_pParent;
    }
    CPDF_Dictionary *		GetDict() const
    {
        return m_pDict;
    }
    int						CountKids() const
    {
        return m_Kids.GetSize();
    }
    const CPDF_StructKid&	GetKid(int index) const
    {
        return m_Kids.GetData()[index];
    }
    CFX_PtrArray*			GetObjectArray()
    {
        return &m_ObjectArray;
    }

    CPDF_Object*			GetAttr(FX_BSTR owner, FX_BSTR name, FX_BOOL bInheritable = FALSE, FX_FLOAT fLevel = 0.0F);

    CFX_ByteString			GetName(FX_BSTR owner, FX_BSTR name, FX_BSTR default_value, FX_BOOL bInheritable = FALSE, int subindex = -1);
    FX_ARGB					GetColor(FX_BSTR owner, FX_BSTR name, FX_ARGB default_value, FX_BOOL bInheritable = FALSE, int subindex = -1);
    FX_FLOAT				GetNumber(FX_BSTR owner, FX_BSTR name, FX_FLOAT default_value, FX_BOOL bInheritable = FALSE, int subindex = -1);
    int						GetInteger(FX_BSTR owner, FX_BSTR name, int default_value, FX_BOOL bInheritable = FALSE, int subindex = -1);
    CFX_PtrArray			m_ObjectArray;
    void					LoadKids(CPDF_Dictionary* pDict);
    void					LoadKid(FX_DWORD PageObjNum, CPDF_Object* pObj, CPDF_StructKid* pKid);
    CPDF_Object*			GetAttr(FX_BSTR owner, FX_BSTR name, FX_BOOL bInheritable, int subindex);
    CPDF_StructElementImpl*	Retain();
    void					Release();
protected:
    CPDF_StructTreeImpl*	m_pTree;
    CFX_ByteString			m_Type;
    CPDF_StructElementImpl*	m_pParent;
    CPDF_Dictionary*		m_pDict;
    CFX_ArrayTemplate<CPDF_StructKid>	m_Kids;

    int			m_RefCount;
    friend class CPDF_StructTreeImpl;
};
#endif
