// 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 "core/fpdfapi/fpdf_parser/include/cpdf_array.h"
#include "core/fpdfapi/fpdf_parser/include/cpdf_document.h"
#include "core/fpdfapi/fpdf_parser/include/fpdf_parser_decode.h"
#include "core/fpdfdoc/doc_utils.h"
#include "core/fpdfdoc/cpdf_pagelabel.h"
#include "core/fpdfdoc/include/cpdf_filespec.h"
#include "core/fpdfdoc/include/cpdf_nametree.h"
#include "core/fpdfdoc/include/ipdf_formnotify.h"

namespace {

const int nMaxRecursion = 32;
const FX_CHAR* const g_sZoomModes[] = {"XYZ",  "Fit",   "FitH",  "FitV", "FitR",
                                       "FitB", "FitBH", "FitBV", nullptr};

}  // namespace

int CPDF_Dest::GetPageIndex(CPDF_Document* pDoc) {
  CPDF_Array* pArray = ToArray(m_pObj);
  if (!pArray)
    return 0;

  CPDF_Object* pPage = pArray->GetDirectObjectAt(0);
  if (!pPage)
    return 0;
  if (pPage->IsNumber())
    return pPage->GetInteger();
  if (!pPage->IsDictionary())
    return 0;
  return pDoc->GetPageIndex(pPage->GetObjNum());
}

uint32_t CPDF_Dest::GetPageObjNum() {
  CPDF_Array* pArray = ToArray(m_pObj);
  if (!pArray)
    return 0;

  CPDF_Object* pPage = pArray->GetDirectObjectAt(0);
  if (!pPage)
    return 0;
  if (pPage->IsNumber())
    return pPage->GetInteger();
  if (pPage->IsDictionary())
    return pPage->GetObjNum();
  return 0;
}

int CPDF_Dest::GetZoomMode() {
  CPDF_Array* pArray = ToArray(m_pObj);
  if (!pArray)
    return 0;

  CPDF_Object* pObj = pArray->GetDirectObjectAt(1);
  if (!pObj)
    return 0;

  CFX_ByteString mode = pObj->GetString();
  for (int i = 0; g_sZoomModes[i]; ++i) {
    if (mode == g_sZoomModes[i])
      return i + 1;
  }

  return 0;
}

FX_FLOAT CPDF_Dest::GetParam(int index) {
  CPDF_Array* pArray = ToArray(m_pObj);
  return pArray ? pArray->GetNumberAt(2 + index) : 0;
}

CFX_ByteString CPDF_Dest::GetRemoteName() {
  return m_pObj ? m_pObj->GetString() : CFX_ByteString();
}

CPDF_NameTree::CPDF_NameTree(CPDF_Document* pDoc,
                             const CFX_ByteString& category)
    : m_pRoot(nullptr) {
  CPDF_Dictionary* pRoot = pDoc->GetRoot();
  if (!pRoot)
    return;

  CPDF_Dictionary* pNames = pRoot->GetDictBy("Names");
  if (!pNames)
    return;

  m_pRoot = pNames->GetDictBy(category);
}

