//========================================================================
//
// Annot.h
//
// Copyright 2000-2003 Glyph & Cog, LLC
//
//========================================================================

//========================================================================
//
// Modified under the Poppler project - http://poppler.freedesktop.org
//
// All changes made under the Poppler project to this file are licensed
// under GPL version 2 or later
//
// Copyright (C) 2006 Scott Turner <scotty1024@mac.com>
// Copyright (C) 2007, 2008 Julien Rebetez <julienr@svn.gnome.org>
// Copyright (C) 2007-2011, 2013, 2015, 2018 Carlos Garcia Campos <carlosgc@gnome.org>
// Copyright (C) 2007, 2008 Iñigo Martínez <inigomartinez@gmail.com>
// Copyright (C) 2008 Michael Vrable <mvrable@cs.ucsd.edu>
// Copyright (C) 2008 Hugo Mercier <hmercier31@gmail.com>
// Copyright (C) 2008 Pino Toscano <pino@kde.org>
// Copyright (C) 2008 Tomas Are Haavet <tomasare@gmail.com>
// Copyright (C) 2009-2011, 2013, 2016-2018 Albert Astals Cid <aacid@kde.org>
// Copyright (C) 2012, 2013 Fabio D'Urso <fabiodurso@hotmail.it>
// Copyright (C) 2012, 2015 Tobias Koenig <tokoe@kdab.com>
// Copyright (C) 2013 Thomas Freitag <Thomas.Freitag@alfa.de>
// Copyright (C) 2013, 2017 Adrian Johnson <ajohnson@redneon.com>
// Copyright (C) 2018 Klarälvdalens Datakonsult AB, a KDAB Group company, <info@kdab.com>. Work sponsored by the LiMux project of the city of Munich
// Copyright (C) 2018 Dileep Sankhla <sankhla.dileep96@gmail.com>
// Copyright (C) 2018 Tobias Deiminger <haxtibal@posteo.de>
// Copyright (C) 2018 Oliver Sander <oliver.sander@tu-dresden.de>
// Copyright (C) 2018 Adam Reichold <adam.reichold@t-online.de>
//
// To see a description of the changes please see the Changelog file that
// came with your tarball or type make ChangeLog if you are building from git
//
//========================================================================

#ifndef ANNOT_H
#define ANNOT_H

#include <memory>
#include <atomic>
#include <mutex>
#include <vector>

#include "Object.h"

class XRef;
class Gfx;
class CharCodeToUnicode;
class GfxFont;
class GfxResources;
class Page;
class PDFDoc;
class Form;
class FormWidget;
class FormField;
class FormFieldButton;
class FormFieldText;
class FormFieldChoice;
class PDFRectangle;
class Movie;
class LinkAction;
class Sound;
class FileSpec;

enum AnnotLineEndingStyle {
  annotLineEndingSquare,        // Square
  annotLineEndingCircle,        // Circle
  annotLineEndingDiamond,       // Diamond
  annotLineEndingOpenArrow,     // OpenArrow
  annotLineEndingClosedArrow,   // ClosedArrow
  annotLineEndingNone,          // None
  annotLineEndingButt,          // Butt
  annotLineEndingROpenArrow,    // ROpenArrow
  annotLineEndingRClosedArrow,  // RClosedArrow
  annotLineEndingSlash          // Slash
};

enum AnnotExternalDataType {
  annotExternalDataMarkupUnknown,
  annotExternalDataMarkup3D       // Markup3D
};

//------------------------------------------------------------------------
// AnnotCoord
//------------------------------------------------------------------------

class AnnotCoord {
public:

  AnnotCoord() : x(0), y(0) { }
  AnnotCoord(double _x, double _y) : x(_x), y(_y) { }

  double getX() const { return x; }
  double getY() const { return y; }

protected:

  double x, y;
};

//------------------------------------------------------------------------
// AnnotPath
//------------------------------------------------------------------------

class AnnotPath {
public:
  AnnotPath();
  AnnotPath(Array *array);
  AnnotPath(std::vector<AnnotCoord> &&coords);
  ~AnnotPath();

  AnnotPath(const AnnotPath &) = delete;
  AnnotPath& operator=(const AnnotPath &other) = delete;

  double getX(int coord) const;
  double getY(int coord) const;
  AnnotCoord *getCoord(int coord);
  int getCoordsLength() const { return coords.size(); }
protected:
  std::vector<AnnotCoord> coords;

  void parsePathArray(Array *array);
};
  
//------------------------------------------------------------------------
// AnnotCalloutLine
//------------------------------------------------------------------------

class AnnotCalloutLine {
public:

  AnnotCalloutLine(double x1, double y1, double x2, double y2);
  virtual ~AnnotCalloutLine() { }

  AnnotCalloutLine(const AnnotCalloutLine &) = delete;
  AnnotCalloutLine& operator=(const AnnotCalloutLine &other) = delete;

  double getX1() const { return coord1.getX(); }
  double getY1() const { return coord1.getY(); }
  double getX2() const { return coord2.getX(); }
  double getY2() const { return coord2.getY(); }
  
protected:

  AnnotCoord coord1, coord2;
};

//------------------------------------------------------------------------
// AnnotCalloutMultiLine
//------------------------------------------------------------------------

class AnnotCalloutMultiLine: public AnnotCalloutLine {
public:

  AnnotCalloutMultiLine(double x1, double y1, double x2, double y2,
    double x3, double y3);

  double getX3() const { return coord3.getX(); }
  double getY3() const { return coord3.getY(); }

protected:

  AnnotCoord coord3;
};

//------------------------------------------------------------------------
// AnnotBorderEffect
//------------------------------------------------------------------------

class AnnotBorderEffect {
public:

  enum AnnotBorderEffectType {
    borderEffectNoEffect, // S
    borderEffectCloudy    // C
  };

  AnnotBorderEffect(Dict *dict);

  AnnotBorderEffectType getEffectType() const { return effectType; }
  double getIntensity() const { return intensity; }

private:

  AnnotBorderEffectType effectType; // S  (Default S)
  double intensity;                 // I  (Default 0)
};

//------------------------------------------------------------------------
// AnnotQuadrilateral
//------------------------------------------------------------------------

class AnnotQuadrilaterals {
public:
  class AnnotQuadrilateral {
  public:
    AnnotQuadrilateral();
    AnnotQuadrilateral(double x1, double y1, double x2, double y2, double x3,
      double y3, double x4, double y4);

    AnnotCoord coord1, coord2, coord3, coord4;
  };

  AnnotQuadrilaterals(Array *array, PDFRectangle *rect);
  AnnotQuadrilaterals(std::unique_ptr<AnnotQuadrilateral[]> &&quads, int quadsLength);
  ~AnnotQuadrilaterals();

  AnnotQuadrilaterals(const AnnotQuadrilaterals &) = delete;
  AnnotQuadrilaterals& operator=(const AnnotQuadrilaterals &other) = delete;

