//========================================================================
//
// OptionalContent.cc
//
// Copyright 2007 Brad Hards <bradh@kde.org>
// Copyright 2008 Pino Toscano <pino@kde.org>
// Copyright 2008, 2010 Carlos Garcia Campos <carlosgc@gnome.org>
// Copyright 2008, 2010, 2011, 2017-2019 Albert Astals Cid <aacid@kde.org>
// Copyright 2008 Mark Kaplan <mkaplan@finjan.com>
// Copyright 2018 Adam Reichold <adam.reichold@t-online.de>
// Copyright 2019 Oliver Sander <oliver.sander@tu-dresden.de>
//
// Released under the GPL (version 2, or later, at your option)
//
//========================================================================

#include <config.h>

#include "goo/gmem.h"
#include "goo/GooString.h"
#include "Error.h"
#include "OptionalContent.h"

// Max depth of nested visibility expressions.  This is used to catch
// infinite loops in the visibility expression object structure.
#define visibilityExprRecursionLimit 50

// Max depth of nested display nodes.  This is used to catch infinite
// loops in the "Order" object structure.
#define displayNodeRecursionLimit 50

//------------------------------------------------------------------------

OCGs::OCGs(Object *ocgObject, XRef *xref) :
  m_xref(xref)
{
  // we need to parse the dictionary here, and build optionalContentGroups
  ok = true;

  Object ocgList = ocgObject->dictLookup("OCGs");
  if (!ocgList.isArray()) {
    error(errSyntaxError, -1, "Expected the optional content group list, but wasn't able to find it, or it isn't an Array");
    ok = false;
    return;
  }

  // we now enumerate over the ocgList, and build up the optionalContentGroups list.
  for(int i = 0; i < ocgList.arrayGetLength(); ++i) {
    Object ocgDict = ocgList.arrayGet(i);
    if (!ocgDict.isDict()) {
      break;
    }
    auto thisOptionalContentGroup = std::make_unique<OptionalContentGroup>(ocgDict.getDict());
    const Object &ocgRef = ocgList.arrayGetNF(i);
    if (!ocgRef.isRef()) {
      break;
    }
    thisOptionalContentGroup->setRef( ocgRef.getRef() );
    // the default is ON - we change state later, depending on BaseState, ON and OFF
    thisOptionalContentGroup->setState(OptionalContentGroup::On);
    optionalContentGroups.emplace(ocgRef.getRef(), std::move(thisOptionalContentGroup));
  }

  Object defaultOcgConfig = ocgObject->dictLookup("D");
  if (!defaultOcgConfig.isDict()) {
    error(errSyntaxError, -1, "Expected the default config, but wasn't able to find it, or it isn't a Dictionary");
    ok = false;
    return;
  }

  Object baseState = defaultOcgConfig.dictLookup("BaseState");
  if (baseState.isName("OFF")) {
    for (auto &group : optionalContentGroups) {
      group.second->setState(OptionalContentGroup::Off);
    }
  }

  Object on = defaultOcgConfig.dictLookup("ON");
  if (on.isArray()) {
    // ON is an optional element
    for (int i = 0; i < on.arrayGetLength(); ++i) {
      const Object &reference = on.arrayGetNF(i);
      if (!reference.isRef()) {
	// there can be null entries
	break;
      }
      OptionalContentGroup *group = findOcgByRef( reference.getRef() );
      if (!group) {
	error(errSyntaxWarning, -1, "Couldn't find group for reference");
	break;
      }
      group->setState(OptionalContentGroup::On);
    }
  }

  Object off = defaultOcgConfig.dictLookup("OFF");
  if (off.isArray()) {
    // OFF is an optional element
    for (int i = 0; i < off.arrayGetLength(); ++i) {
      const Object &reference = off.arrayGetNF(i);
      if (!reference.isRef()) {
	// there can be null entries
	break;
      }
      OptionalContentGroup *group = findOcgByRef( reference.getRef() );
      if (!group) {
	error(errSyntaxWarning, -1, "Couldn't find group for reference to set OFF");
	break;
      }
      group->setState(OptionalContentGroup::Off);
    }
  }

  order = defaultOcgConfig.dictLookup("Order");
  rbgroups = defaultOcgConfig.dictLookup("RBGroups");
}

bool OCGs::hasOCGs() const
{
  return !( optionalContentGroups.empty() );
}

OptionalContentGroup* OCGs::findOcgByRef( const Ref ref )
{
  const auto ocg = optionalContentGroups.find( ref );
  return ocg != optionalContentGroups.end() ? ocg->second.get() : nullptr;
}

OCDisplayNode *OCGs::getDisplayRoot()
{
  if (display)
    return display.get();

  if (order.isArray())
    display.reset(OCDisplayNode::parse(&order, this, m_xref));

  return display.get();
}

