// 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());
}
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 nullptr;

  if (m_bLinearized && (iPage == (int)m_dwFirstPageNo)) {
    CPDF_Object* pObj = GetIndirectObject(m_dwFirstPageObjNum);
    if (pObj && pObj->GetType() == PDFOBJ_DICTIONARY) {
      return static_cast<CPDF_Dictionary*>(pObj);
    }
  }

  int objnum = m_PageList.GetAt(iPage);
  if (objnum) {
    CPDF_Object* pObj = GetIndirectObject(objnum);
    if (pObj && pObj->GetType() == PDFOBJ_DICTIONARY) {
      return static_cast<CPDF_Dictionary*>(pObj);
    }
  }

  CPDF_Dictionary* pRoot = GetRoot();
  if (!pRoot)
    return nullptr;

  CPDF_Dictionary* pPages = pRoot->GetDict(FX_BSTRC("Pages"));
  if (!pPages)
    return nullptr;

  CPDF_Dictionary* pPage = _FindPDFPage(pPages, iPage, iPage, 0);
  if (!pPage)
    return nullptr;

  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);
  }
}