static CPDF_Object* SearchNameNode(CPDF_Dictionary* pNode,
                                   const CFX_ByteString& csName,
                                   size_t& nIndex,
                                   CPDF_Array** ppFind,
                                   int nLevel = 0) {
  if (nLevel > nMaxRecursion) {
    return nullptr;
  }
  CPDF_Array* pLimits = pNode->GetArrayBy("Limits");
  if (pLimits) {
    CFX_ByteString csLeft = pLimits->GetStringAt(0);
    CFX_ByteString csRight = pLimits->GetStringAt(1);
    if (csLeft.Compare(csRight.AsStringC()) > 0) {
      CFX_ByteString csTmp = csRight;
      csRight = csLeft;
      csLeft = csTmp;
    }
    if (csName.Compare(csLeft.AsStringC()) < 0 ||
        csName.Compare(csRight.AsStringC()) > 0) {
      return nullptr;
    }
  }
  CPDF_Array* pNames = pNode->GetArrayBy("Names");
  if (pNames) {
    size_t dwCount = pNames->GetCount() / 2;
    for (size_t i = 0; i < dwCount; i++) {
      CFX_ByteString csValue = pNames->GetStringAt(i * 2);
      int32_t iCompare = csValue.Compare(csName.AsStringC());
      if (iCompare <= 0) {
        if (ppFind) {
          *ppFind = pNames;
        }
        if (iCompare < 0) {
          continue;
        }
      } else {
        break;
      }
      nIndex += i;
      return pNames->GetDirectObjectAt(i * 2 + 1);
    }
    nIndex += dwCount;
    return nullptr;
  }
  CPDF_Array* pKids = pNode->GetArrayBy("Kids");
  if (!pKids) {
    return nullptr;
  }
  for (size_t i = 0; i < pKids->GetCount(); i++) {
    CPDF_Dictionary* pKid = pKids->GetDictAt(i);
    if (!pKid) {
      continue;
    }
    CPDF_Object* pFound =
        SearchNameNode(pKid, csName, nIndex, ppFind, nLevel + 1);
    if (pFound) {
      return pFound;
    }
  }
  return nullptr;
}

static CPDF_Object* SearchNameNode(CPDF_Dictionary* pNode,
                                   size_t nIndex,
                                   size_t& nCurIndex,
                                   CFX_ByteString& csName,
                                   CPDF_Array** ppFind,
                                   int nLevel = 0) {
  if (nLevel > nMaxRecursion)
    return nullptr;

  CPDF_Array* pNames = pNode->GetArrayBy("Names");
  if (pNames) {
    size_t nCount = pNames->GetCount() / 2;
    if (nIndex >= nCurIndex + nCount) {
      nCurIndex += nCount;
      return nullptr;
    }
    if (ppFind)
      *ppFind = pNames;
    csName = pNames->GetStringAt((nIndex - nCurIndex) * 2);
    return pNames->GetDirectObjectAt((nIndex - nCurIndex) * 2 + 1);
  }
  CPDF_Array* pKids = pNode->GetArrayBy("Kids");
  if (!pKids)
    return nullptr;
  for (size_t i = 0; i < pKids->GetCount(); i++) {
    CPDF_Dictionary* pKid = pKids->GetDictAt(i);
    if (!pKid)
      continue;
    CPDF_Object* pFound =
        SearchNameNode(pKid, nIndex, nCurIndex, csName, ppFind, nLevel + 1);
    if (pFound)
      return pFound;
  }
  return nullptr;
}

static size_t CountNames(CPDF_Dictionary* pNode, int nLevel = 0) {
  if (nLevel > nMaxRecursion) {
    return 0;
  }
  CPDF_Array* pNames = pNode->GetArrayBy("Names");
  if (pNames) {
    return pNames->GetCount() / 2;
  }
  CPDF_Array* pKids = pNode->GetArrayBy("Kids");
  if (!pKids) {
    return 0;
  }
  size_t nCount = 0;
  for (size_t i = 0; i < pKids->GetCount(); i++) {
    CPDF_Dictionary* pKid = pKids->GetDictAt(i);
    if (!pKid) {
      continue;
    }
    nCount += CountNames(pKid, nLevel + 1);
  }
  return nCount;
}

size_t CPDF_NameTree::GetCount() const {
  if (!m_pRoot) {
    return 0;
  }
  return ::CountNames(m_pRoot);
}

int CPDF_NameTree::GetIndex(const CFX_ByteString& csName) const {
  if (!m_pRoot) {
    return -1;
  }
  size_t nIndex = 0;
  if (!SearchNameNode(m_pRoot, csName, nIndex, nullptr)) {
    return -1;
  }
  return nIndex;
}

CPDF_Object* CPDF_NameTree::LookupValue(int nIndex,
                                        CFX_ByteString& csName) const {
  if (!m_pRoot) {
    return nullptr;
  }
  size_t nCurIndex = 0;
  return SearchNameNode(m_pRoot, nIndex, nCurIndex, csName, nullptr);
}

