//========================================================================
//
// StructElement.h
//
// This file is licensed under the GPLv2 or later
//
// Copyright 2013, 2014 Igalia S.L.
// Copyright 2014 Luigi Scarso <luigi.scarso@gmail.com>
// Copyright 2014, 2018 Albert Astals Cid <aacid@kde.org>
//
//========================================================================

#ifndef STRUCTELEMENT_H
#define STRUCTELEMENT_H

#include "goo/gtypes.h"
#include "goo/GooString.h"
#include "MarkedContentOutputDev.h"
#include "Object.h"
#include <vector>
#include <set>

class GooString;
class Dict;
class StructElement;
class StructTreeRoot;


class Attribute {
public:
  enum Type {
    Unknown = 0,        // Uninitialized, parsing error, etc.
    UserProperty,       // User defined attribute (i.e. non-standard)

    // Common standard attributes
    Placement, WritingMode, BackgroundColor, BorderColor, BorderStyle,
    BorderThickness, Color, Padding,

    // Block element standard attributes
    SpaceBefore, SpaceAfter, StartIndent, EndIndent, TextIndent, TextAlign,
    BBox, Width, Height, BlockAlign, InlineAlign, TBorderStyle, TPadding,

    // Inline element standard attributes
    BaselineShift, LineHeight, TextDecorationColor, TextDecorationThickness,
    TextDecorationType, RubyAlign, RubyPosition, GlyphOrientationVertical,

    // Column-only standard attributes
    ColumnCount, ColumnGap, ColumnWidths,

    // List-only standard attributes
    ListNumbering,

    // PrintField-only standard attributes
    Role, checked, Desc,

    // Table-only standard attributes
    RowSpan, ColSpan, Headers, Scope, Summary,
  };

  enum Owner {
    UnknownOwner = 0,
    // User-defined attributes
    UserProperties,
    // Standard attributes
    Layout, List, PrintField, Table,
    // Translation to other formats
    XML_1_00, HTML_3_20, HTML_4_01, OEB_1_00, RTF_1_05, CSS_1_00, CSS_2_00,
  };

  // Creates a standard attribute. The name is predefined, and the
  // value is type-checked to conform to the PDF specification.
  Attribute(Type type, Object *value);

  // Creates an UserProperty attribute, with an arbitrary name and value.
  Attribute(const char *name, int nameLen, Object *value);

  GBool isOk() const { return type != Unknown; }

  // Name, type and value can be set only on construction.
  Type getType() const { return type; }
  Owner getOwner() const { return owner; }
  const char *getTypeName() const;
  const char *getOwnerName() const;
  Object *getValue() const { return &value; }
  static Object *getDefaultValue(Type type);

  // The caller gets the ownership of the return GooString and is responsible of deleting it
  GooString *getName() const { return type == UserProperty ? name.copy() : new GooString(getTypeName()); }

  // The revision is optional, and defaults to zero.
  Guint getRevision() const { return revision; }
  void setRevision(Guint revisionA) { revision = revisionA; }

  // Hidden elements should not be displayed by the user agent
  GBool isHidden() const { return hidden; }
  void setHidden(GBool hiddenA) { hidden = hiddenA; }

  // The formatted value may be in the PDF, or be left undefined (nullptr).
  // In the later case the user agent should provide a default representation.
  const char *getFormattedValue() const { return formatted ? formatted->getCString() : nullptr; }
  void setFormattedValue(const char *formattedA);

  ~Attribute();

private:
  Type type;
  Owner owner;
  Guint revision;
  mutable GooString name;
  mutable Object value;
  GBool hidden;
  GooString *formatted;

  GBool checkType(StructElement *element = nullptr);
  static Type getTypeForName(const char *name, StructElement *element = nullptr);
  static Attribute *parseUserProperty(Dict *property);

  friend class StructElement;
};


class StructElement {
public:
  enum Type {
    Unknown = 0,
    MCID,                                   // MCID reference, used internally
    OBJR,                                   // Object reference, used internally

    Document, Part, Art, Sect, Div,         // Structural elements

    Span, Quote, Note, Reference, BibEntry, // Inline elements
    Code, Link, Annot,
    BlockQuote, Caption, NonStruct,
    TOC, TOCI, Index, Private,

    P, H, H1, H2, H3, H4, H5, H6,           // Paragraph-like

    L, LI, Lbl, LBody,                      // List elements

    Table, TR, TH, TD, THead, TFoot, TBody, // Table elements

    Ruby, RB, RT, RP,                       // Ruby text elements
    Warichu, WT, WP,

    Figure, Formula, Form,                  // Illustration-like elements
  };

  static const Ref InvalidRef;

  const char *getTypeName() const;
  Type getType() const { return type; }
  GBool isOk() const { return type != Unknown; }
  GBool isBlock() const;
  GBool isInline() const;
  GBool isGrouping() const;

  inline GBool isContent() const { return (type == MCID) || isObjectRef(); }
  inline GBool isObjectRef() const { return (type == OBJR && c->ref.num != -1 && c->ref.gen != -1); }

  int getMCID() const { return c->mcid; }
  Ref getObjectRef() const { return c->ref; }
  Ref getParentRef() { return isContent() ? parent->getParentRef() : s->parentRef.getRef(); }
  GBool hasPageRef() const;
  GBool getPageRef(Ref& ref) const;
  StructTreeRoot *getStructTreeRoot() { return treeRoot; }

