//========================================================================
//
// Linearization.cc
//
// This file is licensed under the GPLv2 or later
//
// Copyright 2010, 2012 Hib Eris <hib@hiberis.nl>
// Copyright 2015 Jason Crain <jason@aquaticape.us>
// Copyright 2017, 2019 Albert Astals Cid <aacid@kde.org>
// Copyright 2019 Adam Reichold <adam.reichold@t-online.de>
// Copyright 2019 Even Rouault <even.rouault@spatialys.com>
//
//========================================================================

#include "Linearization.h"
#include "Parser.h"
#include "Lexer.h"

//------------------------------------------------------------------------
// Linearization
//------------------------------------------------------------------------

Linearization::Linearization(BaseStream *str)
{
    Parser *parser;

    str->reset();
    parser = new Parser(nullptr, str->makeSubStream(str->getStart(), false, 0, Object(objNull)), false);
    Object obj1 = parser->getObj();
    Object obj2 = parser->getObj();
    Object obj3 = parser->getObj();
    linDict = parser->getObj();
    if (obj1.isInt() && obj2.isInt() && obj3.isCmd("obj") && linDict.isDict()) {
        Object obj5 = linDict.dictLookup("Linearized");
        if (!(obj5.isNum() && obj5.getNum() > 0)) {
            linDict.setToNull();
        }
    } else {
        linDict.setToNull();
    }
    delete parser;
}

Linearization::~Linearization() { }

unsigned int Linearization::getLength() const
{
    if (!linDict.isDict()) {
        return 0;
    }

    int length;
    if (linDict.getDict()->lookupInt("L", nullptr, &length) && length > 0) {
        return length;
    } else {
        error(errSyntaxWarning, -1, "Length in linearization table is invalid");
        return 0;
    }
}

unsigned int Linearization::getHintsOffset() const
{
    int hintsOffset;

    Object obj1, obj2;
    if (linDict.isDict() && (obj1 = linDict.dictLookup("H"), obj1.isArray()) && obj1.arrayGetLength() >= 2 && (obj2 = obj1.arrayGet(0), obj2.isInt()) && obj2.getInt() > 0) {
        hintsOffset = obj2.getInt();
    } else {
        error(errSyntaxWarning, -1, "Hints table offset in linearization table is invalid");
        hintsOffset = 0;
    }

    return hintsOffset;
}

unsigned int Linearization::getHintsLength() const
{
    int hintsLength;

    Object obj1, obj2;
    if (linDict.isDict() && (obj1 = linDict.dictLookup("H"), obj1.isArray()) && obj1.arrayGetLength() >= 2 && (obj2 = obj1.arrayGet(1), obj2.isInt()) && obj2.getInt() > 0) {
        hintsLength = obj2.getInt();
    } else {
        error(errSyntaxWarning, -1, "Hints table length in linearization table is invalid");
        hintsLength = 0;
    }

    return hintsLength;
}

unsigned int Linearization::getHintsOffset2() const
{
    int hintsOffset2 = 0; // default to 0

    Object obj1;
    if (linDict.isDict() && (obj1 = linDict.dictLookup("H"), obj1.isArray()) && obj1.arrayGetLength() >= 4) {
        Object obj2 = obj1.arrayGet(2);
        if (obj2.isInt() && obj2.getInt() > 0) {
            hintsOffset2 = obj2.getInt();
        } else {
            error(errSyntaxWarning, -1, "Second hints table offset in linearization table is invalid");
            hintsOffset2 = 0;
        }
    }

    return hintsOffset2;
}

unsigned int Linearization::getHintsLength2() const
{
    int hintsLength2 = 0; // default to 0

    Object obj1;
    if (linDict.isDict() && (obj1 = linDict.dictLookup("H"), obj1.isArray()) && obj1.arrayGetLength() >= 4) {
        Object obj2 = obj1.arrayGet(3);
        if (obj2.isInt() && obj2.getInt() > 0) {
            hintsLength2 = obj2.getInt();
        } else {
            error(errSyntaxWarning, -1, "Second hints table length in linearization table is invalid");
            hintsLength2 = 0;
        }
    }

    return hintsLength2;
}

int Linearization::getObjectNumberFirst() const
{
    int objectNumberFirst = 0;
    if (linDict.isDict() && linDict.getDict()->lookupInt("O", nullptr, &objectNumberFirst) && objectNumberFirst > 0) {
        return objectNumberFirst;
    } else {
        error(errSyntaxWarning, -1, "Object number of first page in linearization table is invalid");
        return 0;
    }
}

unsigned int Linearization::getEndFirst() const
{
    int pageEndFirst = 0;
    if (linDict.isDict() && linDict.getDict()->lookupInt("E", nullptr, &pageEndFirst) && pageEndFirst > 0) {
        return pageEndFirst;
    } else {
        error(errSyntaxWarning, -1, "First page end offset in linearization table is invalid");
        return 0;
    }
}

int Linearization::getNumPages() const
{
    int numPages = 0;
    if (linDict.isDict() && linDict.getDict()->lookupInt("N", nullptr, &numPages) && numPages > 0) {
        return numPages;
    } else {
        error(errSyntaxWarning, -1, "Page count in linearization table is invalid");
        return 0;
    }
}

unsigned int Linearization::getMainXRefEntriesOffset() const
{
    int mainXRefEntriesOffset = 0;
    if (linDict.isDict() && linDict.getDict()->lookupInt("T", nullptr, &mainXRefEntriesOffset) && mainXRefEntriesOffset > 0) {
        return mainXRefEntriesOffset;
    } else {
        error(errSyntaxWarning, -1, "Main Xref offset in linearization table is invalid");
        return 0;
    }
}

int Linearization::getPageFirst() const
{
    int pageFirst = 0; // Optional, defaults to 0.

    if (linDict.isDict()) {
        linDict.getDict()->lookupInt("P", nullptr, &pageFirst);
    }

    if ((pageFirst < 0) || (pageFirst >= getNumPages())) {
        error(errSyntaxWarning, -1, "First page in linearization table is invalid");
        return 0;
    }

    return pageFirst;
}