  double getX1(int quadrilateral);
  double getY1(int quadrilateral);
  double getX2(int quadrilateral);
  double getY2(int quadrilateral);
  double getX3(int quadrilateral);
  double getY3(int quadrilateral);
  double getX4(int quadrilateral);
  double getY4(int quadrilateral);
  int getQuadrilateralsLength() const { return quadrilateralsLength; }
protected:

  std::unique_ptr<AnnotQuadrilateral[]> quadrilaterals;
  int quadrilateralsLength;
};

//------------------------------------------------------------------------
// AnnotBorder
//------------------------------------------------------------------------

class AnnotBorder {
public:
  enum AnnotBorderType {
    typeArray,
    typeBS
  };

  enum AnnotBorderStyle {
    borderSolid,      // Solid
    borderDashed,     // Dashed
    borderBeveled,    // Beveled
    borderInset,      // Inset
    borderUnderlined  // Underlined
  };

  virtual ~AnnotBorder();

  AnnotBorder(const AnnotBorder &) = delete;
  AnnotBorder& operator=(const AnnotBorder &other) = delete;

  virtual void setWidth(double new_width) { width = new_width; }

  virtual AnnotBorderType getType() const = 0;
  virtual double getWidth() const { return width; }
  virtual int getDashLength() const { return dashLength; }
  virtual double *getDash() const { return dash; }
  virtual AnnotBorderStyle getStyle() const { return style; }

  virtual Object writeToObject(XRef *xref) const = 0;

protected:
  AnnotBorder();

  bool parseDashArray(Object *dashObj);

  AnnotBorderType type;
  double width;
  static const int DASH_LIMIT = 10; // implementation note 82 in Appendix H.
  int dashLength;
  double *dash;
  AnnotBorderStyle style;
};

//------------------------------------------------------------------------
// AnnotBorderArray
//------------------------------------------------------------------------

class AnnotBorderArray: public AnnotBorder {
public:
  AnnotBorderArray();
  AnnotBorderArray(Array *array);

  void setHorizontalCorner(double hc) { horizontalCorner = hc; }
  void setVerticalCorner(double vc) { verticalCorner = vc; }

  double getHorizontalCorner() const { return horizontalCorner; }
  double getVerticalCorner() const { return verticalCorner; }

private:
  AnnotBorderType getType() const override { return typeArray; }
  Object writeToObject(XRef *xref) const override;

  double horizontalCorner;          // (Default 0)
  double verticalCorner;            // (Default 0)
  // double width;                  // (Default 1)  (inherited from AnnotBorder)
};

//------------------------------------------------------------------------
// AnnotBorderBS
//------------------------------------------------------------------------

class AnnotBorderBS: public AnnotBorder {
public:

  AnnotBorderBS();
  AnnotBorderBS(Dict *dict);

private:
  AnnotBorderType getType() const override { return typeBS; }
  Object writeToObject(XRef *xref) const override;

  const char *getStyleName() const;

  // double width;           // W  (Default 1)   (inherited from AnnotBorder)
  // AnnotBorderStyle style; // S  (Default S)   (inherited from AnnotBorder)
  // double *dash;           // D  (Default [3]) (inherited from AnnotBorder)
};

//------------------------------------------------------------------------
// AnnotColor
//------------------------------------------------------------------------

class AnnotColor {
public:

  enum AnnotColorSpace {
    colorTransparent = 0,
    colorGray        = 1,
    colorRGB         = 3,
    colorCMYK        = 4
  };

  AnnotColor();
  AnnotColor(double gray);
  AnnotColor(double r, double g, double b);
  AnnotColor(double c, double m, double y, double k);
  AnnotColor(Array *array, int adjust = 0);

  void adjustColor(int adjust);

  AnnotColorSpace getSpace() const { return (AnnotColorSpace) length; }
  const double *getValues() const { return values; }

  Object writeToObject(XRef *xref) const;

private:

  double values[4];
  int length;
};

//------------------------------------------------------------------------
// DefaultAppearance
//------------------------------------------------------------------------

class DefaultAppearance {
public:

  DefaultAppearance(Object &&fontNameA, double fontPtSizeA, std::unique_ptr<AnnotColor> fontColorA);
  DefaultAppearance(GooString *da);
  void setFontName(Object &&fontNameA);
  const Object &getFontName() const { return fontName; }
  void setFontPtSize(double fontPtSizeA);
  double getFontPtSize() const { return fontPtSize; }
  void setFontColor(std::unique_ptr<AnnotColor> fontColorA);
  const AnnotColor *getFontColor() const { return fontColor.get(); }
  GooString *toAppearanceString() const;

  DefaultAppearance(const DefaultAppearance &) = delete;
  DefaultAppearance& operator=(const DefaultAppearance&) = delete;

private:

  Object fontName;
  double fontPtSize;
  std::unique_ptr<AnnotColor> fontColor;
};

//------------------------------------------------------------------------
// AnnotIconFit
//------------------------------------------------------------------------

class AnnotIconFit {
public:

  enum AnnotIconFitScaleWhen {
    scaleAlways,  // A
    scaleBigger,  // B
    scaleSmaller, // S
    scaleNever    // N
  };

  enum AnnotIconFitScale {
    scaleAnamorphic,  // A
    scaleProportional // P
  };

  AnnotIconFit(Dict *dict);

  AnnotIconFitScaleWhen getScaleWhen() { return scaleWhen; }
  AnnotIconFitScale getScale() { return scale; }
  double getLeft() { return left; }
  double getBottom() { return bottom; }
  bool getFullyBounds() { return fullyBounds; }

protected:

  AnnotIconFitScaleWhen scaleWhen;  // SW (Default A)
  AnnotIconFitScale scale;          // S  (Default P)
  double left;                      // A  (Default [0.5 0.5]
  double bottom;                    // Only if scale is P
  bool fullyBounds;                 // FB (Default false)
};

//------------------------------------------------------------------------
// AnnotAppearance
//------------------------------------------------------------------------

class AnnotAppearance {
public:

  enum AnnotAppearanceType {
    appearNormal,
    appearRollover,
    appearDown
  };

  AnnotAppearance(PDFDoc *docA, Object *dict);
  ~AnnotAppearance();

  // State is ignored if no subdictionary is present
  Object getAppearanceStream(AnnotAppearanceType type, const char *state);

  // Access keys in normal appearance subdictionary (N)
  std::unique_ptr<GooString> getStateKey(int i);
  int getNumStates();

  // Removes all associated streams in the xref table. Caller is required to
  // reset parent annotation's AP and AS after this call.
  void removeAllStreams();

  // Test if this AnnotAppearance references the specified stream
  bool referencesStream(Ref targetStreamRef);

private:
  static bool referencesStream(Object *stateObj, Ref targetStreamRef);
  void removeStream(Ref refToStream);
  void removeStateStreams(Object *state);

protected:
  PDFDoc *doc;
  XRef *xref;                   // the xref table for this PDF file
  Object appearDict;            // Annotation's AP
};