bool OCGs::optContentIsVisible( const Object *dictRef )
{
  Dict *dict;
  bool result = true;

  if (dictRef->isNull())
    return result;

  if (dictRef->isRef()) {
    OptionalContentGroup *oc = findOcgByRef(dictRef->getRef());
    if (oc)
      return oc->getState() == OptionalContentGroup::On;
  }

  Object dictObj = dictRef->fetch( m_xref);
  if ( ! dictObj.isDict() ) {
    error(errSyntaxWarning, -1, "Unexpected oc reference target: {0:d}", dictObj.getType() );
    return result;
  }
  dict = dictObj.getDict();
  Object dictType = dict->lookup("Type");
  if (dictType.isName("OCMD")) {
    Object ve = dict->lookup("VE");
    if (ve.isArray()) {
      result = evalOCVisibilityExpr(&ve, 0);
    } else {
      const Object &ocg = dict->lookupNF("OCGs");
      if (ocg.isArray()) {
        Object policy = dict->lookup("P");
        if (policy.isName("AllOn")) {
          result = allOn( ocg.getArray() );
        } else if (policy.isName("AllOff")) {
          result = allOff( ocg.getArray() );
        } else if (policy.isName("AnyOff")) {
          result = anyOff( ocg.getArray() );
        } else if ( (!policy.isName()) || (policy.isName("AnyOn") ) ) {
          // this is the default
          result = anyOn( ocg.getArray() );
        }
      } else if (ocg.isRef()) {
        OptionalContentGroup *oc = findOcgByRef( ocg.getRef() );
        if ( oc && oc->getState() == OptionalContentGroup::Off ) {
          result = false;
        } else {
          result = true ;
        }
      }
    }
  } else if ( dictType.isName("OCG") && dictRef->isRef() ) {
    OptionalContentGroup* oc = findOcgByRef( dictRef->getRef() );
    if ( oc && oc->getState() == OptionalContentGroup::Off ) {
      result=false;
    }
  }
  return result;
}

bool OCGs::evalOCVisibilityExpr(const Object *expr, int recursion) {
  OptionalContentGroup *ocg;
  bool ret;

  if (recursion > visibilityExprRecursionLimit) {
    error(errSyntaxError, -1,
	  "Loop detected in optional content visibility expression");
    return true;
  }
  if (expr->isRef()) {
    if ((ocg = findOcgByRef(expr->getRef()))) {
      return ocg->getState() == OptionalContentGroup::On;
    }
  }
  Object expr2 = expr->fetch(m_xref);
  if (!expr2.isArray() || expr2.arrayGetLength() < 1) {
    error(errSyntaxError, -1,
	  "Invalid optional content visibility expression");
    return true;
  }
  Object op = expr2.arrayGet(0);
  if (op.isName("Not")) {
    if (expr2.arrayGetLength() == 2) {
      const Object &obj = expr2.arrayGetNF(1);
      ret = !evalOCVisibilityExpr(&obj, recursion + 1);
    } else {
      error(errSyntaxError, -1,
	    "Invalid optional content visibility expression");
      ret = true;
    }
  } else if (op.isName("And")) {
    ret = true;
    for (int i = 1; i < expr2.arrayGetLength() && ret; ++i) {
      const Object &obj = expr2.arrayGetNF(i);
      ret = evalOCVisibilityExpr(&obj, recursion + 1);
    }
  } else if (op.isName("Or")) {
    ret = false;
    for (int i = 1; i < expr2.arrayGetLength() && !ret; ++i) {
      const Object &obj = expr2.arrayGetNF(i);
      ret = evalOCVisibilityExpr(&obj, recursion + 1);
    }
  } else {
    error(errSyntaxError, -1,
	  "Invalid optional content visibility expression");
    ret = true;
  }
  return ret;
}

bool OCGs::allOn( Array *ocgArray )
{
  for (int i = 0; i < ocgArray->getLength(); ++i) {
    const Object &ocgItem = ocgArray->getNF(i);
    if (ocgItem.isRef()) {
      OptionalContentGroup* oc = findOcgByRef( ocgItem.getRef() );      
      if ( oc && oc->getState() == OptionalContentGroup::Off ) {
	return false;
      }
    }
  }
  return true;
}

bool OCGs::allOff( Array *ocgArray )
{
  for (int i = 0; i < ocgArray->getLength(); ++i) {
    const Object &ocgItem = ocgArray->getNF(i);
    if (ocgItem.isRef()) {
      OptionalContentGroup* oc = findOcgByRef( ocgItem.getRef() );      
      if ( oc && oc->getState() == OptionalContentGroup::On ) {
	return false;
      }
    }
  }
  return true;
}

bool OCGs::anyOn( Array *ocgArray )
{
  for (int i = 0; i < ocgArray->getLength(); ++i) {
    const Object &ocgItem = ocgArray->getNF(i);
    if (ocgItem.isRef()) {
      OptionalContentGroup* oc = findOcgByRef( ocgItem.getRef() );      
      if ( oc && oc->getState() == OptionalContentGroup::On ) {
	return true;
      }
    }
  }
  return false;
}

