#include <limits.h>
#include <stdlib.h>
#include <stdio.h>
#include <assert.h>
#include "UGooString.h"

#include "PageLabelInfo.h"

/* http://mathworld.wolfram.com/RomanNumerals.html */

static int fromRoman(const char *buffer) {
  int digit_value, prev_digit_value, value;
  int i;

  prev_digit_value = INT_MAX;
  value = 0;
  for (i = 0; buffer[i] != '\0'; i++) {
    switch (buffer[i]) {
    case 'm':
    case 'M':
      digit_value = 1000;
      break;
    case 'd':
    case 'D':
      digit_value = 500;
      break;
    case 'c':
    case 'C':
      digit_value = 100;
      break;
    case 'l':
    case 'L':
      digit_value = 50;
      break;
    case 'x':
    case 'X':
      digit_value = 10;
      break;
    case 'v':
    case 'V':
      digit_value = 5;
      break;
    case 'i':
    case 'I':
      digit_value = 1;
      break;
    default:
      return -1;
    }

    if (digit_value <= prev_digit_value)
      value += digit_value;
    else
      value += digit_value - prev_digit_value * 2;
    prev_digit_value = digit_value;
  }

  return value;
}

static void toRoman(int number, GooString *str, GBool uppercase) {
  static const char uppercaseNumerals[] = "IVXLCDM";
  static const char lowercaseNumerals[] = "ivxlcdm";
  int divisor;
  int i, j, k;
  const char *wh;

  if (uppercase)
    wh = uppercaseNumerals;
  else
    wh = lowercaseNumerals;

  divisor = 1000;
  for (k = 3; k >= 0; k--) {
    i = number / divisor;
    number = number % divisor;

    switch (i) {
    case 0:
      break;
    case 5:
      str->append(wh[2 * k + 1]);
      break;
    case 9:
      str->append(wh[2 * k + 0]);
      str->append(wh[ 2 * k + 2]);
      break;
    case 4:
      str->append(wh[2 * k + 0]);
      str->append(wh[2 * k + 1]);
      break;
    default:
      if (i > 5) {
       str->append(wh[2 * k + 1]);
       i -= 5;
      }
      for (j = 0; j < i; j++) {
       str->append(wh[2 * k + 0]);
      }
    }
       
    divisor = divisor / 10;
  }
}

static int fromLatin(const char *buffer)
{
  int count;
  const char *p;

  for (p = buffer; *p; p++) {
    if (*p != buffer[0])
      return -1;
  }

  count = p - buffer;
  if (buffer[0] >= 'a' && buffer[0] <= 'z')
    return 26 * (count - 1) + buffer[0] - 'a' + 1;
  if (buffer[0] >= 'A' && buffer[0] <= 'Z')
    return 26 * (count - 1) + buffer[0] - 'A' + 1;

  return -1;
}

static void toLatin(int number, GooString *str, GBool uppercase) {
  char base, letter;
  int i, count;

  if (uppercase)
    base = 'A';
  else
    base = 'a';

  count = (number - 1) / 26 + 1;
  letter = base + (number - 1) % 26;

  for (i = 0; i < count; i++)
    str->append(letter);
}

PageLabelInfo::Interval::Interval(Object *dict, int baseA) {
  Object obj;

  style = None;
  if (dict->dictLookup("S", &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.free();

  if (dict->dictLookup("P", &obj)->isString())
    prefix = obj.getString()->copy();
  else
    prefix = new GooString("");
  obj.free();

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

  base = baseA;
}

PageLabelInfo::Interval::~Interval() {
  delete prefix;
}

PageLabelInfo::PageLabelInfo(Object *tree, int numPages) {
  int i;
  Interval *interval, *next;

  parse(tree);

  for (i = 0; i < intervals.getLength(); i++) {
    interval = (Interval *) intervals.get(i);

    if (i + 1 < intervals.getLength()) {
      next = (Interval *) intervals.get(i + 1);
      interval->length = next->base - interval->base;
    } else {
      interval->length = numPages - interval->base;
    }
  }
}

PageLabelInfo::~PageLabelInfo() {
  int i;
  for (i = 0; i < intervals.getLength(); ++i) {
    delete (Interval*)intervals.get(i);
  }
}

void PageLabelInfo::parse(Object *tree) {
  Object nums, obj;
  Object kids, kid, limits, low, high;
  int i, base;
  Interval *interval;

  // leaf node
  if (tree->dictLookup("Nums", &nums)->isArray()) {
    for (i = 0; i < nums.arrayGetLength(); i += 2) {
      if (!nums.arrayGet(i, &obj)->isInt()) {
	obj.free();
	continue;
      }
      base = obj.getInt();
      obj.free();
      if (!nums.arrayGet(i + 1, &obj)->isDict()) {
	obj.free();
	continue;
      }

      interval = new Interval(&obj, base);
      obj.free();
      intervals.append(interval);
    }
  }
  nums.free();

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

GBool PageLabelInfo::labelToIndex(GooString *label, int *index)
{
  Interval *interval;
  char *str = label->getCString(), *end;
  int prefixLength;
  int i, base, number;

  base = 0;
  for (i = 0; i < intervals.getLength(); i++) {
    interval = (Interval *) intervals.get(i);
    prefixLength = interval->prefix->getLength();
    if (label->cmpN(interval->prefix, prefixLength) != 0)
      continue;

    switch (interval->style) {
    case Interval::Arabic:
      number = strtol(str + prefixLength, &end, 10);
      if (*end == '\0' && number - interval->first < interval->length) {
	*index = base + number - interval->first;
	return gTrue;
      }
      break;
    case Interval::LowercaseRoman:
    case Interval::UppercaseRoman:
      number = fromRoman(str + prefixLength);
      if (number >= 0 && number - interval->first < interval->length) {
	*index = base + number - interval->first;
	return gTrue;
      }
      break;
    case Interval::UppercaseLatin:
    case Interval::LowercaseLatin:
      number = fromLatin(str + prefixLength);
      if (number >= 0 && number - interval->first < interval->length) {
	*index = base + number - interval->first;
	return gTrue;
      }
      break;
    case Interval::None:
      break;
    }

    base += interval->length;
  }

  return gFalse;
}

GBool PageLabelInfo::indexToLabel(int index, GooString *label)
{
  char buffer[32];
  int i, base, number;
  Interval *interval;
  GooString number_string;

  base = 0;
  interval = NULL;
  for (i = 0; i < intervals.getLength(); i++) {
    interval = (Interval *) intervals.get(i);
    if (base <= index && index < base + interval->length)
      break;
    base += interval->length;
  }

  if (i == intervals.getLength())
    return gFalse;

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

  label->clear();
  label->append(interval->prefix);
  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);
      }
      ucs2_char[1] = 0;
      label->append(ucs2_char, 2);
  } else {
      label->append(&number_string);
  }

  return gTrue;
}

#ifdef TEST
int main(int argc, char *argv[])
{
  {
    GooString str;
    toRoman(177, &str, gFalse);
    assert (str.cmp("clxxvii") == 0);
  }

  {
    GooString roman("clxxvii");
    assert (fromRoman(roman.getCString()) == 177);
  }

  {
    GooString str;
    toLatin(54, &str, gFalse);
    assert (str.cmp("bbb") == 0);
  }

  {
    GooString latin("ddd");
    assert (fromLatin(latin.getCString()) == 56);
  }
}
#endif