//------------------------------------------------------------------------
// AnnotAppearanceCharacs
//------------------------------------------------------------------------

class AnnotAppearanceCharacs {
public:

  enum AnnotAppearanceCharacsTextPos {
    captionNoIcon,    // 0
    captionNoCaption, // 1
    captionBelow,     // 2
    captionAbove,     // 3
    captionRight,     // 4
    captionLeft,      // 5
    captionOverlaid   // 6
  };

  AnnotAppearanceCharacs(Dict *dict);
  ~AnnotAppearanceCharacs();

  AnnotAppearanceCharacs(const AnnotAppearanceCharacs &) = delete;
  AnnotAppearanceCharacs& operator=(const AnnotAppearanceCharacs &) = delete;

  int getRotation() const { return rotation; }
  const AnnotColor *getBorderColor() const { return borderColor.get(); }
  const AnnotColor *getBackColor() const { return backColor.get(); }
  const GooString *getNormalCaption() const { return normalCaption.get(); }
  const GooString *getRolloverCaption() { return rolloverCaption.get(); }
  const GooString *getAlternateCaption() { return alternateCaption.get(); }
  const AnnotIconFit *getIconFit() { return iconFit.get(); }
  AnnotAppearanceCharacsTextPos getPosition() const { return position; }

protected:

  int rotation;                                // R  (Default 0)
  std::unique_ptr<AnnotColor> borderColor;     // BC
  std::unique_ptr<AnnotColor> backColor;       // BG
  std::unique_ptr<GooString> normalCaption;    // CA
  std::unique_ptr<GooString> rolloverCaption;  // RC
  std::unique_ptr<GooString> alternateCaption; // AC
  // I
  // RI
  // IX
  std::unique_ptr<AnnotIconFit> iconFit;       // IF
  AnnotAppearanceCharacsTextPos position;      // TP (Default 0)
};

//------------------------------------------------------------------------
// AnnotAppearanceBBox
//------------------------------------------------------------------------

class AnnotAppearanceBBox
{
public:
  AnnotAppearanceBBox(PDFRectangle *init);

  void setBorderWidth(double w) { borderWidth = w; }

  // The following functions operate on coords relative to [origX origY]
  void extendTo(double x, double y);
  void getBBoxRect(double bbox[4]) const;

  // Get boundaries in page coordinates
  double getPageXMin() const;
  double getPageYMin() const;
  double getPageXMax() const;
  double getPageYMax() const;

private:
  double origX, origY, borderWidth;
  double minX, minY, maxX, maxY;
};

//------------------------------------------------------------------------
// AnnotAppearanceBuilder
//------------------------------------------------------------------------

class AnnotAppearanceBuilder {
public:
  AnnotAppearanceBuilder();
  ~AnnotAppearanceBuilder();

  AnnotAppearanceBuilder(const AnnotAppearanceBuilder &) = delete;
  AnnotAppearanceBuilder& operator=(const AnnotAppearanceBuilder &) = delete;

  void setDrawColor(const AnnotColor *color, bool fill);
  void setLineStyleForBorder(const AnnotBorder *border);
  void setTextFont(const Object &fontName, double fontSize);
  void drawCircle(double cx, double cy, double r, bool fill);
  void drawCircleTopLeft(double cx, double cy, double r);
  void drawCircleBottomRight(double cx, double cy, double r);
  void drawFieldBorder(const FormField *field, const AnnotBorder *border, const AnnotAppearanceCharacs *appearCharacs, const PDFRectangle *rect);
  bool drawFormField(const FormField *field, const Form *form, const GfxResources *resources, const GooString *da, const AnnotBorder *border, const AnnotAppearanceCharacs *appearCharacs, const PDFRectangle *rect, const GooString *appearState, XRef *xref, bool *addedDingbatsResource);

  void writeString(const GooString &str);

  void append(const char *text);
  void appendf(const char *fmt, ...) GOOSTRING_FORMAT;

  const GooString *buffer() const;

private:
  bool drawListBox(const FormFieldChoice *fieldChoice, const AnnotBorder *border, const PDFRectangle *rect,
		   const GooString *da, const GfxResources *resources, int quadding);
  bool drawFormFieldButton(const FormFieldButton *field, const GfxResources *resources, const GooString *da, const AnnotBorder *border, const AnnotAppearanceCharacs *appearCharacs, const PDFRectangle *rect, const GooString *appearState, XRef *xref, bool *addedDingbatsResource);
  bool drawFormFieldText(const FormFieldText *fieldText, const Form *form, const GfxResources *resources, const GooString *da, const AnnotBorder *border, const AnnotAppearanceCharacs *appearCharacs, const PDFRectangle *rect);
  bool drawFormFieldChoice(const FormFieldChoice *fieldChoice, const Form *form, const GfxResources *resources, const GooString *da, const AnnotBorder *border, const AnnotAppearanceCharacs *appearCharacs, const PDFRectangle *rect);
  bool drawText(const GooString *text, const GooString *da, const GfxResources *resources,
		const AnnotBorder *border, const AnnotAppearanceCharacs *appearCharacs, const PDFRectangle *rect,
		bool multiline, int comb, int quadding,
		bool txField, bool forceZapfDingbats,
		XRef *xref, bool *addedDingbatsResource, // xref and addedDingbatsResource both must not be null if forceZapfDingbats is passed
		bool password);

  GooString *appearBuf;
};

//------------------------------------------------------------------------
// Annot
//------------------------------------------------------------------------

class Annot {
  friend class Annots;
  friend class Page;
public:
  enum AnnotFlag {
    flagUnknown        = 0x0000,
    flagInvisible      = 0x0001,
    flagHidden         = 0x0002,
    flagPrint          = 0x0004,
    flagNoZoom         = 0x0008,
    flagNoRotate       = 0x0010,
    flagNoView         = 0x0020,
    flagReadOnly       = 0x0040,
    flagLocked         = 0x0080,
    flagToggleNoView   = 0x0100,
    flagLockedContents = 0x0200
  };

  enum AnnotSubtype {
    typeUnknown,        //                 0
    typeText,           // Text            1
    typeLink,           // Link            2
    typeFreeText,       // FreeText        3
    typeLine,           // Line            4
    typeSquare,         // Square          5
    typeCircle,         // Circle          6
    typePolygon,        // Polygon         7
    typePolyLine,       // PolyLine        8
    typeHighlight,      // Highlight       9
    typeUnderline,      // Underline      10
    typeSquiggly,       // Squiggly       11
    typeStrikeOut,      // StrikeOut      12
    typeStamp,          // Stamp          13
    typeCaret,          // Caret          14
    typeInk,            // Ink            15
    typePopup,          // Popup          16
    typeFileAttachment, // FileAttachment 17
    typeSound,          // Sound          18
    typeMovie,          // Movie          19
    typeWidget,         // Widget         20
    typeScreen,         // Screen         21
    typePrinterMark,    // PrinterMark    22
    typeTrapNet,        // TrapNet        23
    typeWatermark,      // Watermark      24
    type3D,             // 3D             25
    typeRichMedia       // RichMedia      26
  };