  // Optional element identifier.
  const GooString *getID() const { return isContent() ? nullptr : s->id; }
  GooString *getID() { return isContent() ? nullptr : s->id; }

  // Optional ISO language name, e.g. en_US
  GooString *getLanguage() {
    if (!isContent() && s->language) return s->language;
    return parent ? parent->getLanguage() : nullptr;
  }
  const GooString *getLanguage() const {
    if (!isContent() && s->language) return s->language;
    return parent ? parent->getLanguage() : nullptr;
  }

  // Optional revision number, defaults to zero.
  Guint getRevision() const { return isContent() ? 0 : s->revision; }
  void setRevision(Guint revision) { if (isContent()) s->revision = revision; }

  // Optional element title, in human-readable form.
  const GooString *getTitle() const { return isContent() ? nullptr : s->title; }
  GooString *getTitle() { return isContent() ? nullptr : s->title; }

  // Optional element expanded abbreviation text.
  const GooString *getExpandedAbbr() const { return isContent() ? nullptr : s->expandedAbbr; }
  GooString *getExpandedAbbr() { return isContent() ? nullptr : s->expandedAbbr; }

  unsigned getNumChildren() const { return isContent() ? 0 : s->elements.size(); }
  const StructElement *getChild(int i) const { return isContent() ? nullptr : s->elements.at(i); }
  StructElement *getChild(int i) { return isContent() ? nullptr : s->elements.at(i); }

  void appendChild(StructElement *element) {
    if (!isContent() && element && element->isOk()) {
      s->elements.push_back(element);
    }
  }

  unsigned getNumAttributes() const { return isContent() ? 0 : s->attributes.size(); }
  const Attribute *getAttribute(int i) const { return isContent() ? nullptr : s->attributes.at(i); }
  Attribute *getAttribute(int i) { return isContent() ? nullptr : s->attributes.at(i); }

  void appendAttribute(Attribute *attribute) {
    if (!isContent() && attribute) {
      s->attributes.push_back(attribute);
    }
  }

  const Attribute* findAttribute(Attribute::Type attributeType, GBool inherit = gFalse,
                                 Attribute::Owner owner = Attribute::UnknownOwner) const;

  const GooString *getAltText() const { return isContent() ? nullptr : s->altText; }
  GooString *getAltText() { return isContent() ? nullptr : s->altText; }

  const GooString *getActualText() const { return isContent() ? nullptr : s->actualText; }
  GooString *getActualText() { return isContent() ? nullptr : s->actualText; }

  // Content text referenced by the element:
  //
  // - For MCID reference elements, this is just the text of the
  //   corresponding marked content object in the page stream, regardless
  //   of the setting of the "recursive" flag.
  // - For other elements, if the "recursive" flag is set, the text
  //   enclosed by *all* the child MCID reference elements of the subtree
  //   is returned. The text is assembled by traversing the leaf MCID
  //   reference elements in logical order.
  // - In any other case, the function returns nullptr.
  //
  // A new string is returned, and the ownership passed to the caller.
  //
  GooString *getText(GBool recursive = gTrue) const {
    return appendSubTreeText(nullptr, recursive);
  }

  const TextSpanArray getTextSpans() const {
    if (!isContent())
      return TextSpanArray();
    MarkedContentOutputDev mcdev(getMCID());
    return getTextSpansInternal(mcdev);
  }

  ~StructElement();

private:
  GooString* appendSubTreeText(GooString *string, GBool recursive) const;
  const TextSpanArray& getTextSpansInternal(MarkedContentOutputDev& mcdev) const;

  typedef std::vector<Attribute*>     AttrPtrArray;
  typedef std::vector<StructElement*> ElemPtrArray;

  struct StructData {
    Object       parentRef;
    GooString   *altText;
    GooString   *actualText;
    GooString   *id;
    GooString   *title;
    GooString   *expandedAbbr;
    GooString   *language;
    Guint        revision;
    ElemPtrArray elements;
    AttrPtrArray attributes;

    StructData();
    ~StructData();

    StructData(const StructData &) = delete;
    StructData& operator=(const StructData &) = delete;
  };

  // Data in content elements (MCID, MCR)
  struct ContentData {
    union {
      int mcid;
      Ref ref;
    };

    ContentData(int mcidA): mcid(mcidA) {}
    ContentData(const Ref& r) { ref.num = r.num; ref.gen = r.gen; }
  };

  // Common data
  Type type;
  StructTreeRoot *treeRoot;
  StructElement *parent;
  mutable Object pageRef;

  union {
    StructData  *s;
    ContentData *c;
  };

  StructElement(Dict *elementDict, StructTreeRoot *treeRootA, StructElement *parentA, std::set<int> &seen);
  StructElement(int mcid, StructTreeRoot *treeRootA, StructElement *parentA);
  StructElement(const Ref &ref, StructTreeRoot *treeRootA, StructElement *parentA);

  void parse(Dict* elementDict);
  StructElement* parseChild(Object *ref, Object* childObj, std::set<int> &seen);
  void parseChildren(Dict* element, std::set<int> &seen);
  void parseAttributes(Dict *element, GBool keepExisting = gFalse);

  friend class StructTreeRoot;
};

#endif

