// 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
