// 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/fpdfdoc/fpdf_doc.h"
const int nMaxRecursion = 32;
int CPDF_Dest::GetPageIndex(CPDF_Document* pDoc) {
  if (m_pObj == NULL || m_pObj->GetType() != PDFOBJ_ARRAY) {
    return 0;
  }
  CPDF_Object* pPage = ((CPDF_Array*)m_pObj)->GetElementValue(0);
  if (pPage == NULL) {
    return 0;
  }
  if (pPage->GetType() == PDFOBJ_NUMBER) {
    return pPage->GetInteger();
  }
  if (pPage->GetType() != PDFOBJ_DICTIONARY) {
    return 0;
  }
  return pDoc->GetPageIndex(pPage->GetObjNum());
}
FX_DWORD CPDF_Dest::GetPageObjNum() {
  if (m_pObj == NULL || m_pObj->GetType() != PDFOBJ_ARRAY) {
    return 0;
  }
  CPDF_Object* pPage = ((CPDF_Array*)m_pObj)->GetElementValue(0);
  if (pPage == NULL) {
    return 0;
  }
  if (pPage->GetType() == PDFOBJ_NUMBER) {
    return pPage->GetInteger();
  }
  if (pPage->GetType() == PDFOBJ_DICTIONARY) {
    return pPage->GetObjNum();
  }
  return 0;
}
const FX_CHAR* g_sZoomModes[] = {"XYZ",  "Fit",   "FitH",  "FitV", "FitR",
                                 "FitB", "FitBH", "FitBV", ""};
