//========================================================================
//
// This file is under the GPLv2 or later license
//
// Copyright (C) 2005-2006 Kristian Høgsberg <krh@redhat.com>
// Copyright (C) 2005, 2009, 2013, 2017, 2018 Albert Astals Cid <aacid@kde.org>
// Copyright (C) 2011 Simon Kellner <kellner@kit.edu>
// Copyright (C) 2012 Fabio D'Urso <fabiodurso@hotmail.it>
// Copyright (C) 2018 Adam Reichold <adam.reichold@t-online.de>
//
// To see a description of the changes please see the Changelog file that
// came with your tarball or type make ChangeLog if you are building from git
//
//========================================================================

#include <config.h>
#include <limits.h>
#include <stdlib.h>
#include <stdio.h>
#include <assert.h>

#include <algorithm>

#include "PageLabelInfo.h"
#include "PageLabelInfo_p.h"

PageLabelInfo::Interval::Interval(Object *dict, int baseA) {
  style = None;
  Object obj = dict->dictLookup("S");
  if (obj.isName()) {
    if (obj.isName("D")) {
      style = Arabic;
    } else if (obj.isName("R")) {
      style = UppercaseRoman;
    } else if (obj.isName("r")) {
      style = LowercaseRoman;
    } else if (obj.isName("A")) {
      style = UppercaseLatin;
    } else if (obj.isName("a")) {
      style = LowercaseLatin;
    }
  }

  obj = dict->dictLookup("P");
  if (obj.isString()) {
    const auto str = obj.getString();
    prefix.assign(str->c_str(), str->getLength());
  }

  obj = dict->dictLookup("St");
  if (obj.isInt())
    first = obj.getInt();
  else
    first = 1;

  base = baseA;
}

PageLabelInfo::PageLabelInfo(Object *tree, int numPages) {
  parse(tree);

  if (intervals.empty())
    return;

  auto curr = intervals.begin();
  for(auto next = curr + 1; next != intervals.end(); ++next, ++curr) {
    curr->length = std::max(0, next->base - curr->base);
  }
  curr->length = std::max(0, numPages - curr->base);
}

void PageLabelInfo::parse(Object *tree) {
  // leaf node
  Object nums = tree->dictLookup("Nums");
  if (nums.isArray()) {
    for (int i = 0; i < nums.arrayGetLength(); i += 2) {
      Object obj = nums.arrayGet(i);
      if (!obj.isInt()) {
	continue;
      }
      int base = obj.getInt();
      obj = nums.arrayGet(i + 1);
      if (!obj.isDict()) {
	continue;
      }

      intervals.emplace_back(&obj, base);
    }
  }

  Object kids = tree->dictLookup("Kids");
  if (kids.isArray()) {
    for (int i = 0; i < kids.arrayGetLength(); ++i) {
      Object kid = kids.arrayGet(i);
      if (kid.isDict())
	parse(&kid);
    }
  }
}

bool PageLabelInfo::labelToIndex(GooString *label, int *index) const
{
  const char *const str = label->c_str();
  const std::size_t strLen = label->getLength();
  const bool strUnicode = label->hasUnicodeMarker();
  int number;
  bool ok;

  for (const auto& interval : intervals) {
    const std::size_t prefixLen = interval.prefix.size();
    if (strLen < prefixLen || interval.prefix.compare(0, prefixLen, str, prefixLen) != 0)
      continue;

    switch (interval.style) {
    case Interval::Arabic:
      std::tie(number, ok) = fromDecimal(str + prefixLen, str + strLen, strUnicode);
      if (ok && number - interval.first < interval.length) {
    *index = interval.base + number - interval.first;
	return true;
      }
      break;
    case Interval::LowercaseRoman:
    case Interval::UppercaseRoman:
      number = fromRoman(str + prefixLen);
      if (number >= 0 && number - interval.first < interval.length) {
    *index = interval.base + number - interval.first;
	return true;
      }
      break;
    case Interval::UppercaseLatin:
    case Interval::LowercaseLatin:
      number = fromLatin(str + prefixLen);
      if (number >= 0 && number - interval.first < interval.length) {
    *index = interval.base + number - interval.first;
	return true;
      }
      break;
    case Interval::None:
      break;
    }
  }

  return false;
}

bool PageLabelInfo::indexToLabel(int index, GooString *label) const
{
  char buffer[32];
  int base, number;
  const Interval *matching_interval;
  GooString number_string;

  base = 0;
  matching_interval = nullptr;
  for (const auto& interval : intervals) {
    if (base <= index && index < base + interval.length) {
      matching_interval = &interval;
      break;
    }
    base += interval.length;
  }

  if (!matching_interval)
    return false;

  number = index - base + matching_interval->first;
  switch (matching_interval->style) {
  case Interval::Arabic:
    snprintf (buffer, sizeof(buffer), "%d", number);
    number_string.append(buffer);
    break;
  case Interval::LowercaseRoman:
    toRoman(number, &number_string, false);
    break;
  case Interval::UppercaseRoman:
    toRoman(number, &number_string, true);
    break;
  case Interval::LowercaseLatin:
    toLatin(number, &number_string, false);
    break;
  case Interval::UppercaseLatin:
    toLatin(number, &number_string, true);
    break;
  case Interval::None:
    break;
  }

  label->clear();
  label->append(matching_interval->prefix.c_str(), matching_interval->prefix.size());
  if (label->hasUnicodeMarker()) {
      int i, len;
      char ucs2_char[2];

      /* Convert the ascii number string to ucs2 and append. */
      len = number_string.getLength ();
      ucs2_char[0] = 0;
      for (i = 0; i < len; ++i) {
	  ucs2_char[1] = number_string.getChar(i);
	  label->append(ucs2_char, 2);
      }
  } else {
      label->append(&number_string);
  }

  return true;
}