bool OCGs::anyOff( Array *ocgArray )
{
  for (int i = 0; i < ocgArray->getLength(); ++i) {
    const Object &ocgItem = ocgArray->getNF(i);
    if (ocgItem.isRef()) {
      OptionalContentGroup* oc = findOcgByRef( ocgItem.getRef() );      
      if ( oc && oc->getState() == OptionalContentGroup::Off ) {
	return true;
      }
    }
  }
  return false;
}

//------------------------------------------------------------------------

OptionalContentGroup::OptionalContentGroup(Dict *ocgDict) : m_name(nullptr)
{
  Object ocgName = ocgDict->lookup("Name");
  if (!ocgName.isString()) {
    error(errSyntaxWarning, -1, "Expected the name of the OCG, but wasn't able to find it, or it isn't a String");
  } else {
    m_name = new GooString( ocgName.getString() );
  }

  viewState = printState = ocUsageUnset;
  Object obj1 = ocgDict->lookup("Usage");
  if (obj1.isDict()) {
    Object obj2 = obj1.dictLookup("View");
    if (obj2.isDict()) {
      Object obj3 = obj2.dictLookup("ViewState");
      if (obj3.isName()) {
	if (obj3.isName("ON")) {
	  viewState = ocUsageOn;
	} else {
	  viewState = ocUsageOff;
	}
      }
    }
    obj2 = obj1.dictLookup("Print");
    if (obj2.isDict()) {
      Object obj3 = obj2.dictLookup("PrintState");
      if (obj3.isName()) {
	if (obj3.isName("ON")) {
	  printState = ocUsageOn;
	} else {
	  printState = ocUsageOff;
	}
      }
    }
  }
}

OptionalContentGroup::OptionalContentGroup(GooString *label)
{
  m_name = label;
  m_state = On;
}

const GooString* OptionalContentGroup::getName() const
{
  return m_name;
}

void OptionalContentGroup::setRef(const Ref ref)
{
  m_ref = ref;
}

Ref OptionalContentGroup::getRef() const
{
  return m_ref;
}

OptionalContentGroup::~OptionalContentGroup()
{
  delete m_name;
}

//------------------------------------------------------------------------

OCDisplayNode *OCDisplayNode::parse(const Object *obj, OCGs *oc,
				    XRef *xref, int recursion) {
  OptionalContentGroup *ocgA;
  OCDisplayNode *node, *child;
  int i;

  if (recursion > displayNodeRecursionLimit) {
    error(errSyntaxError, -1, "Loop detected in optional content order");
    return nullptr;
  }
  if (obj->isRef()) {
    if ((ocgA = oc->findOcgByRef(obj->getRef()))) {
      return new OCDisplayNode(ocgA);
    }
  }
  Object obj2 = obj->fetch(xref);
  if (!obj2.isArray()) {
    return nullptr;
  }
  i = 0;
  if (obj2.arrayGetLength() >= 1) {
    Object obj3 = obj2.arrayGet(0);
    if (obj3.isString()) {
      node = new OCDisplayNode(obj3.getString());
      i = 1;
    } else {
      node = new OCDisplayNode();
    }
  } else {
    node = new OCDisplayNode();
  }
  for (; i < obj2.arrayGetLength(); ++i) {
    const Object &obj3 = obj2.arrayGetNF(i);
    if ((child = OCDisplayNode::parse(&obj3, oc, xref, recursion + 1))) {
      if (!child->ocg && !child->name && node->getNumChildren() > 0) {
	node->getChild(node->getNumChildren() - 1)->addChildren(child->takeChildren());
	delete child;
      } else {
	node->addChild(child);
      }
    }
  }
  return node;
}

OCDisplayNode::OCDisplayNode() {
  name = nullptr;
  ocg = nullptr;
  children = nullptr;
}

OCDisplayNode::OCDisplayNode(const GooString *nameA) {
  name = new GooString(nameA);
  ocg = nullptr;
  children = nullptr;
}

OCDisplayNode::OCDisplayNode(OptionalContentGroup *ocgA) {
  name = (ocgA->getName()) ? ocgA->getName()->copy() : nullptr;
  ocg = ocgA;
  children = nullptr;
}

void OCDisplayNode::addChild(OCDisplayNode *child) {
  if (!children) {
    children = new std::vector<OCDisplayNode*>();
  }
  children->push_back(child);
}

void OCDisplayNode::addChildren(std::vector<OCDisplayNode*> *childrenA) {
  if (!children) {
    children = new std::vector<OCDisplayNode*>();
  }
  children->reserve(children->size() + childrenA->size());
  children->insert(children->end(), childrenA->begin(), childrenA->end());
  delete childrenA;
}

std::vector<OCDisplayNode*> *OCDisplayNode::takeChildren() {
  std::vector<OCDisplayNode*> *childrenA = children;

  children = nullptr;
  return childrenA;
}

OCDisplayNode::~OCDisplayNode() {
  delete name;
  if (children) {
    for (auto entry : *children) {
      delete entry;
    }
    delete children;
  }
}

int OCDisplayNode::getNumChildren() const {
  if (!children) {
    return 0;
  }
  return children->size();
}

OCDisplayNode *OCDisplayNode::getChild(int idx) const {
  return (*children)[idx];
}