int CPDF_Dest::GetZoomMode() {
  if (m_pObj == NULL || m_pObj->GetType() != PDFOBJ_ARRAY) {
    return 0;
  }
  CFX_ByteString mode;
  CPDF_Object* pObj = ((CPDF_Array*)m_pObj)->GetElementValue(1);
  mode = pObj ? pObj->GetString() : CFX_ByteString();
  int i = 0;
  while (g_sZoomModes[i][0] != '\0') {
    if (mode == g_sZoomModes[i]) {
      return i + 1;
    }
    i++;
  }
  return 0;
}
FX_FLOAT CPDF_Dest::GetParam(int index) {
  if (m_pObj == NULL || m_pObj->GetType() != PDFOBJ_ARRAY) {
    return 0;
  }
  return ((CPDF_Array*)m_pObj)->GetNumber(2 + index);
}
CFX_ByteString CPDF_Dest::GetRemoteName() {
  if (m_pObj == NULL) {
    return CFX_ByteString();
  }
  return m_pObj->GetString();
}
CPDF_NameTree::CPDF_NameTree(CPDF_Document* pDoc,
                             const CFX_ByteStringC& category) {
  if (pDoc->GetRoot() && pDoc->GetRoot()->GetDict(FX_BSTRC("Names")))
    m_pRoot = pDoc->GetRoot()->GetDict(FX_BSTRC("Names"))->GetDict(category);
  else
    m_pRoot = NULL;
}
static CPDF_Object* SearchNameNode(CPDF_Dictionary* pNode,
                                   const CFX_ByteString& csName,
                                   int& nIndex,
                                   CPDF_Array** ppFind,
                                   int nLevel = 0) {
  if (nLevel > nMaxRecursion) {
    return NULL;
  }
  CPDF_Array* pLimits = pNode->GetArray(FX_BSTRC("Limits"));
  if (pLimits != NULL) {
    CFX_ByteString csLeft = pLimits->GetString(0);
    CFX_ByteString csRight = pLimits->GetString(1);
    if (csLeft.Compare(csRight) > 0) {
      CFX_ByteString csTmp = csRight;
      csRight = csLeft;
      csLeft = csTmp;
    }
    if (csName.Compare(csLeft) < 0 || csName.Compare(csRight) > 0) {
      return NULL;
    }
  }
  CPDF_Array* pNames = pNode->GetArray(FX_BSTRC("Names"));
  if (pNames) {
    FX_DWORD dwCount = pNames->GetCount() / 2;
    for (FX_DWORD i = 0; i < dwCount; i++) {
      CFX_ByteString csValue = pNames->GetString(i * 2);
      int32_t iCompare = csValue.Compare(csName);
      if (iCompare <= 0) {
        if (ppFind != NULL) {
          *ppFind = pNames;
        }
        if (iCompare < 0) {
          continue;
        }
      } else {
        break;
      }
      nIndex += i;
      return pNames->GetElementValue(i * 2 + 1);
    }
    nIndex += dwCount;
    return NULL;
  }
  CPDF_Array* pKids = pNode->GetArray(FX_BSTRC("Kids"));
  if (pKids == NULL) {
    return NULL;
  }
  for (FX_DWORD i = 0; i < pKids->GetCount(); i++) {
    CPDF_Dictionary* pKid = pKids->GetDict(i);
    if (pKid == NULL) {
      continue;
    }
    CPDF_Object* pFound =
        SearchNameNode(pKid, csName, nIndex, ppFind, nLevel + 1);
    if (pFound) {
      return pFound;
    }
  }
  return NULL;
}
static CPDF_Object* SearchNameNode(CPDF_Dictionary* pNode,
                                   int nIndex,
                                   int& nCurIndex,
                                   CFX_ByteString& csName,
                                   CPDF_Array** ppFind,
                                   int nLevel = 0) {
  if (nLevel > nMaxRecursion) {
    return NULL;
  }
  CPDF_Array* pNames = pNode->GetArray(FX_BSTRC("Names"));
  if (pNames) {
    int nCount = pNames->GetCount() / 2;
    if (nIndex >= nCurIndex + nCount) {
      nCurIndex += nCount;
      return NULL;
    }
    if (ppFind != NULL) {
      *ppFind = pNames;
    }
    csName = pNames->GetString((nIndex - nCurIndex) * 2);
    return pNames->GetElementValue((nIndex - nCurIndex) * 2 + 1);
  }
  CPDF_Array* pKids = pNode->GetArray(FX_BSTRC("Kids"));
  if (pKids == NULL) {
    return NULL;
  }
  for (FX_DWORD i = 0; i < pKids->GetCount(); i++) {
    CPDF_Dictionary* pKid = pKids->GetDict(i);
    if (pKid == NULL) {
      continue;
    }
    CPDF_Object* pFound =
        SearchNameNode(pKid, nIndex, nCurIndex, csName, ppFind, nLevel + 1);
    if (pFound) {
      return pFound;
    }
  }
  return NULL;
}
static int CountNames(CPDF_Dictionary* pNode, int nLevel = 0) {
  if (nLevel > nMaxRecursion) {
    return 0;
  }
  CPDF_Array* pNames = pNode->GetArray(FX_BSTRC("Names"));
  if (pNames) {
    return pNames->GetCount() / 2;
  }
  CPDF_Array* pKids = pNode->GetArray(FX_BSTRC("Kids"));
  if (pKids == NULL) {
    return 0;
  }
  int nCount = 0;
  for (FX_DWORD i = 0; i < pKids->GetCount(); i++) {
    CPDF_Dictionary* pKid = pKids->GetDict(i);
    if (pKid == NULL) {
      continue;
    }
    nCount += CountNames(pKid, nLevel + 1);
  }
  return nCount;
}
int CPDF_NameTree::GetCount() const {
  if (m_pRoot == NULL) {
    return 0;
  }
  return ::CountNames(m_pRoot);
}
int CPDF_NameTree::GetIndex(const CFX_ByteString& csName) const {
  if (m_pRoot == NULL) {
    return -1;
  }
  int nIndex = 0;
  if (SearchNameNode(m_pRoot, csName, nIndex, NULL) == NULL) {
    return -1;
  }
  return nIndex;
}
CPDF_Object* CPDF_NameTree::LookupValue(int nIndex,
                                        CFX_ByteString& csName) const {
  if (m_pRoot == NULL) {
    return NULL;
  }
  int nCurIndex = 0;
  return SearchNameNode(m_pRoot, nIndex, nCurIndex, csName, NULL);
}
CPDF_Object* CPDF_NameTree::LookupValue(const CFX_ByteString& csName) const {
  if (m_pRoot == NULL) {
    return NULL;
  }
  int nIndex = 0;
  return SearchNameNode(m_pRoot, csName, nIndex, NULL);
}
CPDF_Array* CPDF_NameTree::LookupNamedDest(CPDF_Document* pDoc,
                                           const CFX_ByteStringC& sName) {
  CPDF_Object* pValue = LookupValue(sName);
  if (pValue == NULL) {
    CPDF_Dictionary* pDests = pDoc->GetRoot()->GetDict(FX_BSTRC("Dests"));
    if (pDests == NULL) {
      return NULL;
    }
    pValue = pDests->GetElementValue(sName);
  }
  if (pValue == NULL) {
    return NULL;
  }
  if (pValue->GetType() == PDFOBJ_ARRAY) {
    return (CPDF_Array*)pValue;
  }
  if (pValue->GetType() == PDFOBJ_DICTIONARY) {
    return ((CPDF_Dictionary*)pValue)->GetArray(FX_BSTRC("D"));
  }
  return NULL;
}
#if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_ || \
    _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_
