// 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_module.h"

CPDF_Document::CPDF_Document(CPDF_Parser* pParser) : CPDF_IndirectObjects(pParser)
{
    ASSERT(pParser != NULL);
    m_pRootDict = NULL;
    m_pInfoDict = NULL;
    m_bLinearized = FALSE;
    m_dwFirstPageNo = 0;
    m_dwFirstPageObjNum = 0;
    m_pDocPage = CPDF_ModuleMgr::Get()->GetPageModule()->CreateDocData(this);
    m_pDocRender = CPDF_ModuleMgr::Get()->GetRenderModule()->CreateDocData(this);
}
CPDF_DocPageData* CPDF_Document::GetValidatePageData()
{
    if (m_pDocPage) {
        return m_pDocPage;
    }
    m_pDocPage = CPDF_ModuleMgr::Get()->GetPageModule()->CreateDocData(this);
    return m_pDocPage;
}
CPDF_DocRenderData* CPDF_Document::GetValidateRenderData()
{
    if (m_pDocRender) {
        return m_pDocRender;
    }
    m_pDocRender = CPDF_ModuleMgr::Get()->GetRenderModule()->CreateDocData(this);
    return m_pDocRender;
}
void CPDF_Document::LoadDoc()
{
    m_LastObjNum = m_pParser->GetLastObjNum();
    CPDF_Object* pRootObj = GetIndirectObject(m_pParser->GetRootObjNum());
    if (pRootObj == NULL) {
        return;
    }
    m_pRootDict = pRootObj->GetDict();
    if (m_pRootDict == NULL) {
        return;
    }
    CPDF_Object* pInfoObj = GetIndirectObject(m_pParser->GetInfoObjNum());
    if (pInfoObj) {
        m_pInfoDict = pInfoObj->GetDict();
    }
    CPDF_Array* pIDArray = m_pParser->GetIDArray();
    if (pIDArray) {
        m_ID1 = pIDArray->GetString(0);
        m_ID2 = pIDArray->GetString(1);
    }
    m_PageList.SetSize(_GetPageCount());
}
void CPDF_Document::LoadAsynDoc(CPDF_Dictionary *pLinearized)
{
    m_bLinearized = TRUE;
    m_LastObjNum = m_pParser->GetLastObjNum();
    CPDF_Object* indirectObj = GetIndirectObject(m_pParser->GetRootObjNum());
    m_pRootDict = indirectObj ? indirectObj->GetDict() : NULL;
    if (m_pRootDict == NULL) {
        return;
    }
    indirectObj = GetIndirectObject(m_pParser->GetInfoObjNum());
    m_pInfoDict = indirectObj ? indirectObj->GetDict() : NULL;
    CPDF_Array* pIDArray = m_pParser->GetIDArray();
    if (pIDArray) {
        m_ID1 = pIDArray->GetString(0);
        m_ID2 = pIDArray->GetString(1);
    }
    FX_DWORD dwPageCount = 0;
    CPDF_Object *pCount = pLinearized->GetElement(FX_BSTRC("N"));
    if (pCount && pCount->GetType() == PDFOBJ_NUMBER) {
        dwPageCount = pCount->GetInteger();
    }
    m_PageList.SetSize(dwPageCount);
    CPDF_Object *pNo = pLinearized->GetElement(FX_BSTRC("P"));
    if (pNo && pNo->GetType() == PDFOBJ_NUMBER) {
        m_dwFirstPageNo = pNo->GetInteger();
    }
    CPDF_Object *pObjNum = pLinearized->GetElement(FX_BSTRC("O"));
    if (pObjNum && pObjNum->GetType() == PDFOBJ_NUMBER) {
        m_dwFirstPageObjNum = pObjNum->GetInteger();
    }
}
void CPDF_Document::LoadPages()
{
    m_PageList.SetSize(_GetPageCount());
}
extern void FPDF_TTFaceMapper_ReleaseDoc(CPDF_Document*);
CPDF_Document::~CPDF_Document()
{
    if (m_pDocPage) {
        CPDF_ModuleMgr::Get()->GetPageModule()->ReleaseDoc(this);
        CPDF_ModuleMgr::Get()->GetPageModule()->ClearStockFont(this);
    }
    if (m_pDocRender) {
        CPDF_ModuleMgr::Get()->GetRenderModule()->DestroyDocData(m_pDocRender);
    }
}
#define		FX_MAX_PAGE_LEVEL			1024
CPDF_Dictionary* CPDF_Document::_FindPDFPage(CPDF_Dictionary* pPages, int iPage, int nPagesToGo, int level)
{
    CPDF_Array* pKidList = pPages->GetArray(FX_BSTRC("Kids"));
    if (pKidList == NULL) {
        if (nPagesToGo == 0) {
            return pPages;
        }
        return NULL;
    }
    if (level >= FX_MAX_PAGE_LEVEL) {
        return NULL;
    }
    int nKids = pKidList->GetCount();
    for (int i = 0; i < nKids; i ++) {
        CPDF_Dictionary* pKid = pKidList->GetDict(i);
        if (pKid == NULL) {
            nPagesToGo --;
            continue;
        }
        if (pKid == pPages) {
            continue;
        }
        if (!pKid->KeyExist(FX_BSTRC("Kids"))) {
            if (nPagesToGo == 0) {
                return pKid;
            }
            m_PageList.SetAt(iPage - nPagesToGo, pKid->GetObjNum());
            nPagesToGo --;
        } else {
            int nPages = pKid->GetInteger(FX_BSTRC("Count"));
            if (nPagesToGo < nPages) {
                return _FindPDFPage(pKid, iPage, nPagesToGo, level + 1);
            }
            nPagesToGo -= nPages;
        }
    }
    return NULL;
}
CPDF_Dictionary* CPDF_Document::GetPage(int iPage)
{
    if (iPage < 0 || iPage >= m_PageList.GetSize()) {
        return NULL;
    }
    if (m_bLinearized && (iPage == (int)m_dwFirstPageNo)) {
        CPDF_Object* pObj = GetIndirectObject(m_dwFirstPageObjNum);
        if (pObj && pObj->GetType() == PDFOBJ_DICTIONARY) {
            return (CPDF_Dictionary*)pObj;
        }
    }
    int objnum = m_PageList.GetAt(iPage);
    if (objnum) {
        CPDF_Object* pObj = GetIndirectObject(objnum);
        ASSERT(pObj->GetType() == PDFOBJ_DICTIONARY);
        return (CPDF_Dictionary*)pObj;
    }
    CPDF_Dictionary* pRoot = GetRoot();
    if (pRoot == NULL) {
        return NULL;
    }
    CPDF_Dictionary* pPages = pRoot->GetDict(FX_BSTRC("Pages"));
    if (pPages == NULL) {
        return NULL;
    }
    CPDF_Dictionary* pPage = _FindPDFPage(pPages, iPage, iPage, 0);
    if (pPage == NULL) {
        return NULL;
    }
    m_PageList.SetAt(iPage, pPage->GetObjNum());
    return pPage;
}
int CPDF_Document::_FindPageIndex(CPDF_Dictionary* pNode, FX_DWORD& skip_count, FX_DWORD objnum, int& index, int level)
{
    if (pNode->KeyExist(FX_BSTRC("Kids"))) {
        CPDF_Array* pKidList = pNode->GetArray(FX_BSTRC("Kids"));
        if (pKidList == NULL) {
            return -1;
        }
        if (level >= FX_MAX_PAGE_LEVEL) {
            return -1;
        }
        FX_DWORD count = pNode->GetInteger(FX_BSTRC("Count"));
        if (count <= skip_count) {
            skip_count -= count;
            index += count;
            return -1;
        }
        if (count && count == pKidList->GetCount()) {
            for (FX_DWORD i = 0; i < count; i ++) {
                CPDF_Object* pKid = pKidList->GetElement(i);
                if (pKid && pKid->GetType() == PDFOBJ_REFERENCE) {
                    if (((CPDF_Reference*) pKid)->GetRefObjNum() == objnum) {
                        m_PageList.SetAt(index + i, objnum);
                        return index + i;
                    }
                }
            }
        }
        for (FX_DWORD i = 0; i < pKidList->GetCount(); i ++) {
            CPDF_Dictionary* pKid = pKidList->GetDict(i);
            if (pKid == NULL) {
                continue;
            }
            if (pKid == pNode) {
                continue;
            }
            int found_index = _FindPageIndex(pKid, skip_count, objnum, index, level + 1);
            if (found_index >= 0) {
                return found_index;
            }
        }
    } else {
        if (objnum == pNode->GetObjNum()) {
            return index;
        }
        if (skip_count) {
            skip_count--;
        }
        index ++;
    }
    return -1;
}
int CPDF_Document::GetPageIndex(FX_DWORD objnum)
{
    FX_DWORD nPages = m_PageList.GetSize();
    FX_DWORD skip_count = 0;
    FX_BOOL bSkipped = FALSE;
    for (FX_DWORD i = 0; i < nPages; i ++) {
        FX_DWORD objnum1 = m_PageList.GetAt(i);
        if (objnum1 == objnum) {
            return i;
        }
        if (!bSkipped && objnum1 == 0) {
            skip_count = i;
            bSkipped = TRUE;
        }
    }
    CPDF_Dictionary* pRoot = GetRoot();
    if (pRoot == NULL) {
        return -1;
    }
    CPDF_Dictionary* pPages = pRoot->GetDict(FX_BSTRC("Pages"));
    if (pPages == NULL) {
        return -1;
    }
    int index = 0;
    return _FindPageIndex(pPages, skip_count, objnum, index);
}
int CPDF_Document::GetPageCount() const
{
    return m_PageList.GetSize();
}
static int _CountPages(CPDF_Dictionary* pPages, int level)
{
    if (level > 128) {
        return 0;
    }
    int count = pPages->GetInteger(FX_BSTRC("Count"));
    if (count > 0 && count < FPDF_PAGE_MAX_NUM) {
        return count;
    }
    CPDF_Array* pKidList = pPages->GetArray(FX_BSTRC("Kids"));
    if (pKidList == NULL) {
        return 0;
    }
    count = 0;
    for (FX_DWORD i = 0; i < pKidList->GetCount(); i ++) {
        CPDF_Dictionary* pKid = pKidList->GetDict(i);
        if (pKid == NULL) {
            continue;
        }
        if (!pKid->KeyExist(FX_BSTRC("Kids"))) {
            count ++;
        } else {
            count += _CountPages(pKid, level + 1);
        }
    }
    pPages->SetAtInteger(FX_BSTRC("Count"), count);
    return count;
}
int CPDF_Document::_GetPageCount() const
{
    CPDF_Dictionary* pRoot = GetRoot();
    if (pRoot == NULL) {
        return 0;
    }
    CPDF_Dictionary* pPages = pRoot->GetDict(FX_BSTRC("Pages"));
    if (pPages == NULL) {
        return 0;
    }
    if (!pPages->KeyExist(FX_BSTRC("Kids"))) {
        return 1;
    }
    return _CountPages(pPages, 0);
}
FX_BOOL CPDF_Document::IsContentUsedElsewhere(FX_DWORD objnum, CPDF_Dictionary* pThisPageDict)
{
    for (int i = 0; i < m_PageList.GetSize(); i ++) {
        CPDF_Dictionary* pPageDict = GetPage(i);
        if (pPageDict == pThisPageDict) {
            continue;
        }
        CPDF_Object* pContents = pPageDict ? pPageDict->GetElement(FX_BSTRC("Contents")) : NULL;
        if (pContents == NULL) {
            continue;
        }
        if (pContents->GetDirectType() == PDFOBJ_ARRAY) {
            CPDF_Array* pArray = (CPDF_Array*)pContents->GetDirect();
            for (FX_DWORD j = 0; j < pArray->GetCount(); j ++) {
                CPDF_Object* pRef = pArray->GetElement(j);
                if (pRef == NULL || pRef->GetType() != PDFOBJ_REFERENCE) {
                    continue;
                }
                if (((CPDF_Reference*) pRef)->GetRefObjNum() == objnum) {
                    return TRUE;
                }
            }
        } else if (pContents->GetObjNum() == objnum) {
            return TRUE;
        }
    }
    return FALSE;
}
FX_DWORD CPDF_Document::GetUserPermissions(FX_BOOL bCheckRevision) const
{
    if (m_pParser == NULL) {
        return (FX_DWORD) - 1;
    }
    return m_pParser->GetPermissions(bCheckRevision);
}
FX_BOOL CPDF_Document::IsOwner() const
{
    if (m_pParser == NULL) {
        return TRUE;
    }
    return m_pParser->IsOwner();
}
FX_BOOL CPDF_Document::IsFormStream(FX_DWORD objnum, FX_BOOL& bForm) const
{
    {
        CPDF_Object* pObj;
        if (m_IndirectObjs.Lookup((void*)(uintptr_t)objnum, (void*&)pObj)) {
            bForm = pObj->GetType() == PDFOBJ_STREAM &&
                    ((CPDF_Stream*)pObj)->GetDict()->GetString(FX_BSTRC("Subtype")) == FX_BSTRC("Form");
            return TRUE;
        }
    }
    if (m_pParser == NULL) {
        bForm = FALSE;
        return TRUE;
    }
    return m_pParser->IsFormStream(objnum, bForm);
}
void CPDF_Document::ClearPageData()
{
    if (m_pDocPage) {
        CPDF_ModuleMgr::Get()->GetPageModule()->ClearDoc(this);
    }
}
void CPDF_Document::ClearRenderData()
{
    if (m_pDocRender) {
        CPDF_ModuleMgr::Get()->GetRenderModule()->ClearDocData(m_pDocRender);
    }
}
