//========================================================================
//
// 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 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
//
// 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

#ifdef USE_GCC_PRAGMAS
#pragma interface
#endif

#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(AnnotCoord **coords, int coordLength);
  ~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) const;
  int getCoordsLength() const { return coordsLength; }
protected:
  AnnotCoord **coords;
  int coordsLength;

  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(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(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:

  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();

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

//------------------------------------------------------------------------
// 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)
  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
  GBool referencesStream(Ref targetStreamRef);

private:
  static GBool 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; }
  const AnnotColor *getBackColor() const { return backColor; }
  const GooString *getNormalCaption() const { return normalCaption; }
  const GooString *getRolloverCaption() const { return rolloverCaption; }
  const GooString *getAlternateCaption() const { return alternateCaption; }
  const AnnotIconFit *getIconFit() const { return iconFit; }
  AnnotAppearanceCharacsTextPos getPosition() const { return position; }

protected:

  int rotation;                           // R  (Default 0)
  AnnotColor *borderColor;                // BC
  AnnotColor *backColor;                  // BG
  GooString *normalCaption;               // CA
  GooString *rolloverCaption;             // RC
  GooString *alternateCaption;            // AC
  // I
  // RI
  // IX
  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, GBool fill);
  void setLineStyleForBorder(const AnnotBorder *border);
  void drawCircle(double cx, double cy, double r, GBool 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,
		GBool multiline, int comb, int quadding,
		GBool txField, GBool forceZapfDingbats,
		XRef *xref, bool *addedDingbatsResource, // xref and addedDingbatsResource both must not be null if forceZapfDingbats is passed
		GBool 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);
  GBool isOk() { return ok; }

  void incRefCnt();
  void decRefCnt();

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

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

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

  double getFontSize() { return fontSize; }

  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(AnnotBorder *new_border); // Takes ownership

  // The annotation takes the ownership of
  // new_color. 
  void setColor(AnnotColor *new_color);

  void setAppearanceState(const char *state);

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

  int getId() { return ref.num; }

  // Check if point is inside the annot rectangle.
  GBool 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,
		  GBool 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, GBool 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, GBool transparencyGroup, Dict *resDict);
  Dict *createResourcesDict(const char *formName, Object &&formStream, const char *stateName,
			   double opacity, const char *blendMode);
  GBool isVisible(GBool 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;

  int refCnt;
  
  // required data
  AnnotSubtype type;                // Annotation type
  PDFRectangle *rect;               // Rect

  // optional data
  GooString *contents;              // Contents
  GooString *name;                  // NM
  GooString *modified;              // M
  int       page;                   // P
  Guint flags;                      // F (must be a 32 bit unsigned int)
  AnnotAppearance *appearStreams;   // AP
  Object appearance;     // a reference to the Form XObject stream
                         //   for the normal appearance
  AnnotAppearanceBBox *appearBBox;  // BBox of generated appearance
  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
  AnnotBorder *border;          // Border, BS
  AnnotColor *color;            // C
  double fontSize; 
  GBool ok;

  bool hasRef;
#ifdef MULTITHREADED
  GooMutex mutex;
#endif
};

//------------------------------------------------------------------------
// 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);
  GBool getOpen() const { return open; }
  void setOpen(GBool openA);

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

  Object parent; // Parent
  GBool 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; }
  AnnotPopup *getPopup() const { return popup; }
  double getOpacity() const { return opacity; }
  // getRC
  const GooString *getDate() const { return date; }
  int getInReplyToID() const { return inReplyTo.num; }
  const GooString *getSubject() const { return subject; }
  AnnotMarkupReplyType getReplyTo() const { return replyTo; }
  AnnotExternalDataType getExData() const { return exData; }

  // The annotation takes the ownership of new_popup
  void setPopup(AnnotPopup *new_popup);
  void setLabel(GooString *new_label);
  void setOpacity(double opacityA);
  void setDate(GooString *new_date);

protected:
  void removeReferencedObjects() override;

  GooString *label;             // T            (Default autor)
  AnnotPopup *popup;            // Popup
  double opacity;               // CA           (Default 1.0)
  // RC
  GooString *date;              // CreationDate
  Ref inReplyTo;                // IRT
  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, GBool printing) override;

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

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