static CFX_WideString ChangeSlashToPlatform(const FX_WCHAR* str) {
  CFX_WideString result;
  while (*str) {
    if (*str == '/') {
#if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_
      result += ':';
#else
      result += '\\';
#endif
    } else {
      result += *str;
    }
    str++;
  }
  return result;
}
static CFX_WideString ChangeSlashToPDF(const FX_WCHAR* str) {
  CFX_WideString result;
  while (*str) {
    if (*str == '\\' || *str == ':') {
      result += '/';
    } else {
      result += *str;
    }
    str++;
  }
  return result;
}
#endif
static CFX_WideString FILESPEC_DecodeFileName(const CFX_WideStringC& filepath) {
  if (filepath.GetLength() <= 1) {
    return CFX_WideString();
  }
#if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_
  if (filepath.Left(sizeof("/Mac") - 1) == CFX_WideStringC(L"/Mac")) {
    return ChangeSlashToPlatform(filepath.GetPtr() + 1);
  }
  return ChangeSlashToPlatform(filepath.GetPtr());
#elif _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_
  if (filepath.GetAt(0) != '/') {
    return ChangeSlashToPlatform(filepath.GetPtr());
  }
  if (filepath.GetAt(1) == '/') {
    return ChangeSlashToPlatform(filepath.GetPtr() + 1);
  }
  if (filepath.GetAt(2) == '/') {
    CFX_WideString result;
    result += filepath.GetAt(1);
    result += ':';
    result += ChangeSlashToPlatform(filepath.GetPtr() + 2);
    return result;
  }
  CFX_WideString result;
  result += '\\';
  result += ChangeSlashToPlatform(filepath.GetPtr());
  return result;
#else
  return filepath;
#endif
}
FX_BOOL CPDF_FileSpec::GetFileName(CFX_WideString& csFileName) const {
  if (m_pObj == NULL) {
    return FALSE;
  }
  if (m_pObj->GetType() == PDFOBJ_DICTIONARY) {
    CPDF_Dictionary* pDict = (CPDF_Dictionary*)m_pObj;
    csFileName = pDict->GetUnicodeText(FX_BSTRC("UF"));
    if (csFileName.IsEmpty()) {
      csFileName = CFX_WideString::FromLocal(pDict->GetString(FX_BSTRC("F")));
    }
    if (pDict->GetString(FX_BSTRC("FS")) == FX_BSTRC("URL")) {
      return TRUE;
    }
    if (csFileName.IsEmpty()) {
      if (pDict->KeyExist(FX_BSTRC("DOS"))) {
        csFileName =
            CFX_WideString::FromLocal(pDict->GetString(FX_BSTRC("DOS")));
      } else if (pDict->KeyExist(FX_BSTRC("Mac"))) {
        csFileName =
            CFX_WideString::FromLocal(pDict->GetString(FX_BSTRC("Mac")));
      } else if (pDict->KeyExist(FX_BSTRC("Unix"))) {
        csFileName =
            CFX_WideString::FromLocal(pDict->GetString(FX_BSTRC("Unix")));
      } else {
        return FALSE;
      }
    }
  } else {
    csFileName = CFX_WideString::FromLocal(m_pObj->GetString());
  }
  csFileName = FILESPEC_DecodeFileName(csFileName);
  return TRUE;
}
CPDF_FileSpec::CPDF_FileSpec() {
  m_pObj = CPDF_Dictionary::Create();
  if (m_pObj != NULL) {
    ((CPDF_Dictionary*)m_pObj)
        ->SetAtName(FX_BSTRC("Type"), FX_BSTRC("Filespec"));
  }
}
FX_BOOL CPDF_FileSpec::IsURL() const {
  if (m_pObj == NULL) {
    return FALSE;
  }
  if (m_pObj->GetType() != PDFOBJ_DICTIONARY) {
    return FALSE;
  }
  return ((CPDF_Dictionary*)m_pObj)->GetString(FX_BSTRC("FS")) ==
         FX_BSTRC("URL");
}
CFX_WideString FILESPEC_EncodeFileName(const CFX_WideStringC& filepath) {
  if (filepath.GetLength() <= 1) {
    return CFX_WideString();
  }
#if _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_
  if (filepath.GetAt(1) == ':') {
    CFX_WideString result;
    result = '/';
    result += filepath.GetAt(0);
    if (filepath.GetAt(2) != '\\') {
      result += '/';
    }
    result += ChangeSlashToPDF(filepath.GetPtr() + 2);
    return result;
  }
  if (filepath.GetAt(0) == '\\' && filepath.GetAt(1) == '\\') {
    return ChangeSlashToPDF(filepath.GetPtr() + 1);
  }
  if (filepath.GetAt(0) == '\\') {
    CFX_WideString result;
    result = '/';
    result += ChangeSlashToPDF(filepath.GetPtr());
    return result;
  }
  return ChangeSlashToPDF(filepath.GetPtr());
#elif _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_
  if (filepath.Left(sizeof("Mac") - 1) == FX_WSTRC(L"Mac")) {
    CFX_WideString result;
    result = '/';
    result += ChangeSlashToPDF(filepath.GetPtr());
    return result;
  }
  return ChangeSlashToPDF(filepath.GetPtr());
#else
  return filepath;
#endif
}
CPDF_Stream* CPDF_FileSpec::GetFileStream() const {
  if (m_pObj == NULL) {
    return NULL;
  }
  int32_t iType = m_pObj->GetType();
  if (iType == PDFOBJ_STREAM) {
    return (CPDF_Stream*)m_pObj;
  } else if (iType == PDFOBJ_DICTIONARY) {
    CPDF_Dictionary* pEF = ((CPDF_Dictionary*)m_pObj)->GetDict(FX_BSTRC("EF"));
    if (pEF == NULL) {
      return NULL;
    }
    return pEF->GetStream(FX_BSTRC("F"));
  }
  return NULL;
}
static void FPDFDOC_FILESPEC_SetFileName(CPDF_Object* pObj,
                                         const CFX_WideStringC& wsFileName,
                                         FX_BOOL bURL) {
  ASSERT(pObj != NULL);
  CFX_WideString wsStr;
  if (bURL) {
    wsStr = wsFileName;
  } else {
    wsStr = FILESPEC_EncodeFileName(wsFileName);
  }
  int32_t iType = pObj->GetType();
  if (iType == PDFOBJ_STRING) {
    pObj->SetString(CFX_ByteString::FromUnicode(wsStr));
  } else if (iType == PDFOBJ_DICTIONARY) {
    CPDF_Dictionary* pDict = (CPDF_Dictionary*)pObj;
    pDict->SetAtString(FX_BSTRC("F"), CFX_ByteString::FromUnicode(wsStr));
    pDict->SetAtString(FX_BSTRC("UF"), PDF_EncodeText(wsStr));
  }
}
void CPDF_FileSpec::SetFileName(const CFX_WideStringC& wsFileName,
                                FX_BOOL bURL) {
  ASSERT(m_pObj != NULL);
  if (m_pObj->GetType() == PDFOBJ_DICTIONARY && bURL) {
    ((CPDF_Dictionary*)m_pObj)->SetAtName(FX_BSTRC("FS"), "URL");
  }
  FPDFDOC_FILESPEC_SetFileName(m_pObj, wsFileName, bURL);
}
static CFX_WideString _MakeRoman(int num) {
  const int arabic[] = {1000, 900, 500, 400, 100, 90, 50, 40, 10, 9, 5, 4, 1};
  const CFX_WideString roman[] = {L"m",  L"cm", L"d",  L"cd", L"c",
                                  L"xc", L"l",  L"xl", L"x",  L"ix",
                                  L"v",  L"iv", L"i"};
  const int nMaxNum = 1000000;
  num %= nMaxNum;
  int i = 0;
  CFX_WideString wsRomanNumber;
  while (num > 0) {
    while (num >= arabic[i]) {
      num = num - arabic[i];
      wsRomanNumber += roman[i];
    }
    i = i + 1;
  }
  return wsRomanNumber;
}
static CFX_WideString _MakeLetters(int num) {
  if (num == 0) {
    return CFX_WideString();
  }
  CFX_WideString wsLetters;
  const int nMaxCount = 1000;
  const int nLetterCount = 26;
  num -= 1;
  int count = num / nLetterCount + 1;
  count %= nMaxCount;
  FX_WCHAR ch = L'a' + num % nLetterCount;
  for (int i = 0; i < count; i++) {
    wsLetters += ch;
  }
  return wsLetters;
}
static CFX_WideString _GetLabelNumPortion(int num,
                                          const CFX_ByteString& bsStyle) {
  CFX_WideString wsNumPortion;
  if (bsStyle.IsEmpty()) {
    return wsNumPortion;
  }
  if (bsStyle == "D") {
    wsNumPortion.Format(L"%d", num);
  } else if (bsStyle == "R") {
    wsNumPortion = _MakeRoman(num);
    wsNumPortion.MakeUpper();
  } else if (bsStyle == "r") {
    wsNumPortion = _MakeRoman(num);
  } else if (bsStyle == "A") {
    wsNumPortion = _MakeLetters(num);
    wsNumPortion.MakeUpper();
  } else if (bsStyle == "a") {
    wsNumPortion = _MakeLetters(num);
  }
  return wsNumPortion;
}
CFX_WideString CPDF_PageLabel::GetLabel(int nPage) const {
  CFX_WideString wsLabel;
  if (m_pDocument == NULL) {
    return wsLabel;
  }
  CPDF_Dictionary* pPDFRoot = m_pDocument->GetRoot();
  if (pPDFRoot == NULL) {
    return wsLabel;
  }
  CPDF_Dictionary* pLabels = pPDFRoot->GetDict(FX_BSTRC("PageLabels"));
  CPDF_NumberTree numberTree(pLabels);
  CPDF_Object* pValue = NULL;
  int n = nPage;
  while (n >= 0) {
    pValue = numberTree.LookupValue(n);
    if (pValue != NULL) {
      break;
    }
    n--;
  }
  if (pValue != NULL) {
    pValue = pValue->GetDirect();
    if (pValue->GetType() == PDFOBJ_DICTIONARY) {
      CPDF_Dictionary* pLabel = (CPDF_Dictionary*)pValue;
      if (pLabel->KeyExist(FX_BSTRC("P"))) {
        wsLabel += pLabel->GetUnicodeText(FX_BSTRC("P"));
      }
      CFX_ByteString bsNumberingStyle = pLabel->GetString(FX_BSTRC("S"), NULL);
      int nLabelNum = nPage - n + pLabel->GetInteger(FX_BSTRC("St"), 1);
      CFX_WideString wsNumPortion =
          _GetLabelNumPortion(nLabelNum, bsNumberingStyle);
      wsLabel += wsNumPortion;
      return wsLabel;
    }
  }
  wsLabel.Format(L"%d", nPage + 1);
  return wsLabel;
}
int32_t CPDF_PageLabel::GetPageByLabel(const CFX_ByteStringC& bsLabel) const {
  if (m_pDocument == NULL) {
    return -1;
  }
  CPDF_Dictionary* pPDFRoot = m_pDocument->GetRoot();
  if (pPDFRoot == NULL) {
    return -1;
  }
  int nPages = m_pDocument->GetPageCount();
  CFX_ByteString bsLbl;
  CFX_ByteString bsOrig = bsLabel;
  for (int i = 0; i < nPages; i++) {
    bsLbl = PDF_EncodeText(GetLabel(i));
    if (!bsLbl.Compare(bsOrig)) {
      return i;
    }
  }
  bsLbl = bsOrig;
  int nPage = FXSYS_atoi(bsLbl);
  if (nPage > 0 && nPage <= nPages) {
    return nPage;
  }
  return -1;
}
int32_t CPDF_PageLabel::GetPageByLabel(const CFX_WideStringC& wsLabel) const {
  CFX_ByteString bsLabel = PDF_EncodeText(wsLabel.GetPtr());
  return GetPageByLabel(bsLabel);
}