  /**
   * Describes the additional actions of a screen or widget annotation.
   */
  enum AdditionalActionsType {
    actionCursorEntering, ///< Performed when the cursor enters the annotation's active area
    actionCursorLeaving,  ///< Performed when the cursor exists the annotation's active area
    actionMousePressed,   ///< Performed when the mouse button is pressed inside the annotation's active area
    actionMouseReleased,  ///< Performed when the mouse button is released inside the annotation's active area
    actionFocusIn,        ///< Performed when the annotation receives the input focus
    actionFocusOut,       ///< Performed when the annotation loses the input focus
    actionPageOpening,    ///< Performed when the page containing the annotation is opened
    actionPageClosing,    ///< Performed when the page containing the annotation is closed
    actionPageVisible,    ///< Performed when the page containing the annotation becomes visible
    actionPageInvisible   ///< Performed when the page containing the annotation becomes invisible
  };

  enum FormAdditionalActionsType {
    actionFieldModified,   ///< Performed when the when the user modifies the field
    actionFormatField,     ///< Performed before the field is formatted to display its value
    actionValidateField,   ///< Performed when the field value changes
    actionCalculateField,  ///< Performed when the field needs to be recalculated
  };

  Annot(PDFDoc *docA, PDFRectangle *rectA);
  Annot(PDFDoc *docA, Object *dictObject);
  Annot(PDFDoc *docA, Object *dictObject, Object *obj);
  bool isOk() { return ok; }

  void incRefCnt();
  void decRefCnt();

  virtual void draw(Gfx *gfx, bool printing);
  // Get the resource dict of the appearance stream
  virtual Object getAppearanceResDict();

  bool match(Ref *refA)
    { return ref.num == refA->num && ref.gen == refA->gen; }

  double getXMin();
  double getYMin();
  double getXMax();
  double getYMax();

  void setRect(PDFRectangle *rect);
  void setRect(double x1, double y1, double x2, double y2);

  // Sets the annot contents to new_content
  // new_content should never be NULL
  virtual void setContents(GooString *new_content);
  void setName(GooString *new_name);
  void setModified(GooString *new_date);
  void setFlags(Guint new_flags);

  void setBorder(std::unique_ptr<AnnotBorder> &&new_border);
  void setColor(std::unique_ptr<AnnotColor> &&new_color);

  void setAppearanceState(const char *state);

  // getters
  PDFDoc *getDoc() const { return doc; }
  XRef *getXRef() const { return xref; }
  bool getHasRef() const { return hasRef; }
  Ref getRef() const { return ref; }
  AnnotSubtype getType() const { return type; }
  PDFRectangle *getRect() const { return rect.get(); }
  void getRect(double *x1, double *y1, double *x2, double *y2) const;
  const GooString *getContents() const { return contents.get(); }
  int getPageNum() const { return page; }
  const GooString *getName() const { return name.get(); }
  const GooString *getModified() const { return modified.get(); }
  Guint getFlags() const { return flags; }
  AnnotAppearance *getAppearStreams() const { return appearStreams.get(); }
  const GooString *getAppearState() const { return appearState.get(); }
  AnnotBorder *getBorder() const { return border.get(); }
  AnnotColor *getColor() const { return color.get(); }
  int getTreeKey() const { return treeKey; }

  int getId() { return ref.num; }

  // Check if point is inside the annot rectangle.
  bool inRect(double x, double y) const;

  static void layoutText(const GooString *text, GooString *outBuf, int *i, const GfxFont *font,
		  double *width, double widthLimit, int *charCount,
		  bool noReencode);

private:
  void readArrayNum(Object *pdfArray, int key, double *value);
  // write vStr[i:j[ in appearBuf

  void initialize (PDFDoc *docA, Dict *dict);
  void setPage (int new_page, bool updateP); // Called by Page::addAnnot and Annots ctor


protected:
  virtual ~Annot();
  virtual void removeReferencedObjects(); // Called by Page::removeAnnot
  Object createForm(const GooString *appearBuf, double *bbox, bool transparencyGroup, Dict *resDict);
  Object createForm(const GooString *appearBuf, double *bbox, bool transparencyGroup, Object &&resDictObject); // overload to support incRef/decRef
  Dict *createResourcesDict(const char *formName, Object &&formStream, const char *stateName,
			   double opacity, const char *blendMode);
  bool isVisible(bool printing);
  int getRotation() const;

  // Updates the field key of the annotation dictionary
  // and sets M to the current time
  void update(const char *key, Object &&value);

  // Delete appearance streams and reset appearance state
  void invalidateAppearance();

  Object annotObj;

  std::atomic_int refCnt;
  
  // required data
  AnnotSubtype type;                                // Annotation type
  std::unique_ptr<PDFRectangle> rect;               // Rect

  // optional data
  std::unique_ptr<GooString> contents;              // Contents
  std::unique_ptr<GooString> name;                  // NM
  std::unique_ptr<GooString> modified;              // M
  int       page;                                   // P
  Guint flags;                                      // F (must be a 32 bit unsigned int)
  std::unique_ptr<AnnotAppearance> appearStreams;   // AP
  Object appearance;                                // a reference to the Form XObject stream
                                                    //   for the normal appearance
  std::unique_ptr<AnnotAppearanceBBox> appearBBox;  // BBox of generated appearance
  std::unique_ptr<GooString> appearState;           // AS
  int treeKey;                                      // Struct Parent;
  Object oc;                                        // OC

  PDFDoc *doc;
  XRef *xref;			// the xref table for this PDF file
  Ref ref;                      // object ref identifying this annotation
  std::unique_ptr<AnnotBorder> border;              // Border, BS
  std::unique_ptr<AnnotColor> color;                // C
  bool ok;

  bool hasRef;
  mutable std::recursive_mutex mutex;
};

//------------------------------------------------------------------------
// AnnotPopup
//------------------------------------------------------------------------

class AnnotPopup: public Annot {
public:
  AnnotPopup(PDFDoc *docA, PDFRectangle *rect);
  AnnotPopup(PDFDoc *docA, Object *dictObject, Object *obj);
  ~AnnotPopup();

  Object *getParentNF() { return &parent; }
  void setParent(Object *parentA);
  void setParent(Annot *parentA);
  bool getOpen() const { return open; }
  void setOpen(bool openA);

protected:
  void initialize(PDFDoc *docA, Dict *dict);

  Object parent; // Parent
  bool open;   // Open
};