CPDF_Object* CPDF_NameTree::LookupValue(const CFX_ByteString& csName) const {
  if (!m_pRoot) {
    return nullptr;
  }
  size_t nIndex = 0;
  return SearchNameNode(m_pRoot, csName, nIndex, nullptr);
}

CPDF_Array* CPDF_NameTree::LookupNamedDest(CPDF_Document* pDoc,
                                           const CFX_ByteString& sName) {
  CPDF_Object* pValue = LookupValue(sName);
  if (!pValue) {
    CPDF_Dictionary* pDests = pDoc->GetRoot()->GetDictBy("Dests");
    if (!pDests)
      return nullptr;
    pValue = pDests->GetDirectObjectBy(sName);
  }
  if (!pValue)
    return nullptr;
  if (CPDF_Array* pArray = pValue->AsArray())
    return pArray;
  if (CPDF_Dictionary* pDict = pValue->AsDictionary())
    return pDict->GetArrayBy("D");
  return nullptr;
}

#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  // _FXM_PLATFORM_APPLE_ || _FXM_PLATFORM_WINDOWS_

CFX_WideString CPDF_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.c_str() + 1);
  return ChangeSlashToPlatform(filepath.c_str());
#elif _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_
  if (filepath.GetAt(0) != '/')
    return ChangeSlashToPlatform(filepath.c_str());
  if (filepath.GetAt(1) == '/')
    return ChangeSlashToPlatform(filepath.c_str() + 1);
  if (filepath.GetAt(2) == '/') {
    CFX_WideString result;
    result += filepath.GetAt(1);
    result += ':';
    result += ChangeSlashToPlatform(filepath.c_str() + 2);
    return result;
  }
  CFX_WideString result;
  result += '\\';
  result += ChangeSlashToPlatform(filepath.c_str());
  return result;
#else
  return CFX_WideString(filepath);
#endif
}

bool CPDF_FileSpec::GetFileName(CFX_WideString* csFileName) const {
  if (CPDF_Dictionary* pDict = m_pObj->AsDictionary()) {
    *csFileName = pDict->GetUnicodeTextBy("UF");
    if (csFileName->IsEmpty()) {
      *csFileName =
          CFX_WideString::FromLocal(pDict->GetStringBy("F").AsStringC());
    }
    if (pDict->GetStringBy("FS") == "URL")
      return true;
    if (csFileName->IsEmpty()) {
      if (pDict->KeyExist("DOS")) {
        *csFileName =
            CFX_WideString::FromLocal(pDict->GetStringBy("DOS").AsStringC());
      } else if (pDict->KeyExist("Mac")) {
        *csFileName =
            CFX_WideString::FromLocal(pDict->GetStringBy("Mac").AsStringC());
      } else if (pDict->KeyExist("Unix")) {
        *csFileName =
            CFX_WideString::FromLocal(pDict->GetStringBy("Unix").AsStringC());
      } else {
        return false;
      }
    }
  } else if (m_pObj->IsString()) {
    *csFileName = CFX_WideString::FromLocal(m_pObj->GetString().AsStringC());
  } else {
    return false;
  }
  *csFileName = DecodeFileName(csFileName->AsStringC());
  return true;
}

CPDF_FileSpec::CPDF_FileSpec() {
  m_pObj = new CPDF_Dictionary;
  m_pObj->AsDictionary()->SetAtName("Type", "Filespec");
}

CFX_WideString CPDF_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.c_str() + 2);
    return result;
  }
  if (filepath.GetAt(0) == '\\' && filepath.GetAt(1) == '\\') {
    return ChangeSlashToPDF(filepath.c_str() + 1);
  }
  if (filepath.GetAt(0) == '\\') {
    CFX_WideString result;
    result = '/';
    result += ChangeSlashToPDF(filepath.c_str());
    return result;
  }
  return ChangeSlashToPDF(filepath.c_str());