private:

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

  GBool open;                       // Open       (Default false)
  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, GBool printing) override;

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

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

  GooString* title;      // T
  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; }

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

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


  GooString* title;                      // T

  AnnotAppearanceCharacs* appearCharacs; // MK

  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, GBool printing) override;

  // getters
  LinkAction *getAction() const { return action; }
  AnnotLinkEffect getLinkEffect() const { return linkEffect; }
  Dict *getUriAction() const { return uriAction; }
  AnnotQuadrilaterals *getQuadrilaterals() const { return quadrilaterals; }

protected:

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

  LinkAction *action;                  // A, Dest
  AnnotLinkEffect linkEffect;          // H          (Default I)
  Dict *uriAction;                     // PA

  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, GooString *da);
  AnnotFreeText(PDFDoc *docA, Object *dictObject, Object *obj);
  ~AnnotFreeText();

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

  void setAppearanceString(GooString *new_string);
  void setQuadding(AnnotFreeTextQuadding new_quadding);
  void setStyleString(GooString *new_string);
  void setCalloutLine(AnnotCalloutLine *line);
  void setIntent(AnnotFreeTextIntent new_intent);

  // getters
  const GooString *getAppearanceString() const { return appearanceString; }
  AnnotFreeTextQuadding getQuadding() const { return quadding; }
  // return rc
  const GooString *getStyleString() const { return styleString; }
  AnnotCalloutLine *getCalloutLine() const {  return calloutLine; }
  AnnotFreeTextIntent getIntent() const { return intent; }
  AnnotBorderEffect *getBorderEffect() const { return borderEffect; }
  PDFRectangle *getRectangle() const { return rectangle; }
  AnnotLineEndingStyle getEndStyle() const { return endStyle; }

protected:

  void initialize(PDFDoc *docA, Dict *dict);
  static void parseAppearanceString(GooString *da, double &fontsize, AnnotColor* &fontcolor);
  void generateFreeTextAppearance();

  // required
  GooString *appearanceString;      // DA

  // optional
  AnnotFreeTextQuadding quadding;   // Q  (Default 0)
  // RC
  GooString *styleString;           // DS
  AnnotCalloutLine *calloutLine;    // CL
  AnnotFreeTextIntent intent;       // IT
  AnnotBorderEffect *borderEffect;  // BE
  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, GBool 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(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; }
  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
  AnnotCoord *coord1, *coord2;
  
  // optional
  // inherited  from Annot
  // AnnotBorderBS border;          // BS
  AnnotLineEndingStyle startStyle;  // LE       (Default [/None /None])
  AnnotLineEndingStyle endStyle;    //
  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, GBool printing) override;

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

  void setQuadrilaterals(AnnotQuadrilaterals *quadPoints);

  AnnotQuadrilaterals *getQuadrilaterals() const { return quadrilaterals; }

protected:

  void initialize(PDFDoc *docA, Dict *dict);
  
  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; }

private:

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

  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, GBool printing) override;

  void setType(AnnotSubtype new_type); // typeSquare or typeCircle
  void setInteriorColor(AnnotColor *new_color);

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

private:

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

  AnnotColor *interiorColor;        // IC
  AnnotBorderEffect *borderEffect;  // BE
  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, GBool printing) override;

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

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

private:

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

  // required
  AnnotPath *vertices;              // Vertices

  // optional
  AnnotLineEndingStyle startStyle;  // LE       (Default [/None /None])
  AnnotLineEndingStyle endStyle;    //
  // inherited  from Annot
  // AnnotBorderBS border;          // BS
  AnnotColor *interiorColor;        // IC
  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; }

private:

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

  AnnotCaretSymbol symbol;       // Sy         (Default None)
  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, GBool 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, GBool printing) override;

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

private:

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

  // required
  Object file;      // FS

  // optional
  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, GBool printing) override;

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

private:

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

  // required
  Sound *sound;                  // Sound

  // optional
  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, GBool printing) override;

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

  AnnotWidgetHighlightMode getMode() { return mode; }
  AnnotAppearanceCharacs *getAppearCharacs() { return appearCharacs; }
  LinkAction *getAction() { return action; }  // 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)
  AnnotAppearanceCharacs *appearCharacs;  // MK
  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)
    GBool displayToolbar;         // TB  (Default true)
    GBool 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);

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

    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
    Activation *activation;
    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
  Content *content;     // RichMediaContent

  // optional
  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() { return nAnnots; }
  Annot *getAnnot(int i) { return annots[i]; }
  void appendAnnot(Annot *annot);
  GBool removeAnnot(Annot *annot);

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

  PDFDoc *doc;
  Annot **annots;
  int nAnnots;
  int size;
};

#endif
