// 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

#include "../../include/fpdfapi/fpdf_parser.h"
#include "../../include/fpdfapi/fpdf_page.h"
#include "../../include/fpdfdoc/fpdf_tagged.h"
#include "tagged_int.h"
const int nMaxRecursion = 32;
static FX_BOOL IsTagged(const CPDF_Document* pDoc)
{
    CPDF_Dictionary* pCatalog = pDoc->GetRoot();
    CPDF_Dictionary* pMarkInfo = pCatalog->GetDict(FX_BSTRC("MarkInfo"));
    return pMarkInfo != NULL && pMarkInfo->GetInteger(FX_BSTRC("Marked"));
}
CPDF_StructTree* CPDF_StructTree::LoadPage(const CPDF_Document* pDoc, const CPDF_Dictionary* pPageDict)
{
    if (!IsTagged(pDoc)) {
        return NULL;
    }
    CPDF_StructTreeImpl* pTree = FX_NEW CPDF_StructTreeImpl(pDoc);
    if (pTree == NULL) {
        return NULL;
    }
    pTree->LoadPageTree(pPageDict);
    return pTree;
}
CPDF_StructTree* CPDF_StructTree::LoadDoc(const CPDF_Document* pDoc)
{
    if (!IsTagged(pDoc)) {
        return NULL;
    }
    CPDF_StructTreeImpl* pTree = FX_NEW CPDF_StructTreeImpl(pDoc);
    if (pTree == NULL) {
        return NULL;
    }
    pTree->LoadDocTree();
    return pTree;
}
CPDF_StructTreeImpl::CPDF_StructTreeImpl(const CPDF_Document* pDoc)
{
    CPDF_Dictionary* pCatalog = pDoc->GetRoot();
    m_pTreeRoot = pCatalog->GetDict(FX_BSTRC("StructTreeRoot"));
    if (m_pTreeRoot == NULL) {
        return;
    }
    m_pRoleMap = m_pTreeRoot->GetDict(FX_BSTRC("RoleMap"));
}
CPDF_StructTreeImpl::~CPDF_StructTreeImpl()
{
    for (int i = 0; i < m_Kids.GetSize(); i ++)
        if (m_Kids[i]) {
            m_Kids[i]->Release();
        }
}
void CPDF_StructTreeImpl::LoadDocTree()
{
    m_pPage = NULL;
    if (m_pTreeRoot == NULL) {
        return;
    }
    CPDF_Object* pKids = m_pTreeRoot->GetElementValue(FX_BSTRC("K"));
    if (pKids == NULL) {
        return;
    }
    if (pKids->GetType() == PDFOBJ_DICTIONARY) {
        CPDF_StructElementImpl* pStructElementImpl = FX_NEW CPDF_StructElementImpl(this, NULL, (CPDF_Dictionary*)pKids);
        if (pStructElementImpl == NULL) {
            return;
        }
        m_Kids.Add(pStructElementImpl);
        return;
    }
    if (pKids->GetType() != PDFOBJ_ARRAY) {
        return;
    }
    CPDF_Array* pArray = (CPDF_Array*)pKids;
    for (FX_DWORD i = 0; i < pArray->GetCount(); i ++) {
        CPDF_Dictionary* pKid = pArray->GetDict(i);
        CPDF_StructElementImpl* pStructElementImpl = FX_NEW CPDF_StructElementImpl(this, NULL, pKid);
        if (pStructElementImpl == NULL) {
            return;
        }
        m_Kids.Add(pStructElementImpl);
    }
}
void CPDF_StructTreeImpl::LoadPageTree(const CPDF_Dictionary* pPageDict)
{
    m_pPage = pPageDict;
    if (m_pTreeRoot == NULL) {
        return;
    }
    CPDF_Object* pKids = m_pTreeRoot->GetElementValue(FX_BSTRC("K"));
    if (pKids == NULL) {
        return;
    }
    FX_DWORD dwKids = 0;
    if (pKids->GetType() == PDFOBJ_DICTIONARY) {
        dwKids = 1;
    } else if (pKids->GetType() == PDFOBJ_ARRAY) {
        dwKids = ((CPDF_Array*)pKids)->GetCount();
    } else {
        return;
    }
    FX_DWORD i;
    m_Kids.SetSize(dwKids);
    for (i = 0; i < dwKids; i ++) {
        m_Kids[i] = NULL;
    }
    CFX_MapPtrToPtr element_map;
    CPDF_Dictionary* pParentTree = m_pTreeRoot->GetDict(FX_BSTRC("ParentTree"));
    if (pParentTree == NULL) {
        return;
    }
    CPDF_NumberTree parent_tree(pParentTree);
    int parents_id = pPageDict->GetInteger(FX_BSTRC("StructParents"), -1);
    if (parents_id >= 0) {
        CPDF_Object* pParents = parent_tree.LookupValue(parents_id);
        if (pParents == NULL || pParents->GetType() != PDFOBJ_ARRAY) {
            return;
        }
        CPDF_Array* pParentArray = (CPDF_Array*)pParents;
        for (i = 0; i < pParentArray->GetCount(); i ++) {
            CPDF_Dictionary* pParent = pParentArray->GetDict(i);
            if (pParent == NULL) {
                continue;
            }
            AddPageNode(pParent, element_map);
        }
    }
}
CPDF_StructElementImpl* CPDF_StructTreeImpl::AddPageNode(CPDF_Dictionary* pDict, CFX_MapPtrToPtr& map, int nLevel)
{
    if (nLevel > nMaxRecursion) {
        return NULL;
    }
    CPDF_StructElementImpl* pElement = NULL;
    if (map.Lookup(pDict, (FX_LPVOID&)pElement)) {
        return pElement;
    }
    pElement = FX_NEW CPDF_StructElementImpl(this, NULL, pDict);
    if (pElement == NULL) {
        return NULL;
    }
    map.SetAt(pDict, pElement);
    CPDF_Dictionary* pParent = pDict->GetDict(FX_BSTRC("P"));
    if (pParent == NULL || pParent->GetString(FX_BSTRC("Type")) == FX_BSTRC("StructTreeRoot")) {
        if (!AddTopLevelNode(pDict, pElement)) {
            pElement->Release();
            map.RemoveKey(pDict);
        }
    } else {
        CPDF_StructElementImpl* pParentElement = AddPageNode(pParent, map, nLevel + 1);
        FX_BOOL bSave = FALSE;
        for (int i = 0; i < pParentElement->m_Kids.GetSize(); i ++) {
            if (pParentElement->m_Kids[i].m_Type != CPDF_StructKid::Element) {
                continue;
            }
            if (pParentElement->m_Kids[i].m_Element.m_pDict != pDict) {
                continue;
            }
            pParentElement->m_Kids[i].m_Element.m_pElement = pElement->Retain();
            bSave = TRUE;
        }
        if (!bSave) {
            pElement->Release();
            map.RemoveKey(pDict);
        }
    }
    return pElement;
}
FX_BOOL CPDF_StructTreeImpl::AddTopLevelNode(CPDF_Dictionary* pDict, CPDF_StructElementImpl* pElement)
{
    CPDF_Object *pObj = m_pTreeRoot->GetElementValue(FX_BSTRC("K"));
    if (!pObj) {
        return FALSE;
    }
    if (pObj->GetType() == PDFOBJ_DICTIONARY) {
        if (pObj->GetObjNum() == pDict->GetObjNum()) {
            if (m_Kids[0]) {
                m_Kids[0]->Release();
            }
            m_Kids[0] = pElement->Retain();
        } else {
            return FALSE;
        }
    }
    if (pObj->GetType() == PDFOBJ_ARRAY) {
        CPDF_Array* pTopKids = (CPDF_Array*)pObj;
        FX_DWORD i;
        FX_BOOL bSave = FALSE;
        for (i = 0; i < pTopKids->GetCount(); i ++) {
            CPDF_Reference* pKidRef = (CPDF_Reference*)pTopKids->GetElement(i);
            if (pKidRef->GetType() != PDFOBJ_REFERENCE || pKidRef->GetRefObjNum() != pDict->GetObjNum()) {
                continue;
            }
            if (m_Kids[i]) {
                m_Kids[i]->Release();
            }
            m_Kids[i] = pElement->Retain();
            bSave = TRUE;
        }
        if (!bSave) {
            return FALSE;
        }
    }
    return TRUE;
}
CPDF_StructElementImpl::CPDF_StructElementImpl(CPDF_StructTreeImpl* pTree, CPDF_StructElementImpl* pParent, CPDF_Dictionary* pDict)
    : m_RefCount(0)
{
    m_pTree = pTree;
    m_pDict = pDict;
    m_Type = pDict->GetString(FX_BSTRC("S"));
    CFX_ByteString mapped = pTree->m_pRoleMap->GetString(m_Type);
    if (!mapped.IsEmpty()) {
        m_Type = mapped;
    }
    m_pParent = pParent;
    LoadKids(pDict);
}
CPDF_StructElementImpl::~CPDF_StructElementImpl()
{
    for (int i = 0; i < m_Kids.GetSize(); i ++) {
        if (m_Kids[i].m_Type == CPDF_StructKid::Element && m_Kids[i].m_Element.m_pElement) {
            ((CPDF_StructElementImpl*)m_Kids[i].m_Element.m_pElement)->Release();
        }
    }
}
CPDF_StructElementImpl* CPDF_StructElementImpl::Retain()
{
    m_RefCount++;
    return this;
}
void CPDF_StructElementImpl::Release()
{
    if(--m_RefCount < 1) {
        delete this;
    }
}
void CPDF_StructElementImpl::LoadKids(CPDF_Dictionary* pDict)
{
    CPDF_Object* pObj = pDict->GetElement(FX_BSTRC("Pg"));
    FX_DWORD PageObjNum = 0;
    if (pObj && pObj->GetType() == PDFOBJ_REFERENCE) {
        PageObjNum = ((CPDF_Reference*)pObj)->GetRefObjNum();
    }
    CPDF_Object* pKids = pDict->GetElementValue(FX_BSTRC("K"));
    if (pKids == NULL) {
        return;
    }
    if (pKids->GetType() == PDFOBJ_ARRAY) {
        CPDF_Array* pArray = (CPDF_Array*)pKids;
        m_Kids.SetSize(pArray->GetCount());
        for (FX_DWORD i = 0; i < pArray->GetCount(); i ++) {
            CPDF_Object* pKid = pArray->GetElementValue(i);
            LoadKid(PageObjNum, pKid, &m_Kids[i]);
        }
    } else {
        m_Kids.SetSize(1);
        LoadKid(PageObjNum, pKids, &m_Kids[0]);
    }
}
void CPDF_StructElementImpl::LoadKid(FX_DWORD PageObjNum, CPDF_Object* pKidObj, CPDF_StructKid* pKid)
{
    pKid->m_Type = CPDF_StructKid::Invalid;
    if (pKidObj == NULL) {
        return;
    }
    if (pKidObj->GetType() == PDFOBJ_NUMBER) {
        if (m_pTree->m_pPage && m_pTree->m_pPage->GetObjNum() != PageObjNum) {
            return;
        }
        pKid->m_Type = CPDF_StructKid::PageContent;
        pKid->m_PageContent.m_ContentId = pKidObj->GetInteger();
        pKid->m_PageContent.m_PageObjNum = PageObjNum;
        return;
    }
    if (pKidObj->GetType() != PDFOBJ_DICTIONARY) {
        return;
    }
    CPDF_Dictionary* pKidDict = (CPDF_Dictionary*)pKidObj;
    CPDF_Object* pPageObj = pKidDict->GetElement(FX_BSTRC("Pg"));
    if (pPageObj && pPageObj->GetType() == PDFOBJ_REFERENCE) {
        PageObjNum = ((CPDF_Reference*)pPageObj)->GetRefObjNum();
    }
    CFX_ByteString type = pKidDict->GetString(FX_BSTRC("Type"));
    if (type == FX_BSTRC("MCR")) {
        if (m_pTree->m_pPage && m_pTree->m_pPage->GetObjNum() != PageObjNum) {
            return;
        }
        pKid->m_Type = CPDF_StructKid::StreamContent;
        CPDF_Object* pStreamObj = pKidDict->GetElement(FX_BSTRC("Stm"));
        if (pStreamObj && pStreamObj->GetType() == PDFOBJ_REFERENCE) {
            pKid->m_StreamContent.m_RefObjNum = ((CPDF_Reference*)pStreamObj)->GetRefObjNum();
        } else {
            pKid->m_StreamContent.m_RefObjNum = 0;
        }
        pKid->m_StreamContent.m_PageObjNum = PageObjNum;
        pKid->m_StreamContent.m_ContentId = pKidDict->GetInteger(FX_BSTRC("MCID"));
    } else if (type == FX_BSTRC("OBJR")) {
        if (m_pTree->m_pPage && m_pTree->m_pPage->GetObjNum() != PageObjNum) {
            return;
        }
        pKid->m_Type = CPDF_StructKid::Object;
        CPDF_Object* pObj = pKidDict->GetElement(FX_BSTRC("Obj"));
        if (pObj && pObj->GetType() == PDFOBJ_REFERENCE) {
            pKid->m_Object.m_RefObjNum = ((CPDF_Reference*)pObj)->GetRefObjNum();
        } else {
            pKid->m_Object.m_RefObjNum = 0;
        }
        pKid->m_Object.m_PageObjNum = PageObjNum;
    } else {
        pKid->m_Type = CPDF_StructKid::Element;
        pKid->m_Element.m_pDict = pKidDict;
        if (m_pTree->m_pPage == NULL) {
            pKid->m_Element.m_pElement = FX_NEW CPDF_StructElementImpl(m_pTree, this, pKidDict);
        } else {
            pKid->m_Element.m_pElement = NULL;
        }
    }
}
static CPDF_Dictionary* FindAttrDict(CPDF_Object* pAttrs, FX_BSTR owner, FX_FLOAT nLevel = 0.0F)
{
    if (nLevel > nMaxRecursion) {
        return NULL;
    }
    if (pAttrs == NULL) {
        return NULL;
    }
    CPDF_Dictionary* pDict = NULL;
    if (pAttrs->GetType() == PDFOBJ_DICTIONARY) {
        pDict = (CPDF_Dictionary*)pAttrs;
    } else if (pAttrs->GetType() == PDFOBJ_STREAM) {
        pDict = ((CPDF_Stream*)pAttrs)->GetDict();
    } else if (pAttrs->GetType() == PDFOBJ_ARRAY) {
        CPDF_Array* pArray = (CPDF_Array*)pAttrs;
        for (FX_DWORD i = 0; i < pArray->GetCount(); i ++) {
            CPDF_Object* pElement = pArray->GetElementValue(i);
            pDict = FindAttrDict(pElement, owner, nLevel + 1);
            if (pDict) {
                return pDict;
            }
        }
    }
    if (pDict && pDict->GetString(FX_BSTRC("O")) == owner) {
        return pDict;
    }
    return NULL;
}
CPDF_Object* CPDF_StructElementImpl::GetAttr(FX_BSTR owner, FX_BSTR name, FX_BOOL bInheritable, FX_FLOAT fLevel)
{
    if (fLevel > nMaxRecursion) {
        return NULL;
    }
    if (bInheritable) {
        CPDF_Object* pAttr = GetAttr(owner, name, FALSE);
        if (pAttr) {
            return pAttr;
        }
        if (m_pParent == NULL) {
            return NULL;
        }
        return m_pParent->GetAttr(owner, name, TRUE, fLevel + 1);
    }
    CPDF_Object* pA = m_pDict->GetElementValue(FX_BSTRC("A"));
    if (pA) {
        CPDF_Dictionary* pAttrDict = FindAttrDict(pA, owner);
        if (pAttrDict) {
            CPDF_Object* pAttr = pAttrDict->GetElementValue(name);
            if (pAttr) {
                return pAttr;
            }
        }
    }
    CPDF_Object* pC = m_pDict->GetElementValue(FX_BSTRC("C"));
    if (pC == NULL) {
        return NULL;
    }
    CPDF_Dictionary* pClassMap = m_pTree->m_pTreeRoot->GetDict(FX_BSTRC("ClassMap"));
    if (pClassMap == NULL) {
        return NULL;
    }
    if (pC->GetType() == PDFOBJ_ARRAY) {
        CPDF_Array* pArray = (CPDF_Array*)pC;
        for (FX_DWORD i = 0; i < pArray->GetCount(); i ++) {
            CFX_ByteString class_name = pArray->GetString(i);
            CPDF_Dictionary* pClassDict = pClassMap->GetDict(class_name);
            if (pClassDict && pClassDict->GetString(FX_BSTRC("O")) == owner) {
                return pClassDict->GetElementValue(name);
            }
        }
        return NULL;
    }
    CFX_ByteString class_name = pC->GetString();
    CPDF_Dictionary* pClassDict = pClassMap->GetDict(class_name);
    if (pClassDict && pClassDict->GetString(FX_BSTRC("O")) == owner) {
        return pClassDict->GetElementValue(name);
    }
    return NULL;
}
CPDF_Object* CPDF_StructElementImpl::GetAttr(FX_BSTR owner, FX_BSTR name, FX_BOOL bInheritable, int subindex)
{
    CPDF_Object* pAttr = GetAttr(owner, name, bInheritable);
    if (pAttr == NULL || subindex == -1 || pAttr->GetType() != PDFOBJ_ARRAY) {
        return pAttr;
    }
    CPDF_Array* pArray = (CPDF_Array*)pAttr;
    if (subindex >= (int)pArray->GetCount()) {
        return pAttr;
    }
    return pArray->GetElementValue(subindex);
}
CFX_ByteString CPDF_StructElementImpl::GetName(FX_BSTR owner, FX_BSTR name, FX_BSTR default_value, FX_BOOL bInheritable, int subindex)
{
    CPDF_Object* pAttr = GetAttr(owner, name, bInheritable, subindex);
    if (pAttr == NULL || pAttr->GetType() != PDFOBJ_NAME) {
        return default_value;
    }
    return pAttr->GetString();
}
FX_ARGB	CPDF_StructElementImpl::GetColor(FX_BSTR owner, FX_BSTR name, FX_ARGB default_value, FX_BOOL bInheritable, int subindex)
{
    CPDF_Object* pAttr = GetAttr(owner, name, bInheritable, subindex);
    if (pAttr == NULL || pAttr->GetType() != PDFOBJ_ARRAY) {
        return default_value;
    }
    CPDF_Array* pArray = (CPDF_Array*)pAttr;
    return 0xff000000 | ((int)(pArray->GetNumber(0) * 255) << 16) | ((int)(pArray->GetNumber(1) * 255) << 8) | (int)(pArray->GetNumber(2) * 255);
}
FX_FLOAT CPDF_StructElementImpl::GetNumber(FX_BSTR owner, FX_BSTR name, FX_FLOAT default_value, FX_BOOL bInheritable, int subindex)
{
    CPDF_Object* pAttr = GetAttr(owner, name, bInheritable, subindex);
    if (pAttr == NULL || pAttr->GetType() != PDFOBJ_NUMBER) {
        return default_value;
    }
    return pAttr->GetNumber();
}
int	CPDF_StructElementImpl::GetInteger(FX_BSTR owner, FX_BSTR name, int default_value, FX_BOOL bInheritable, int subindex)
{
    CPDF_Object* pAttr = GetAttr(owner, name, bInheritable, subindex);
    if (pAttr == NULL || pAttr->GetType() != PDFOBJ_NUMBER) {
        return default_value;
    }
    return pAttr->GetInteger();
}
