// Copyright 2016 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/fpdfdoc/cpdf_pagelabel.h"

#include "core/fpdfapi/parser/cpdf_dictionary.h"
#include "core/fpdfapi/parser/cpdf_document.h"
#include "core/fpdfapi/parser/fpdf_parser_decode.h"
#include "core/fpdfdoc/cpdf_numbertree.h"

namespace {

WideString MakeRoman(int num) {
  const int kArabic[] = {1000, 900, 500, 400, 100, 90, 50, 40, 10, 9, 5, 4, 1};
  const WideStringView kRoman[] = {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 kMaxNum = 1000000;

  num %= kMaxNum;
  int i = 0;
  WideString wsRomanNumber;
  while (num > 0) {
    while (num >= kArabic[i]) {
      num = num - kArabic[i];
      wsRomanNumber += kRoman[i];
    }
    i = i + 1;
  }
  return wsRomanNumber;
}

WideString MakeLetters(int num) {
  if (num == 0)
    return WideString();

  WideString wsLetters;
  const int nMaxCount = 1000;
  const int nLetterCount = 26;
  --num;

  int count = num / nLetterCount + 1;
  count %= nMaxCount;
  wchar_t ch = L'a' + num % nLetterCount;
  for (int i = 0; i < count; i++)
    wsLetters += ch;
  return wsLetters;
}

WideString GetLabelNumPortion(int num, const ByteString& bsStyle) {
  if (bsStyle.IsEmpty())
    return WideString();
  if (bsStyle == "D")
    return WideString::FormatInteger(num);
  if (bsStyle == "R") {
    WideString wsNumPortion = MakeRoman(num);
    wsNumPortion.MakeUpper();
    return wsNumPortion;
  }
  if (bsStyle == "r")
    return MakeRoman(num);
  if (bsStyle == "A") {
    WideString wsNumPortion = MakeLetters(num);
    wsNumPortion.MakeUpper();
    return wsNumPortion;
  }
  if (bsStyle == "a")
    return MakeLetters(num);
  return WideString();
}

}  // namespace

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

CPDF_PageLabel::~CPDF_PageLabel() = default;

absl::optional<WideString> CPDF_PageLabel::GetLabel(int nPage) const {
  if (!m_pDocument)
    return absl::nullopt;

  if (nPage < 0 || nPage >= m_pDocument->GetPageCount())
    return absl::nullopt;

  const CPDF_Dictionary* pPDFRoot = m_pDocument->GetRoot();
  if (!pPDFRoot)
    return absl::nullopt;

  const CPDF_Dictionary* pLabels = pPDFRoot->GetDictFor("PageLabels");
  if (!pLabels)
    return absl::nullopt;

  CPDF_NumberTree numberTree(pLabels);
  const CPDF_Object* pValue = nullptr;
  int n = nPage;
  while (n >= 0) {
    pValue = numberTree.LookupValue(n);
    if (pValue)
      break;
    n--;
  }

  if (pValue) {
    pValue = pValue->GetDirect();
    if (const CPDF_Dictionary* pLabel = pValue->AsDictionary()) {
      WideString label;
      if (pLabel->KeyExist("P"))
        label += pLabel->GetUnicodeTextFor("P");

      ByteString bsNumberingStyle = pLabel->GetStringFor("S", ByteString());
      int nLabelNum = nPage - n + pLabel->GetIntegerFor("St", 1);
      WideString wsNumPortion = GetLabelNumPortion(nLabelNum, bsNumberingStyle);
      label += wsNumPortion;
      return label;
    }
  }
  return WideString::FormatInteger(nPage + 1);
}
