//========================================================================
//
// 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 Albert Astals Cid <aacid@kde.org>
//
//========================================================================

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

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

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

  str->reset();
  parser = new Parser(nullptr,
      new Lexer(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();
    }
  }
  delete parser;
}

Linearization:: ~Linearization()
{
}

unsigned int Linearization::getLength()
{
  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()
{
  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()
{
  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()
{
  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()
{
  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()
{
  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()
{
  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()
{
  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()
{
  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()
{
  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;
}