//------------------------------------------------------------------------
// AnnotMarkup
//------------------------------------------------------------------------

class AnnotMarkup: public Annot {
public:
  enum  AnnotMarkupReplyType {
    replyTypeR,     // R
    replyTypeGroup  // Group
  };

  AnnotMarkup(PDFDoc *docA, PDFRectangle *rect);
  AnnotMarkup(PDFDoc *docA, Object *dictObject, Object *obj);
  ~AnnotMarkup();

  // getters
  const GooString *getLabel() const { return label.get(); }
  AnnotPopup *getPopup() const { return popup.get(); }
  double getOpacity() const { return opacity; }
  // getRC
  const GooString *getDate() const { return date.get(); }
  int getInReplyToID() const { return inReplyTo.num; }
  const GooString *getSubject() const { return subject.get(); }
  AnnotMarkupReplyType getReplyTo() const { return replyTo; }
  AnnotExternalDataType getExData() const { return exData; }

  // The annotation takes the ownership of new_popup
  void setPopup(std::unique_ptr<AnnotPopup> &&new_popup);
  void setLabel(GooString *new_label);
  void setOpacity(double opacityA);
  void setDate(GooString *new_date);

protected:
  void removeReferencedObjects() override;

  std::unique_ptr<GooString> label;   // T            (Default autor)
  std::unique_ptr<AnnotPopup> popup;  // Popup
  double opacity;                     // CA           (Default 1.0)
  // RC
  std::unique_ptr<GooString> date;    // CreationDate
  Ref inReplyTo;                      // IRT
  std::unique_ptr<GooString> subject; // Subj
  AnnotMarkupReplyType replyTo;       // RT           (Default R)
  // this object is overrided by the custom intent fields defined in some
  // annotation types.
  //GooString *intent;                // IT
  AnnotExternalDataType exData;       // ExData

private:
  void initialize(PDFDoc *docA, Dict *dict, Object *obj);
};

//------------------------------------------------------------------------
// AnnotText
//------------------------------------------------------------------------

class AnnotText: public AnnotMarkup {
public:
  enum AnnotTextState {
    stateUnknown,
    // Marked state model
    stateMarked,    // Marked
    stateUnmarked,  // Unmarked
    // Review state model
    stateAccepted,  // Accepted
    stateRejected,  // Rejected
    stateCancelled, // Cancelled
    stateCompleted, // Completed
    stateNone       // None
  };

  AnnotText(PDFDoc *docA, PDFRectangle *rect);
  AnnotText(PDFDoc *docA, Object *dictObject, Object *obj);
  ~AnnotText();

  void draw(Gfx *gfx, bool printing) override;

  // getters
  bool getOpen() const { return open; }
  const GooString *getIcon() const { return icon.get(); }
  AnnotTextState getState() const { return state; }

  void setOpen(bool openA);
  void setIcon(GooString *new_icon);

private:

  void initialize(PDFDoc *docA, Dict *dict);

  bool open;                       // Open       (Default false)
  std::unique_ptr<GooString> icon;  // Name       (Default Note)
  AnnotTextState state;             // State      (Default Umarked if
                                    //             StateModel Marked
                                    //             None if StareModel Review)
};

//------------------------------------------------------------------------
// AnnotMovie
//------------------------------------------------------------------------



class AnnotMovie: public Annot {
 public:
  AnnotMovie(PDFDoc *docA, PDFRectangle *rect, Movie *movieA);
  AnnotMovie(PDFDoc *docA, Object *dictObject, Object *obj);
  ~AnnotMovie();

  void draw(Gfx *gfx, bool printing) override;

  const GooString* getTitle() const { return title.get(); }
  Movie* getMovie() { return movie.get(); }

 private:
  void initialize(PDFDoc *docA, Dict *dict);

  std::unique_ptr<GooString> title; // T
  std::unique_ptr<Movie> movie;     // Movie + A
};


//------------------------------------------------------------------------
// AnnotScreen
//------------------------------------------------------------------------

class AnnotScreen: public Annot {
 public:

  AnnotScreen(PDFDoc *docA, PDFRectangle *rect);
  AnnotScreen(PDFDoc *docA, Object *dictObject, Object *obj);
  ~AnnotScreen();

  const GooString* getTitle() const { return title.get(); }

  AnnotAppearanceCharacs *getAppearCharacs() { return appearCharacs.get(); }
  LinkAction *getAction() { return action.get(); } // The caller should not delete the result
  LinkAction *getAdditionalAction(AdditionalActionsType type); // The caller should delete the result

 private:
  void initialize(PDFDoc *docA, Dict *dict);


  std::unique_ptr<GooString> title;                      // T

  std::unique_ptr<AnnotAppearanceCharacs> appearCharacs; // MK

  std::unique_ptr<LinkAction> action;                    // A
  Object additionalActions;                              // AA
};

//------------------------------------------------------------------------
// AnnotLink
//------------------------------------------------------------------------

class AnnotLink: public Annot {
public:

  enum AnnotLinkEffect {
    effectNone,     // N
    effectInvert,   // I
    effectOutline,  // O
    effectPush      // P
  };

  AnnotLink(PDFDoc *docA, PDFRectangle *rect);
  AnnotLink(PDFDoc *docA, Object *dictObject, Object *obj);
  ~AnnotLink();

  void draw(Gfx *gfx, bool printing) override;

  // getters
  LinkAction *getAction() const { return action.get(); }
  AnnotLinkEffect getLinkEffect() const { return linkEffect; }
  AnnotQuadrilaterals *getQuadrilaterals() const { return quadrilaterals.get(); }

protected:

  void initialize(PDFDoc *docA, Dict *dict);

  std::unique_ptr<LinkAction> action;                  // A, Dest
  AnnotLinkEffect linkEffect;                          // H          (Default I)
  //Dict *uriAction;                                   // PA

  std::unique_ptr<AnnotQuadrilaterals> quadrilaterals; // QuadPoints
};

//------------------------------------------------------------------------
// AnnotFreeText
//------------------------------------------------------------------------

class AnnotFreeText: public AnnotMarkup {
public:

  enum AnnotFreeTextQuadding {
    quaddingLeftJustified,  // 0
    quaddingCentered,       // 1
    quaddingRightJustified  // 2
  };

  enum AnnotFreeTextIntent {
    intentFreeText,           // FreeText
    intentFreeTextCallout,    // FreeTextCallout
    intentFreeTextTypeWriter  // FreeTextTypeWriter
  };

  AnnotFreeText(PDFDoc *docA, PDFRectangle *rect, const DefaultAppearance &da);
  AnnotFreeText(PDFDoc *docA, Object *dictObject, Object *obj);
  ~AnnotFreeText();

  void draw(Gfx *gfx, bool printing) override;
  Object getAppearanceResDict() override;
  void setContents(GooString *new_content) override;

