//========================================================================
//
// 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, 2018 Albert Astals Cid <aacid@kde.org>
// Copyright 2008 Mark Kaplan <mkaplan@finjan.com>
// Copyright 2018 Adam Reichold <adam.reichold@t-online.de>
//
// Released under the GPL (version 2, or later, at your option)
//
//========================================================================

#include <config.h>

#include "goo/gmem.h"
#include "goo/GooString.h"
#include "goo/GooList.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 ocg = ocgList.arrayGet(i);
    if (!ocg.isDict()) {
      break;
    }
    auto thisOptionalContentGroup = std::make_unique<OptionalContentGroup>(ocg.getDict());
    ocg = ocgList.arrayGetNF(i);
    if (!ocg.isRef()) {
      break;
    }
    thisOptionalContentGroup->setRef( ocg.getRef() );
    // the default is ON - we change state later, depending on BaseState, ON and OFF
    thisOptionalContentGroup->setState(OptionalContentGroup::On);
    optionalContentGroups.emplace(ocg.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) {
      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) {
      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( 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 {
      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(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) {
      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) {
      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) {
      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) {
    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) {
    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) {
    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) {
    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(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) {
    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 GooList();
  }
  children->push_back(child);
}

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

GooList *OCDisplayNode::takeChildren() {
  GooList *childrenA;

  childrenA = children;
  children = nullptr;
  return childrenA;
}

OCDisplayNode::~OCDisplayNode() {
  gfree(name);
  if (children) {
    deleteGooList<OCDisplayNode>(children);
  }
}

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

OCDisplayNode *OCDisplayNode::getChild(int idx) const {
  return (OCDisplayNode *)children->get(idx);
}
