//========================================================================
//
// 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, 2020, 2021 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 <climits>
#include <cstdlib>
#include <cstdio>
#include <cassert>

#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)
{
    std::set<int> alreadyParsedRefs;
    parse(tree, alreadyParsedRefs);

    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(const Object *tree, std::set<int> &alreadyParsedRefs)
{
    // 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;
            }
            const int base = obj.getInt();
            if (base < 0) {
                continue;
            }
            obj = nums.arrayGet(i + 1);
            if (!obj.isDict()) {
                continue;
            }

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

    Object kids = tree->dictLookup("Kids");
    if (kids.isArray()) {
        const Array *kidsArray = kids.getArray();
        for (int i = 0; i < kidsArray->getLength(); ++i) {
            Ref ref;
            const Object kid = kidsArray->get(i, &ref);
            if (ref != Ref::INVALID()) {
                const int numObj = ref.num;
                if (alreadyParsedRefs.find(numObj) != alreadyParsedRefs.end()) {
                    error(errSyntaxError, -1, "loop in PageLabelInfo (numObj: {0:d})", numObj);
                    continue;
                }
                alreadyParsedRefs.insert(numObj);
            }
            if (kid.isDict()) {
                parse(&kid, alreadyParsedRefs);
            }
        }
    }
}

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(label->toStr().substr(prefixLen), 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:
            if (interval.length == 1 && label->toStr() == interval.prefix) {
                *index = interval.base;
                return true;
            } else {
                error(errSyntaxError, -1, "asking to convert label to page index in an unknown scenario, report a bug");
            }
            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;
}