#elif _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_
  if (filepath.Left(sizeof("Mac") - 1) == FX_WSTRC(L"Mac")) {
    CFX_WideString result;
    result = '/';
    result += ChangeSlashToPDF(filepath.c_str());
    return result;
  }
  return ChangeSlashToPDF(filepath.c_str());
#else
  return CFX_WideString(filepath);
#endif
}

void CPDF_FileSpec::SetFileName(const CFX_WideStringC& wsFileName) {
  if (!m_pObj)
    return;

  CFX_WideString wsStr = EncodeFileName(wsFileName);
  if (m_pObj->IsString()) {
    m_pObj->SetString(CFX_ByteString::FromUnicode(wsStr));
  } else if (CPDF_Dictionary* pDict = m_pObj->AsDictionary()) {
    pDict->SetAtString("F", CFX_ByteString::FromUnicode(wsStr));
    pDict->SetAtString("UF", PDF_EncodeText(wsStr));
  }
}

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

IPDF_FormNotify::~IPDF_FormNotify() {}

int IPDF_FormNotify::BeforeValueChange(CPDF_FormField* pField,
                                       const CFX_WideString& csValue) {
  return 0;
}

void IPDF_FormNotify::AfterValueChange(CPDF_FormField* pField) {}

int IPDF_FormNotify::BeforeSelectionChange(CPDF_FormField* pField,
                                           const CFX_WideString& csValue) {
  return 0;
}

void IPDF_FormNotify::AfterSelectionChange(CPDF_FormField* pField) {}

void IPDF_FormNotify::AfterCheckedStatusChange(CPDF_FormField* pField) {}

int IPDF_FormNotify::BeforeFormReset(CPDF_InterForm* pForm) {
  return 0;
}

void IPDF_FormNotify::AfterFormReset(CPDF_InterForm* pForm) {}

int IPDF_FormNotify::BeforeFormImportData(CPDF_InterForm* pForm) {
  return 0;
}

void IPDF_FormNotify::AfterFormImportData(CPDF_InterForm* pForm) {}

CPDF_PageLabel::CPDF_PageLabel(CPDF_Document* pDocument)
    : m_pDocument(pDocument) {}

CFX_WideString CPDF_PageLabel::GetLabel(int nPage) const {
  CFX_WideString wsLabel;
  if (!m_pDocument) {
    return wsLabel;
  }
  CPDF_Dictionary* pPDFRoot = m_pDocument->GetRoot();
  if (!pPDFRoot) {
    return wsLabel;
  }
  CPDF_Dictionary* pLabels = pPDFRoot->GetDictBy("PageLabels");
  CPDF_NumberTree numberTree(pLabels);
  CPDF_Object* pValue = nullptr;
  int n = nPage;
  while (n >= 0) {
    pValue = numberTree.LookupValue(n);
    if (pValue) {
      break;
    }
    n--;
  }
  if (pValue) {
    pValue = pValue->GetDirect();
    if (CPDF_Dictionary* pLabel = pValue->AsDictionary()) {
      if (pLabel->KeyExist("P")) {
        wsLabel += pLabel->GetUnicodeTextBy("P");
      }
      CFX_ByteString bsNumberingStyle = pLabel->GetStringBy("S", "");
      int nLabelNum = nPage - n + pLabel->GetIntegerBy("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)
    return -1;

  CPDF_Dictionary* pPDFRoot = m_pDocument->GetRoot();
  if (!pPDFRoot)
    return -1;

  int nPages = m_pDocument->GetPageCount();
  for (int i = 0; i < nPages; i++) {
    if (PDF_EncodeText(GetLabel(i)).Compare(bsLabel))
      return i;
  }

  int nPage = FXSYS_atoi(CFX_ByteString(bsLabel).c_str());  // NUL terminate.
  return nPage > 0 && nPage <= nPages ? nPage : -1;
}

int32_t CPDF_PageLabel::GetPageByLabel(const CFX_WideStringC& wsLabel) const {
  return GetPageByLabel(PDF_EncodeText(wsLabel.c_str()).AsStringC());
}