  void setDefaultAppearance(const DefaultAppearance &da);
  void setQuadding(AnnotFreeTextQuadding new_quadding);
  void setStyleString(GooString *new_string);
  void setCalloutLine(AnnotCalloutLine *line);
  void setIntent(AnnotFreeTextIntent new_intent);

  // getters
  std::unique_ptr<DefaultAppearance> getDefaultAppearance() const;
  AnnotFreeTextQuadding getQuadding() const { return quadding; }
  // return rc
  const GooString *getStyleString() const { return styleString.get(); }
  AnnotCalloutLine *getCalloutLine() const {  return calloutLine.get(); }
  AnnotFreeTextIntent getIntent() const { return intent; }
  AnnotBorderEffect *getBorderEffect() const { return borderEffect.get(); }
  PDFRectangle *getRectangle() const { return rectangle.get(); }
  AnnotLineEndingStyle getEndStyle() const { return endStyle; }

protected:

  void initialize(PDFDoc *docA, Dict *dict);
  void generateFreeTextAppearance();

  // required
  std::unique_ptr<GooString> appearanceString;      // DA

  // optional
  AnnotFreeTextQuadding quadding;                   // Q  (Default 0)
  // RC
  std::unique_ptr<GooString> styleString;           // DS
  std::unique_ptr<AnnotCalloutLine> calloutLine;    // CL
  AnnotFreeTextIntent intent;                       // IT
  std::unique_ptr<AnnotBorderEffect> borderEffect;  // BE
  std::unique_ptr<PDFRectangle> rectangle;          // RD
  // inherited  from Annot
  // AnnotBorderBS border;                          // BS
  AnnotLineEndingStyle endStyle;                    // LE (Default None)
};

//------------------------------------------------------------------------
// AnnotLine
//------------------------------------------------------------------------

class AnnotLine: public AnnotMarkup {
public:

  enum AnnotLineIntent {
    intentLineArrow,    // LineArrow
    intentLineDimension // LineDimension
  };

  enum AnnotLineCaptionPos {
    captionPosInline, // Inline
    captionPosTop     // Top
  };

  AnnotLine(PDFDoc *docA, PDFRectangle *rect);
  AnnotLine(PDFDoc *docA, Object *dictObject, Object *obj);
  ~AnnotLine();

  void draw(Gfx *gfx, bool printing) override;
  Object getAppearanceResDict() override;
  void setContents(GooString *new_content) override;

  void setVertices(double x1, double y1, double x2, double y2);
  void setStartEndStyle(AnnotLineEndingStyle start, AnnotLineEndingStyle end);
  void setInteriorColor(std::unique_ptr<AnnotColor> &&new_color);
  void setLeaderLineLength(double len);
  void setLeaderLineExtension(double len);
  void setCaption(bool new_cap);
  void setIntent(AnnotLineIntent new_intent);

  // getters
  AnnotLineEndingStyle getStartStyle() const { return startStyle; }
  AnnotLineEndingStyle getEndStyle() const { return endStyle; }
  AnnotColor *getInteriorColor() const { return interiorColor.get(); }
  double getLeaderLineLength() const { return leaderLineLength; }
  double getLeaderLineExtension() const { return leaderLineExtension; }
  bool getCaption() const { return caption; }
  AnnotLineIntent getIntent() const { return intent; }
  double  getLeaderLineOffset() const { return leaderLineOffset; }
  AnnotLineCaptionPos getCaptionPos() const { return captionPos; }
  Dict *getMeasure() const { return measure; }
  double getCaptionTextHorizontal() const { return captionTextHorizontal; }
  double getCaptionTextVertical() const { return captionTextVertical; }
  double getX1() const { return coord1->getX(); }
  double getY1() const { return coord1->getY(); }
  double getX2() const { return coord2->getX(); }
  double getY2() const { return coord2->getY(); }

protected:

  void initialize(PDFDoc *docA, Dict *dict);
  void generateLineAppearance();

  // required
  std::unique_ptr<AnnotCoord> coord1;
  std::unique_ptr<AnnotCoord> coord2;

  // optional
  // inherited  from Annot
  // AnnotBorderBS border;                   // BS
  AnnotLineEndingStyle startStyle;           // LE       (Default [/None /None])
  AnnotLineEndingStyle endStyle;             //
  std::unique_ptr<AnnotColor> interiorColor; // IC
  double leaderLineLength;                   // LL       (Default 0)
  double leaderLineExtension;                // LLE      (Default 0)
  bool caption;                              // Cap      (Default false)
  AnnotLineIntent intent;                    // IT
  double leaderLineOffset;                   // LLO
  AnnotLineCaptionPos captionPos;            // CP       (Default Inline)
  Dict *measure;                             // Measure
  double captionTextHorizontal;              // CO       (Default [0, 0])
  double captionTextVertical;                //
};

//------------------------------------------------------------------------
// AnnotTextMarkup
//------------------------------------------------------------------------

class AnnotTextMarkup: public AnnotMarkup {
public:

  AnnotTextMarkup(PDFDoc *docA, PDFRectangle *rect, AnnotSubtype subType);
  AnnotTextMarkup(PDFDoc *docA, Object *dictObject, Object *obj);
  ~AnnotTextMarkup();

  void draw(Gfx *gfx, bool printing) override;

  // typeHighlight, typeUnderline, typeSquiggly or typeStrikeOut
  void setType(AnnotSubtype new_type);

  void setQuadrilaterals(AnnotQuadrilaterals *quadPoints);

  AnnotQuadrilaterals *getQuadrilaterals() const { return quadrilaterals.get(); }

protected:

  void initialize(PDFDoc *docA, Dict *dict);

  std::unique_ptr<AnnotQuadrilaterals> quadrilaterals; // QuadPoints
};

//------------------------------------------------------------------------
// AnnotStamp
//------------------------------------------------------------------------

class AnnotStamp: public AnnotMarkup {
public:

  AnnotStamp(PDFDoc *docA, PDFRectangle *rect);
  AnnotStamp(PDFDoc *docA, Object *dictObject, Object *obj);
  ~AnnotStamp();

  void setIcon(GooString *new_icon);

  // getters
  const GooString *getIcon() const { return icon.get(); }

private:

  void initialize(PDFDoc *docA, Dict *dict);

  std::unique_ptr<GooString> icon; // Name       (Default Draft)
};

//------------------------------------------------------------------------
// AnnotGeometry
//------------------------------------------------------------------------

class AnnotGeometry: public AnnotMarkup {
public:

  AnnotGeometry(PDFDoc *docA, PDFRectangle *rect, AnnotSubtype subType);
  AnnotGeometry(PDFDoc *docA, Object *dictObject, Object *obj);
  ~AnnotGeometry();

  void draw(Gfx *gfx, bool printing) override;

  void setType(AnnotSubtype new_type); // typeSquare or typeCircle
  void setInteriorColor(std::unique_ptr<AnnotColor> &&new_color);

