//========================================================================
//
// 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()
{
}

Guint 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;
  }
}

Guint 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;
}

Guint 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;
}

Guint 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;
}

Guint 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;
  }
}

Guint 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;
  }
}

Guint 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;
}