  // getters
  AnnotColor *getInteriorColor() const { return interiorColor.get(); }
  AnnotBorderEffect *getBorderEffect() const { return borderEffect.get(); }
  PDFRectangle *getGeometryRect() const { return geometryRect.get(); }

private:

  void initialize(PDFDoc *docA, Dict *dict);

  std::unique_ptr<AnnotColor> interiorColor;       // IC
  std::unique_ptr<AnnotBorderEffect> borderEffect; // BE
  std::unique_ptr<PDFRectangle> geometryRect;      // RD (combined with Rect)
};

//------------------------------------------------------------------------
// AnnotPolygon
//------------------------------------------------------------------------

class AnnotPolygon: public AnnotMarkup {
public:

  enum AnnotPolygonIntent {
    polygonCloud,      // PolygonCloud
    polylineDimension, // PolyLineDimension
    polygonDimension   // PolygonDimension
  };

  AnnotPolygon(PDFDoc *docA, PDFRectangle *rect, AnnotSubtype subType);
  AnnotPolygon(PDFDoc *docA, Object *dictObject, Object *obj);
  ~AnnotPolygon();

  void draw(Gfx *gfx, bool printing) override;

  void setType(AnnotSubtype new_type); // typePolygon or typePolyLine
  void setVertices(AnnotPath *path);
  void setStartEndStyle(AnnotLineEndingStyle start, AnnotLineEndingStyle end);
  void setInteriorColor(std::unique_ptr<AnnotColor> &&new_color);
  void setIntent(AnnotPolygonIntent new_intent);

  // getters
  AnnotPath *getVertices() const { return vertices.get(); }
  AnnotLineEndingStyle getStartStyle() const { return startStyle; }
  AnnotLineEndingStyle getEndStyle() const { return endStyle; }
  AnnotColor *getInteriorColor() const { return interiorColor.get(); }
  AnnotBorderEffect *getBorderEffect() const { return borderEffect.get(); }
  AnnotPolygonIntent getIntent() const { return intent; }

private:

  void initialize(PDFDoc *docA, Dict *dict);

  // required
  std::unique_ptr<AnnotPath> vertices;              // Vertices

  // optional
  AnnotLineEndingStyle startStyle;                  // LE       (Default [/None /None])
  AnnotLineEndingStyle endStyle;                    //
  // inherited  from Annot
  // AnnotBorderBS border;                          // BS
  std::unique_ptr<AnnotColor> interiorColor;        // IC
  std::unique_ptr<AnnotBorderEffect> borderEffect;  // BE
  AnnotPolygonIntent intent;                        // IT
  // Measure
};

//------------------------------------------------------------------------
// AnnotCaret
//------------------------------------------------------------------------

class AnnotCaret: public AnnotMarkup {
public:

  enum AnnotCaretSymbol {
    symbolNone,     // None
    symbolP         // P
  };

  AnnotCaret(PDFDoc *docA, PDFRectangle *rect);
  AnnotCaret(PDFDoc *docA, Object *dictObject, Object *obj);
  ~AnnotCaret();

  void setSymbol(AnnotCaretSymbol new_symbol);

  // getters
  AnnotCaretSymbol getSymbol() const { return symbol; }
  PDFRectangle *getCaretRect() const { return caretRect.get(); }

private:

  void initialize(PDFDoc *docA, Dict *dict);

  AnnotCaretSymbol symbol;                 // Sy         (Default None)
  std::unique_ptr<PDFRectangle> caretRect; // RD (combined with Rect)
};

//------------------------------------------------------------------------
// AnnotInk
//------------------------------------------------------------------------

class AnnotInk: public AnnotMarkup {
public:

  AnnotInk(PDFDoc *docA, PDFRectangle *rect);
  AnnotInk(PDFDoc *docA, Object *dictObject, Object *obj);
  ~AnnotInk();

  void draw(Gfx *gfx, bool printing) override;

  void setInkList(AnnotPath **paths, int n_paths);

  // getters
  AnnotPath **getInkList() const { return inkList; }
  int getInkListLength() const { return inkListLength; }

private:

  void initialize(PDFDoc *docA, Dict *dict);
  void writeInkList(AnnotPath **paths, int n_paths, Array *dest_array);
  void parseInkList(Array *src_array);
  void freeInkList();

  // required
  AnnotPath **inkList;       // InkList
  int inkListLength;

  // optional
  // inherited from Annot
  // AnnotBorderBS border;  // BS
};

//------------------------------------------------------------------------
// AnnotFileAttachment
//------------------------------------------------------------------------

class AnnotFileAttachment: public AnnotMarkup {
public:

  AnnotFileAttachment(PDFDoc *docA, PDFRectangle *rect, GooString *filename);
  AnnotFileAttachment(PDFDoc *docA, Object *dictObject, Object *obj);
  ~AnnotFileAttachment();

  void draw(Gfx *gfx, bool printing) override;

  // getters
  Object *getFile() { return &file; }
  const GooString *getName() const { return name.get(); }

private:

  void initialize(PDFDoc *docA, Dict *dict);

  // required
  Object file;                      // FS

  // optional
  std::unique_ptr<GooString> name;  // Name
};

//------------------------------------------------------------------------
// AnnotSound
//------------------------------------------------------------------------

class AnnotSound: public AnnotMarkup {
public:

  AnnotSound(PDFDoc *docA, PDFRectangle *rect, Sound *soundA);
  AnnotSound(PDFDoc *docA, Object *dictObject, Object *obj);
  ~AnnotSound();

  void draw(Gfx *gfx, bool printing) override;

  // getters
  Sound *getSound() { return sound.get(); }
  const GooString *getName() const { return name.get(); }

private:

  void initialize(PDFDoc *docA, Dict *dict);

  // required
  std::unique_ptr<Sound> sound;    // Sound

  // optional
  std::unique_ptr<GooString> name; // Name
};

//------------------------------------------------------------------------
// AnnotWidget
//------------------------------------------------------------------------

class AnnotWidget: public Annot {
public:

  enum AnnotWidgetHighlightMode {
    highlightModeNone,    // N
    highlightModeInvert,  // I
    highlightModeOutline, // O
    highlightModePush     // P,T
  };

  AnnotWidget(PDFDoc *docA, Object *dictObject, Object *obj);
  AnnotWidget(PDFDoc *docA, Object *dictObject, Object *obj, FormField *fieldA);
  ~AnnotWidget();

  void draw(Gfx *gfx, bool printing) override;

  void generateFieldAppearance (bool *addDingbatsResource);
  void updateAppearanceStream ();

  AnnotWidgetHighlightMode getMode() { return mode; }
  AnnotAppearanceCharacs *getAppearCharacs() { return appearCharacs.get(); }
  LinkAction *getAction() { return action.get(); }  // The caller should not delete the result
  LinkAction *getAdditionalAction(AdditionalActionsType type); // The caller should delete the result
  LinkAction *getFormAdditionalAction(FormAdditionalActionsType type); // The caller should delete the result
  Dict *getParent() { return parent; }

private:

  void initialize(PDFDoc *docA, Dict *dict);

  Form *form;
  FormField *field;                                       // FormField object for this annotation
  AnnotWidgetHighlightMode mode;                          // H  (Default I)
  std::unique_ptr<AnnotAppearanceCharacs> appearCharacs;  // MK
  std::unique_ptr<LinkAction> action;                     // A
  Object additionalActions;                               // AA
  // inherited  from Annot
  // AnnotBorderBS border;                // BS
  Dict *parent;                           // Parent
  Ref updatedAppearanceStream; // {-1,-1} if updateAppearanceStream has never been called
};

//------------------------------------------------------------------------
// Annot3D
//------------------------------------------------------------------------

class Annot3D: public Annot {
  class Activation {
  public:
    enum ActivationATrigger {
      aTriggerUnknown,
      aTriggerPageOpened,  // PO
      aTriggerPageVisible, // PV
      aTriggerUserAction   // XA
    };

    enum ActivationAState {
      aStateUnknown,
      aStateEnabled, // I
      aStateDisabled // L
    };

    enum ActivationDTrigger {
      dTriggerUnknown,
      dTriggerPageClosed,    // PC
      dTriggerPageInvisible, // PI
      dTriggerUserAction     // XD
    };

    enum ActivationDState {
      dStateUnknown,
      dStateUninstantiaded, // U
      dStateInstantiated,   // I
      dStateLive            // L
    };

    Activation(Dict *dict);
  private:
    
    ActivationATrigger aTrigger;  // A   (Default XA)
    ActivationAState aState;      // AIS (Default L)
    ActivationDTrigger dTrigger;  // D   (Default PI)
    ActivationDState dState;      // DIS (Default U)
    bool displayToolbar;         // TB  (Default true)
    bool displayNavigation;      // NP  (Default false);
  };
public:

  Annot3D(PDFDoc *docA, PDFRectangle *rect);
  Annot3D(PDFDoc *docA, Object *dictObject, Object *obj);
  ~Annot3D();

  // getters

private:

  void initialize(PDFDoc *docA, Dict *dict);

  std::unique_ptr<Activation> activation;  // 3DA
};

//------------------------------------------------------------------------
// AnnotRichMedia
//------------------------------------------------------------------------

class AnnotRichMedia: public Annot {
public:
  class Params {
  public:
    Params(Dict *dict);
    ~Params();

    Params(const Params &) = delete;
    Params& operator=(const Params &) = delete;

    const GooString* getFlashVars() const;

  private:
    // optional
    std::unique_ptr<GooString> flashVars; // FlashVars
  };

  class Instance {
  public:
    enum Type {
      type3D,       // 3D
      typeFlash,    // Flash
      typeSound,    // Sound
      typeVideo     // Video
    };

    Instance(Dict *dict);
    ~Instance();

    Instance(const Instance &) = delete;
    Instance& operator=(const Instance &) = delete;

    Type getType() const;
    Params* getParams() const;

  private:
    // optional
    Type type;                      // Subtype
    std::unique_ptr<Params> params; // Params
  };

  class Configuration {
  public:
    enum Type {
      type3D,       // 3D
      typeFlash,    // Flash
      typeSound,    // Sound
      typeVideo     // Video
    };

    Configuration(Dict *dict);
    ~Configuration();

    Configuration(const Configuration &) = delete;
    Configuration& operator=(const Configuration &) = delete;

    Type getType() const;
    const GooString* getName() const;
    int getInstancesCount() const;
    Instance* getInstance(int index) const;

  private:
    // optional
    Type type;                       // Subtype
    std::unique_ptr<GooString> name; // Name
    Instance **instances;            // Instances
    int nInstances;
  };

  class Content;

  class Asset {
  public:
    Asset();
    ~Asset();

    Asset(const Asset &) = delete;
    Asset& operator=(const Asset &) = delete;

    const GooString* getName() const;
    Object* getFileSpec() const;

  private:
    friend class AnnotRichMedia::Content;

    std::unique_ptr<GooString> name;
    Object fileSpec;
  };

  class Content {
  public:
    Content(Dict *dict);
    ~Content();

    Content(const Content &) = delete;
    Content& operator=(const Content &) = delete;

    int getConfigurationsCount() const;
    Configuration* getConfiguration(int index) const;

    int getAssetsCount() const;
    Asset* getAsset(int index) const;

  private:
    // optional
    Configuration** configurations; // Configurations
    int nConfigurations;

    Asset **assets; // Assets
    int nAssets;
  };

  class Activation {
  public:
    enum Condition {
      conditionPageOpened,  // PO
      conditionPageVisible, // PV
      conditionUserAction   // XA
    };

    Activation(Dict *dict);

    Condition getCondition() const;

  private:
    // optional
    Condition condition;
  };

  class Deactivation {
  public:
    enum Condition {
      conditionPageClosed,    // PC
      conditionPageInvisible, // PI
      conditionUserAction     // XD
    };

    Deactivation(Dict *dict);

    Condition getCondition() const;

  private:
    // optional
    Condition condition;
  };

  class Settings {
  public:
    Settings(Dict *dict);
    ~Settings();

    Settings(const Settings &) = delete;
    Settings& operator=(const Settings &) = delete;

    Activation* getActivation() const;
    Deactivation* getDeactivation() const;

  private:
    // optional
    std::unique_ptr<Activation> activation;
    std::unique_ptr<Deactivation> deactivation;
  };

  AnnotRichMedia(PDFDoc *docA, PDFRectangle *rect);
  AnnotRichMedia(PDFDoc *docA, Object *dictObject, Object *obj);
  ~AnnotRichMedia();

  Content* getContent() const;

  Settings* getSettings() const;

private:
  void initialize(PDFDoc *docA, Dict *dict);

  // required
  std::unique_ptr<Content> content;     // RichMediaContent

  // optional
  std::unique_ptr<Settings> settings;   // RichMediaSettings
};


//------------------------------------------------------------------------
// Annots
//------------------------------------------------------------------------

class Annots {
public:

  // Build a list of Annot objects and call setPage on them
  Annots(PDFDoc *docA, int page, Object *annotsObj);

  ~Annots();

  Annots(const Annots &) = delete;
  Annots& operator=(const Annots &) = delete;

  // Iterate through list of annotations.
  int getNumAnnots() const { return annots.size(); }
  Annot *getAnnot(int i) { return annots[i]; }
  void appendAnnot(Annot *annot);
  bool removeAnnot(Annot *annot);

private:
  Annot* createAnnot(Object* dictObject, Object *obj);
  Annot *findAnnot(Ref *ref);

  PDFDoc *doc;
  std::vector<Annot*> annots;
};

#endif
