/* poppler-annotation.h: qt interface to poppler
 * Copyright (C) 2006-2008, 2012, 2013, 2018 Albert Astals Cid <aacid@kde.org>
 * Copyright (C) 2006, 2008 Pino Toscano <pino@kde.org>
 * Copyright (C) 2007, Brad Hards <bradh@frogmouth.net>
 * Copyright (C) 2010, Philip Lorenz <lorenzph+freedesktop@gmail.com>
 * Copyright (C) 2012, 2015, Tobias Koenig <tobias.koenig@kdab.com>
 * Copyright (C) 2012, Guillermo A. Amaral B. <gamaral@kde.org>
 * Copyright (C) 2012, 2013 Fabio D'Urso <fabiodurso@hotmail.it>
 * Copyright (C) 2013, Anthony Granger <grangeranthony@gmail.com>
 * Copyright (C) 2018, Dileep Sankhla <sankhla.dileep96@gmail.com>
 * Adapting code from
 *   Copyright (C) 2004 by Enrico Ros <eros.kde@email.it>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2, or (at your option)
 * any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
 */

#ifndef _POPPLER_ANNOTATION_H_
#define _POPPLER_ANNOTATION_H_

#include <QtCore/QDateTime>
#include <QtCore/QSharedDataPointer>
#include <QtCore/QLinkedList>
#include <QtCore/QList>
#include <QtCore/QPointF>
#include <QtCore/QRectF>
#include <QtCore/QScopedPointer>
#include <QtCore/QVector>
#include <QtGui/QColor>
#include <QtGui/QFont>
#include <QtXml/QDomDocument>
#include "poppler-export.h"

namespace Poppler {

class Annotation;
class AnnotationPrivate;
class TextAnnotationPrivate;
class LineAnnotationPrivate;
class GeomAnnotationPrivate;
class HighlightAnnotationPrivate;
class StampAnnotationPrivate;
class InkAnnotationPrivate;
class LinkAnnotationPrivate;
class CaretAnnotationPrivate;
class FileAttachmentAnnotationPrivate;
class SoundAnnotationPrivate;
class MovieAnnotationPrivate;
class ScreenAnnotationPrivate;
class WidgetAnnotationPrivate;
class RichMediaAnnotationPrivate;
class EmbeddedFile;
class Link;
class SoundObject;
class MovieObject;
class LinkRendition;
class Page;

/**
 * \short Helper class for (recursive) Annotation retrieval/storage.
 *
 */
class POPPLER_QT5_EXPORT AnnotationUtils
{
    public:
        /**
         * Restore an Annotation (with revisions if needed) from the DOM
         * element \p annElement.
         * \returns a pointer to the complete Annotation or 0 if element is
         * invalid.
         */
        static Annotation * createAnnotation( const QDomElement & annElement );

        /**
         * Save the Annotation \p ann as a child of \p annElement taking
         * care of saving all revisions if \p ann has any.
         */
        static void storeAnnotation( const Annotation * ann,
            QDomElement & annElement, QDomDocument & document );

        /**
         * Returns an element called \p name from the direct children of
         * \p parentNode or a null element if not found.
         */
        static QDomElement findChildElement( const QDomNode & parentNode,
            const QString & name );
};


/**
 * \short Annotation class holding properties shared by all annotations.
 *
 * An Annotation is an object (text note, highlight, sound, popup window, ..)
 * contained by a Page in the document.
 *
 * \warning Different Annotation objects might point to the same annotation.
 *
 * \section annotCreation How to add annotations
 *
 * Create an Annotation object of the desired subclass (for example
 * TextAnnotation) and set its properties:
 * @code
 * Poppler::TextAnnotation* myann = new Poppler::TextAnnotation(Poppler::TextAnnotation::InPlace);
 * myann->setBoundary(QRectF(0.1, 0.1, 0.2, 0.2)); // normalized coordinates: (0,0) is top-left, (1,1) is bottom-right
 * myann->setContents("Hello, world!");
 * @endcode
 * \note Always set a boundary rectangle, or nothing will be shown!
 *
 * Obtain a pointer to the Page where you want to add the annotation (refer to
 * \ref req for instructions) and add the annotation:
 * @code
 * Poppler::Page* mypage = ...;
 * mypage->addAnnotation(myann);
 * @endcode
 *
 * You can keep on editing the annotation after it has been added to the page:
 * @code
 * myann->setContents("World, hello!"); // Let's change text...
 * myann->setAuthor("Your name here");  // ...and set an author too
 * @endcode
 *
 * When you're done with editing the annotation, you must destroy the Annotation
 * object:
 * @code
 * delete myann;
 * @endcode
 *
 * Use the PDFConverter class to save the modified document.
 *
 * \section annotFixedRotation FixedRotation flag specifics
 *
 * According to the PDF specification, annotations whose
 * Annotation::FixedRotation flag is set must always be shown in their original
 * orientation, no matter what the current rendering rotation or the page's
 * Page::orientation() values are. In comparison with regular annotations, such
 * annotations should therefore be transformed by an extra rotation at rendering
 * time to "undo" such context-related rotations, which is equal to
 * <code>-(rendering_rotation + page_orientation)</code>. The rotation pivot
 * is the top-left corner of the boundary rectangle.
 *
 * In practice, %Poppler's \ref Page::renderToImage only "unrotates" the
 * page orientation, and does <b>not</b> unrotate the rendering rotation.
 * This ensures consistent renderings at different Page::Rotation values:
 * annotations are always positioned as if they were being positioned at the
 * default page orientation.
 *
 * Just like regular annotations, %Poppler Qt5 exposes normalized coordinates
 * relative to the page's default orientation. However, behind the scenes, the
 * coordinate system is different and %Poppler transparently transforms each
 * shape. If you never call either Annotation::setFlags or
 * Annotation::setBoundary, you don't need to worry about this; but if you do
 * call them, then you need to adhere to the following rules:
 *  - Whenever you toggle the Annotation::FixedRotation flag, you <b>must</b>
 *    set again the boundary rectangle first, and then you <b>must</b> set
 *    again any other geometry-related property.
 *  - Whenever you modify the boundary rectangle of an annotation whose
 *    Annotation::FixedRotation flag is set, you <b>must</b> set again any other
 *    geometry-related property.
 *
 * These two rules are necessary to make %Poppler's transparent coordinate
 * conversion work properly.
 */
class POPPLER_QT5_EXPORT Annotation
{
  friend class AnnotationUtils;
  friend class LinkMovie;
  friend class LinkRendition;

  public:
    // enum definitions
    /**
     * Annotation subclasses
     *
     * \sa subType()
     */
    // WARNING!!! oKular uses that very same values so if you change them notify the author!
    enum SubType
    {
        AText = 1,            ///< TextAnnotation
        ALine = 2,            ///< LineAnnotation
        AGeom = 3,            ///< GeomAnnotation
        AHighlight = 4,       ///< HighlightAnnotation
        AStamp = 5,           ///< StampAnnotation
        AInk = 6,             ///< InkAnnotation
        ALink = 7,            ///< LinkAnnotation
        ACaret = 8,           ///< CaretAnnotation
        AFileAttachment = 9,  ///< FileAttachmentAnnotation
        ASound = 10,          ///< SoundAnnotation
        AMovie = 11,          ///< MovieAnnotation
        AScreen = 12,         ///< ScreenAnnotation \since 0.20
        AWidget = 13,         ///< WidgetAnnotation \since 0.22
        ARichMedia = 14,      ///< RichMediaAnnotation \since 0.36
        A_BASE = 0
    };

    /**
     * Annotation flags
     *
     * They can be OR'd together (e.g. Annotation::FixedRotation | Annotation::DenyPrint).
     *
     * \sa flags(), setFlags(int)
     */
    // NOTE: Only flags that are known to work are documented
    enum Flag
    {
        Hidden = 1,                ///< Do not display or print the annotation
        FixedSize = 2,
        FixedRotation = 4,         ///< Do not rotate the annotation according to page orientation and rendering rotation \warning Extra care is needed with this flag: see \ref annotFixedRotation
        DenyPrint = 8,             ///< Do not print the annotation
        DenyWrite = 16,
        DenyDelete = 32,
        ToggleHidingOnMouse = 64,
        External = 128
    };

    enum LineStyle { Solid = 1, Dashed = 2, Beveled = 4, Inset = 8, Underline = 16 };
    enum LineEffect { NoEffect = 1, Cloudy = 2};
    enum RevScope { Root = 0 /** \since 0.20 */, Reply = 1, Group = 2, Delete = 4 };
    enum RevType { None = 1,  Marked = 2, Unmarked = 4,  Accepted = 8, Rejected = 16, Cancelled = 32, Completed = 64 };

    /**
     * Returns the author of the annotation.
     */
    QString author() const;
    /**
     * Sets a new author for the annotation.
     */
    void setAuthor( const QString &author );

    QString contents() const;
    void setContents( const QString &contents );

    /**
     * Returns the unique name (ID) of the annotation.
     */
    QString uniqueName() const;
    /**
     * Sets a new unique name for the annotation.
     *
     * \note no check of the new uniqueName is done
     */
    void setUniqueName( const QString &uniqueName );

    QDateTime modificationDate() const;
    void setModificationDate( const QDateTime &date );

    QDateTime creationDate() const;
    void setCreationDate( const QDateTime &date );

    /**
     * Returns this annotation's flags
     *
     * \sa Flag, setFlags(int)
     */
    int flags() const;
    /**
     * Sets this annotation's flags
     *
     * \sa Flag, flags(), \ref annotFixedRotation
     */
    void setFlags( int flags );

    /**
     * Returns this annotation's boundary rectangle in normalized coordinates
     *
     * \sa setBoundary(const QRectF&)
     */
    QRectF boundary() const;
    /**
     * Sets this annotation's boundary rectangle
     *
     * The boundary rectangle is the smallest rectangle that contains the
     * annotation.
     *
     * \warning This property is mandatory: you must always set this.
     *
     * \sa boundary(), \ref annotFixedRotation
     */
    void setBoundary( const QRectF &boundary );

    /**
     * \short Container class for Annotation style information
     *
     * \since 0.20
     */
    class POPPLER_QT5_EXPORT Style
    {
      public:
        Style();
        Style( const Style &other );
        Style& operator=( const Style &other );
        ~Style();

        // appearance properties
        QColor color() const;                     // black
        void setColor(const QColor &color);
        double opacity() const;                   // 1.0
        void setOpacity(double opacity);

        // pen properties
        double width() const;                     // 1.0
        void setWidth(double width);
        LineStyle lineStyle() const;              // LineStyle::Solid
        void setLineStyle(LineStyle style);
        double xCorners() const;                  // 0.0
        void setXCorners(double radius);
        double yCorners() const;                  // 0.0
        void setYCorners(double radius);
        const QVector<double>& dashArray() const; // [ 3 ]
        void setDashArray(const QVector<double> &array);

        // pen effects
        LineEffect lineEffect() const;            // LineEffect::NoEffect
        void setLineEffect(LineEffect effect);
        double effectIntensity() const;           // 1.0
        void setEffectIntensity(double intens);

      private:
        class Private;
        QSharedDataPointer<Private> d;
    };

    /// \since 0.20
    Style style() const;
    /// \since 0.20
    void setStyle( const Style& style );

    /**
     * \short Container class for Annotation pop-up window information
     *
     * \since 0.20
     */
    class POPPLER_QT5_EXPORT Popup
    {
      public:
        Popup();
        Popup( const Popup &other );
        Popup& operator=( const Popup &other );
        ~Popup();

        // window state (Hidden, FixedRotation, Deny* flags allowed)
        int flags() const;       // -1 (never initialized) -> 0 (if inited and shown)
        void setFlags( int flags );

        // geometric properties
        QRectF geometry() const; // no default
        void setGeometry( const QRectF &geom );

        // window contents/override properties
        QString title() const;   // '' text in the titlebar (overrides author)
        void setTitle( const QString &title );
        QString summary() const; // '' short description (displayed if not empty)
        void setSummary( const QString &summary );
        QString text() const;    // '' text for the window (overrides annot->contents)
        void setText( const QString &text );

      private:
        class Private;
        QSharedDataPointer<Private> d;
    };

    /// \since 0.20
    Popup popup() const;
    /// \warning Currently does nothing \since 0.20
    void setPopup( const Popup& popup );

    /// \since 0.20
    RevScope revisionScope() const; // Root

    /// \since 0.20
    RevType revisionType() const;   // None

    /**
     * Returns the revisions of this annotation
     *
     * \note The caller owns the returned annotations and they should
     *       be deleted when no longer required.
     *
     * \since 0.20
     */
    QList<Annotation*> revisions() const;

    /**
     * The type of the annotation.
     */
    virtual SubType subType() const = 0;

    /**
     * Destructor.
     */
    virtual ~Annotation();

    /**
     * Describes the flags from an annotations 'AA' dictionary.
     *
     * This flag is used by the additionalAction() method for ScreenAnnotation
     * and WidgetAnnotation.
     *
     * \since 0.22
     */
    enum AdditionalActionType
    {
        CursorEnteringAction, ///< Performed when the cursor enters the annotation's active area
        CursorLeavingAction,  ///< Performed when the cursor exists the annotation's active area
        MousePressedAction,   ///< Performed when the mouse button is pressed inside the annotation's active area
        MouseReleasedAction,  ///< Performed when the mouse button is released inside the annotation's active area
        FocusInAction,        ///< Performed when the annotation receives the input focus
        FocusOutAction,       ///< Performed when the annotation loses the input focus
        PageOpeningAction,    ///< Performed when the page containing the annotation is opened
        PageClosingAction,    ///< Performed when the page containing the annotation is closed
        PageVisibleAction,    ///< Performed when the page containing the annotation becomes visible
        PageInvisibleAction   ///< Performed when the page containing the annotation becomes invisible
    };

  protected:
    /// \cond PRIVATE
    Annotation( AnnotationPrivate &dd );
    Annotation( AnnotationPrivate &dd, const QDomNode &description );
    void storeBaseAnnotationProperties( QDomNode & parentNode, QDomDocument & document ) const;
    Q_DECLARE_PRIVATE( Annotation )
    QExplicitlySharedDataPointer<AnnotationPrivate> d_ptr;
    /// \endcond

  private:
    virtual void store( QDomNode & parentNode, QDomDocument & document ) const = 0;
    Q_DISABLE_COPY( Annotation )
};

/**
 * \short Annotation containing text.
 *
 * A text annotation is an object showing some text directly on the page, or
 * linked to the contents using an icon shown on a page.
 */
class POPPLER_QT5_EXPORT TextAnnotation : public Annotation
{
  friend class AnnotationUtils;
  friend class AnnotationPrivate;

  public:
    // local enums
    enum TextType { Linked, InPlace };
    enum InplaceIntent { Unknown, Callout, TypeWriter };

    TextAnnotation( TextType type );
    ~TextAnnotation();
    SubType subType() const override;

    /**
       The type of text annotation represented by this object
    */
    TextType textType() const;

    /**
       The name of the icon for this text annotation.

       Standard names for text annotation icons are:
       - Comment
       - Help
       - Insert
       - Key
       - NewParagraph
       - Note (this is the default icon to use)
       - Paragraph
    */
    QString textIcon() const;

    /**
       Set the name of the icon to use for this text annotation.

       \sa textIcon for the list of standard names
    */
    void setTextIcon( const QString &icon );

    QFont textFont() const;
    void setTextFont( const QFont &font );
    /// \since 0.69
    QColor textColor() const;
    /// \since 0.69
    void setTextColor( const QColor &color );

    int inplaceAlign() const;
    void setInplaceAlign( int align );

    QPointF calloutPoint( int id ) const;
    /// \since 0.20
    QVector<QPointF> calloutPoints() const;
    /// \since 0.20
    void setCalloutPoints( const QVector<QPointF> &points );

    InplaceIntent inplaceIntent() const;
    void setInplaceIntent( InplaceIntent intent );

  private:
    TextAnnotation( const QDomNode &node );
    TextAnnotation( TextAnnotationPrivate &dd );
    void store( QDomNode &parentNode, QDomDocument &document ) const override;
    void setTextType( TextType type );
    Q_DECLARE_PRIVATE( TextAnnotation )
    Q_DISABLE_COPY( TextAnnotation )
};

/**
 * \short Polygon/polyline annotation.
 *
 * This annotation represents a polygon (or polyline) to be drawn on a page.
 */
class POPPLER_QT5_EXPORT LineAnnotation : public Annotation
{
  friend class AnnotationUtils;
  friend class AnnotationPrivate;

  public:
    // local enums
    /// \since 0.20
    enum LineType { StraightLine, Polyline };
    enum TermStyle { Square, Circle, Diamond, OpenArrow, ClosedArrow, None,
                     Butt, ROpenArrow, RClosedArrow, Slash };
    enum LineIntent { Unknown, Arrow, Dimension, PolygonCloud };

    /// \since 0.20
    LineAnnotation( LineType type );
    ~LineAnnotation();
    SubType subType() const override;

    /// \since 0.20
    LineType lineType() const;

    QLinkedList<QPointF> linePoints() const;
    void setLinePoints( const QLinkedList<QPointF> &points );

    TermStyle lineStartStyle() const;
    void setLineStartStyle( TermStyle style );

    TermStyle lineEndStyle() const;
    void setLineEndStyle( TermStyle style );

    bool isLineClosed() const;
    void setLineClosed( bool closed );

    QColor lineInnerColor() const;
    void setLineInnerColor( const QColor &color );

    double lineLeadingForwardPoint() const;
    void setLineLeadingForwardPoint( double point );

    double lineLeadingBackPoint() const;
    void setLineLeadingBackPoint( double point );

    bool lineShowCaption() const;
    void setLineShowCaption( bool show );

    LineIntent lineIntent() const;
    void setLineIntent( LineIntent intent );

  private:
    LineAnnotation( const QDomNode &node );
    LineAnnotation( LineAnnotationPrivate &dd );
    void store( QDomNode &parentNode, QDomDocument &document ) const override;
    void setLineType( LineType type );
    Q_DECLARE_PRIVATE( LineAnnotation )
    Q_DISABLE_COPY( LineAnnotation )
};

/**
 * \short Geometric annotation.
 *
 * The geometric annotation represents a geometric figure, like a rectangle or
 * an ellipse.
 */
class POPPLER_QT5_EXPORT GeomAnnotation : public Annotation
{
  friend class AnnotationUtils;
  friend class AnnotationPrivate;

  public:
    GeomAnnotation();
    ~GeomAnnotation();
    SubType subType() const override;

    // common enums
    enum GeomType { InscribedSquare, InscribedCircle };

    GeomType geomType() const;
    void setGeomType( GeomType style );

    QColor geomInnerColor() const;
    void setGeomInnerColor( const QColor &color );

  private:
    GeomAnnotation( const QDomNode &node );
    GeomAnnotation( GeomAnnotationPrivate &dd );
    void store( QDomNode &parentNode, QDomDocument &document ) const override;
    Q_DECLARE_PRIVATE( GeomAnnotation )
    Q_DISABLE_COPY( GeomAnnotation )
};

/**
 * \short Text highlight annotation.
 *
 * The highlight annotation represents some areas of text being "highlighted".
 */
class POPPLER_QT5_EXPORT HighlightAnnotation : public Annotation
{
  friend class AnnotationUtils;
  friend class AnnotationPrivate;

  public:
    HighlightAnnotation();
    ~HighlightAnnotation();
    SubType subType() const override;

    /**
       The type of highlight
    */
    enum HighlightType { Highlight, ///< highlighter pen style annotation
			 Squiggly,  ///< jagged or squiggly underline
			 Underline, ///< straight line underline
			 StrikeOut  ///< straight line through-line
    };

    /**
       Structure corresponding to a QuadPoints array. This matches a
       quadrilateral that describes the area around a word (or set of
       words) that are to be highlighted.
    */
    struct Quad
    {
        QPointF         points[4];          // 8 valid coords
        bool            capStart;           // false (vtx 1-4) [K]
        bool            capEnd;             // false (vtx 2-3) [K]
        double          feather;            // 0.1 (in range 0..1) [K]
    };

    /**
       The type (style) of highlighting to use for this area
       or these areas.
    */
    HighlightType highlightType() const;

    /**
       Set the type of highlighting to use for the given area
       or areas.
    */
    void setHighlightType( HighlightType type );

    /**
       The list of areas to highlight.
    */
    QList< Quad > highlightQuads() const;

    /**
       Set the areas to highlight.
    */
    void setHighlightQuads( const QList< Quad > &quads );

  private:
    HighlightAnnotation( const QDomNode &node );
    HighlightAnnotation( HighlightAnnotationPrivate &dd );
    void store( QDomNode &parentNode, QDomDocument &document ) const override;
    Q_DECLARE_PRIVATE( HighlightAnnotation )
    Q_DISABLE_COPY( HighlightAnnotation )
};

/**
 * \short Stamp annotation.
 *
 * A simple annotation drawing a stamp on a page.
 */
class POPPLER_QT5_EXPORT StampAnnotation : public Annotation
{
  friend class AnnotationUtils;
  friend class AnnotationPrivate;

  public:
    StampAnnotation();
    ~StampAnnotation();
    SubType subType() const override;

    /**
       The name of the icon for this stamp annotation.

       Standard names for stamp annotation icons are:
       - Approved
       - AsIs
       - Confidential
       - Departmental
       - Draft (this is the default icon type)
       - Experimental
       - Expired
       - Final
       - ForComment
       - ForPublicRelease
       - NotApproved
       - NotForPublicRelease
       - Sold
       - TopSecret
    */
    QString stampIconName() const;

    /**
       Set the icon type for this stamp annotation.

       \sa stampIconName for the list of standard icon names
    */
    void setStampIconName( const QString &name );

  private:
    StampAnnotation( const QDomNode &node );
    StampAnnotation( StampAnnotationPrivate &dd );
    void store( QDomNode &parentNode, QDomDocument &document ) const override;
    Q_DECLARE_PRIVATE( StampAnnotation )
    Q_DISABLE_COPY( StampAnnotation )
};

/**
 * \short Ink Annotation.
 *
 * Annotation representing an ink path on a page.
 */
class POPPLER_QT5_EXPORT InkAnnotation : public Annotation
{
  friend class AnnotationUtils;
  friend class AnnotationPrivate;

  public:
    InkAnnotation();
    ~InkAnnotation();
    SubType subType() const override;

    QList< QLinkedList<QPointF> > inkPaths() const;
    void setInkPaths( const QList< QLinkedList<QPointF> > &paths );

  private:
    InkAnnotation( const QDomNode &node );
    void store( QDomNode &parentNode, QDomDocument &document ) const override;
    InkAnnotation(InkAnnotationPrivate &dd);
    Q_DECLARE_PRIVATE( InkAnnotation )
    Q_DISABLE_COPY( InkAnnotation )
};

class POPPLER_QT5_EXPORT LinkAnnotation : public Annotation
{
  friend class AnnotationUtils;
  friend class AnnotationPrivate;

  public:
    ~LinkAnnotation();
    SubType subType() const override;

    // local enums
    enum HighlightMode { None, Invert, Outline, Push };

    /** \since 0.20 */
    Link* linkDestination() const;
    void setLinkDestination( Link *link );

    HighlightMode linkHighlightMode() const;
    void setLinkHighlightMode( HighlightMode mode );

    QPointF linkRegionPoint( int id ) const;
    // TODO Next ABI break, remove ref from point
    void setLinkRegionPoint( int id, const QPointF &point );

  private:
    LinkAnnotation();
    LinkAnnotation( const QDomNode &node );
    LinkAnnotation( LinkAnnotationPrivate &dd );
    void store( QDomNode &parentNode, QDomDocument &document ) const override;
    Q_DECLARE_PRIVATE( LinkAnnotation )
    Q_DISABLE_COPY( LinkAnnotation )
};

/**
 * \short Caret annotation.
 *
 * The caret annotation represents a symbol to indicate the presence of text.
 */
class POPPLER_QT5_EXPORT CaretAnnotation : public Annotation
{
  friend class AnnotationUtils;
  friend class AnnotationPrivate;

  public:
    CaretAnnotation();
    ~CaretAnnotation();
    SubType subType() const override;

    /**
     * The symbols for the caret annotation.
     */
    enum CaretSymbol { None, P };

    CaretSymbol caretSymbol() const;
    void setCaretSymbol( CaretSymbol symbol );

  private:
    CaretAnnotation( const QDomNode &node );
    CaretAnnotation( CaretAnnotationPrivate &dd );
    void store( QDomNode &parentNode, QDomDocument &document ) const override;
    Q_DECLARE_PRIVATE( CaretAnnotation )
    Q_DISABLE_COPY( CaretAnnotation )
};

/**
 * \short File attachment annotation.
 *
 * The file attachment annotation represents a file embedded in the document.
 *
 * \since 0.10
 */
class POPPLER_QT5_EXPORT FileAttachmentAnnotation : public Annotation
{
  friend class AnnotationPrivate;

  public:
    ~FileAttachmentAnnotation();
    SubType subType() const override;

    /**
     * Returns the name of the icon of this annotation.
     */
    QString fileIconName() const;
    /**
     * Sets a new name for the icon of this annotation.
     */
    void setFileIconName( const QString &icon );

    /**
     * Returns the EmbeddedFile of this annotation.
     */
    EmbeddedFile* embeddedFile() const;
    /**
     * Sets a new EmbeddedFile for this annotation.
     *
     * \note FileAttachmentAnnotation takes ownership of the object
     */
    void setEmbeddedFile( EmbeddedFile *ef );

  private:
    FileAttachmentAnnotation();
    FileAttachmentAnnotation( const QDomNode &node );
    FileAttachmentAnnotation( FileAttachmentAnnotationPrivate &dd );
    void store( QDomNode &parentNode, QDomDocument &document ) const override;
    Q_DECLARE_PRIVATE( FileAttachmentAnnotation )
    Q_DISABLE_COPY( FileAttachmentAnnotation )
};

/**
 * \short Sound annotation.
 *
 * The sound annotation represents a sound to be played when activated.
 *
 * \since 0.10
 */
class POPPLER_QT5_EXPORT SoundAnnotation : public Annotation
{
  friend class AnnotationPrivate;

  public:
    ~SoundAnnotation();
    SubType subType() const override;

    /**
     * Returns the name of the icon of this annotation.
     */
    QString soundIconName() const;
    /**
     * Sets a new name for the icon of this annotation.
     */
    void setSoundIconName( const QString &icon );

    /**
     * Returns the SoundObject of this annotation.
     */
    SoundObject* sound() const;
    /**
     * Sets a new SoundObject for this annotation.
     *
     * \note SoundAnnotation takes ownership of the object
     */
    void setSound( SoundObject *ef );

  private:
    SoundAnnotation();
    SoundAnnotation( const QDomNode &node );
    SoundAnnotation( SoundAnnotationPrivate &dd );
    void store( QDomNode &parentNode, QDomDocument &document ) const override;
    Q_DECLARE_PRIVATE( SoundAnnotation )
    Q_DISABLE_COPY( SoundAnnotation )
};

/**
 * \short Movie annotation.
 *
 * The movie annotation represents a movie to be played when activated.
 *
 * \since 0.10
 */
class POPPLER_QT5_EXPORT MovieAnnotation : public Annotation
{
  friend class AnnotationPrivate;

  public:
    ~MovieAnnotation();
    SubType subType() const override;

    /**
     * Returns the MovieObject of this annotation.
     */
    MovieObject* movie() const;
    /**
     * Sets a new MovieObject for this annotation.
     *
     * \note MovieAnnotation takes ownership of the object
     */
    void setMovie( MovieObject *movie );

    /**
     * Returns the title of the movie of this annotation.
     */
    QString movieTitle() const;
    /**
     * Sets a new title for the movie of this annotation.
     */
    void setMovieTitle( const QString &title );

  private:
    MovieAnnotation();
    MovieAnnotation( const QDomNode &node );
    MovieAnnotation( MovieAnnotationPrivate &dd );
    void store( QDomNode &parentNode, QDomDocument &document ) const override;
    Q_DECLARE_PRIVATE( MovieAnnotation )
    Q_DISABLE_COPY( MovieAnnotation )
};

/**
 * \short Screen annotation.
 *
 * The screen annotation represents a screen to be played when activated.
 *
 * \since 0.20
 */
class POPPLER_QT5_EXPORT ScreenAnnotation : public Annotation
{
  friend class AnnotationPrivate;

  public:
    ~ScreenAnnotation();

    SubType subType() const override;

    /**
     * Returns the LinkRendition of this annotation.
     */
    LinkRendition* action() const;

    /**
     * Sets a new LinkRendition for this annotation.
     *
     * \note ScreenAnnotation takes ownership of the object
     */
    void setAction( LinkRendition *action );

    /**
     * Returns the title of the screen of this annotation.
     */
    QString screenTitle() const;

    /**
     * Sets a new title for the screen of this annotation.
     */
    void setScreenTitle( const QString &title );

    /**
     * Returns the additional action of the given @p type fo the annotation or
     * @c 0 if no action has been defined.
     *
     * \since 0.22
     */
    Link* additionalAction( AdditionalActionType type ) const;

  private:
    ScreenAnnotation();
    ScreenAnnotation( ScreenAnnotationPrivate &dd );
    void store( QDomNode &parentNode, QDomDocument &document ) const override; // stub
    Q_DECLARE_PRIVATE( ScreenAnnotation )
    Q_DISABLE_COPY( ScreenAnnotation )
};

/**
 * \short Widget annotation.
 *
 * The widget annotation represents a widget (form field) on a page.
 *
 * \note This class is just provided for consistency of the annotation API,
 *       use the FormField classes to get all the form-related information.
 *
 * \since 0.22
 */
class POPPLER_QT5_EXPORT WidgetAnnotation : public Annotation
{
  friend class AnnotationPrivate;

  public:
    ~WidgetAnnotation();

    SubType subType() const override;

    /**
     * Returns the additional action of the given @p type fo the annotation or
     * @c 0 if no action has been defined.
     *
     * \since 0.22
     */
    Link* additionalAction( AdditionalActionType type ) const;

  private:
    WidgetAnnotation();
    WidgetAnnotation( WidgetAnnotationPrivate &dd );
    void store( QDomNode &parentNode, QDomDocument &document ) const override; // stub
    Q_DECLARE_PRIVATE( WidgetAnnotation )
    Q_DISABLE_COPY( WidgetAnnotation )
};

/**
 * \short RichMedia annotation.
 *
 * The RichMedia annotation represents a video or sound on a page.
 *
 * \since 0.36
 */
class POPPLER_QT5_EXPORT RichMediaAnnotation : public Annotation
{
  friend class AnnotationPrivate;

  public:
    ~RichMediaAnnotation();

    SubType subType() const override;

    /**
     * The params object of a RichMediaAnnotation::Instance object.
     *
     * The params object provides media specific parameters, to play
     * back the media inside the PDF viewer.
     *
     * At the moment only parameters for flash player are supported.
     */
    class POPPLER_QT5_EXPORT Params
    {
      friend class AnnotationPrivate;

      public:
        Params();
        ~Params();

        /**
         * Returns the parameters for the flash player.
         */
        QString flashVars() const;

      private:
        void setFlashVars( const QString &flashVars );

        class Private;
        QScopedPointer<Private> d;
    };

    /**
     * The instance object of a RichMediaAnnotation::Configuration object.
     *
     * The instance object represents one media object, that should be shown
     * on the page. It has a media type and a Params object, to define the
     * media specific parameters.
     */
    class POPPLER_QT5_EXPORT Instance
    {
      friend class AnnotationPrivate;

      public:
        /**
         * Describes the media type of the instance.
         */
        enum Type
        {
          Type3D,     ///< A 3D media file.
          TypeFlash,  ///< A Flash media file.
          TypeSound,  ///< A sound media file.
          TypeVideo   ///< A video media file.
        };

        Instance();
        ~Instance();

        /**
         * Returns the media type of the instance.
         */
        Type type() const;

        /**
         * Returns the params object of the instance or @c 0 if it doesn't exist.
         */
        RichMediaAnnotation::Params* params() const;

      private:
        void setType( Type type );
        void setParams( RichMediaAnnotation::Params *params );

        class Private;
        QScopedPointer<Private> d;
    };

    /**
     * The configuration object of a RichMediaAnnotation::Content object.
     *
     * The configuration object provides access to the various Instance objects
     * of the rich media annotation.
     */
    class POPPLER_QT5_EXPORT Configuration
    {
      friend class AnnotationPrivate;

      public:
        /**
         * Describes the media type of the configuration.
         */
        enum Type
        {
          Type3D,     ///< A 3D media file.
          TypeFlash,  ///< A Flash media file.
          TypeSound,  ///< A sound media file.
          TypeVideo   ///< A video media file.
        };

        Configuration();
        ~Configuration();

        /**
         * Returns the media type of the configuration.
         */
        Type type() const;

        /**
         * Returns the name of the configuration.
         */
        QString name() const;

        /**
         * Returns the list of Instance objects of the configuration.
         */
        QList< RichMediaAnnotation::Instance* > instances() const;

      private:
        void setType( Type type );
        void setName( const QString &name );
        void setInstances( const QList< RichMediaAnnotation::Instance* > &instances );

        class Private;
        QScopedPointer<Private> d;
    };

    /**
     * The asset object of a RichMediaAnnotation::Content object.
     *
     * The asset object provides a mapping between identifier name, as
     * used in the flash vars string of RichMediaAnnotation::Params,  and the
     * associated file spec object.
     */
    class POPPLER_QT5_EXPORT Asset
    {
      friend class AnnotationPrivate;

      public:
        Asset();
        ~Asset();

        /**
         * Returns the identifier name of the asset.
         */
        QString name() const;

        /**
         * Returns the embedded file the asset points to.
         */
        EmbeddedFile* embeddedFile() const;

      private:
        void setName( const QString &name );
        void setEmbeddedFile( EmbeddedFile *embeddedFile );

        class Private;
        QScopedPointer<Private> d;
    };

    /**
     * The content object of a RichMediaAnnotation.
     *
     * The content object provides access to the list of configurations
     * and assets of the rich media annotation.
     */
    class POPPLER_QT5_EXPORT Content
    {
      friend class AnnotationPrivate;

      public:
        Content();
        ~Content();

        /**
         * Returns the list of configuration objects of the content object.
         */
        QList< RichMediaAnnotation::Configuration* > configurations() const;

        /**
         * Returns the list of asset objects of the content object.
         */
        QList< RichMediaAnnotation::Asset* > assets() const;

      private:
        void setConfigurations( const QList< RichMediaAnnotation::Configuration* > &configurations );
        void setAssets( const QList< RichMediaAnnotation::Asset* > &assets );

        class Private;
        QScopedPointer<Private> d;
    };

    /**
     * The activation object of the RichMediaAnnotation::Settings object.
     *
     * The activation object is a wrapper around the settings for the activation
     * state. At the moment it provides only the activation condition.
     */
    class POPPLER_QT5_EXPORT Activation
    {
      friend class AnnotationPrivate;

      public:
        /**
         * Describes the condition for activating the rich media.
         */
        enum Condition {
          PageOpened,   ///< Activate when page is opened.
          PageVisible,  ///< Activate when page becomes visible.
          UserAction    ///< Activate when user interacts with the annotation.
        };

        Activation();
        ~Activation();

        /**
         * Returns the activation condition.
         */
        Condition condition() const;

      private:
        void setCondition( Condition condition );

        class Private;
        QScopedPointer<Private> d;
    };

    /**
     * The deactivation object of the RichMediaAnnotation::Settings object.
     *
     * The deactivation object is a wrapper around the settings for the deactivation
     * state. At the moment it provides only the deactivation condition.
     */
    class POPPLER_QT5_EXPORT Deactivation
    {
      friend class AnnotationPrivate;

      public:
        /**
         * Describes the condition for deactivating the rich media.
         */
        enum Condition {
          PageClosed,     ///< Deactivate when page is closed.
          PageInvisible,  ///< Deactivate when page becomes invisible.
          UserAction      ///< Deactivate when user interacts with the annotation.
        };

        Deactivation();
        ~Deactivation();

        /**
         * Returns the deactivation condition.
         */
        Condition condition() const;

      private:
        void setCondition( Condition condition );

        class Private;
        QScopedPointer<Private> d;
    };

    /**
     * The settings object of a RichMediaAnnotation.
     *
     * The settings object provides access to the configuration objects
     * for annotation activation and deactivation.
     */
    class POPPLER_QT5_EXPORT Settings
    {
      friend class AnnotationPrivate;

      public:
        Settings();
        ~Settings();

        /**
         * Returns the Activation object of the settings object or @c 0 if it doesn't exist.
         */
        RichMediaAnnotation::Activation* activation() const;

        /**
         * Returns the Deactivation object of the settings object or @c 0 if it doesn't exist.
         */
        RichMediaAnnotation::Deactivation* deactivation() const;

      private:
        void setActivation( RichMediaAnnotation::Activation *activation );
        void setDeactivation( RichMediaAnnotation::Deactivation *deactivation );

        class Private;
        QScopedPointer<Private> d;
    };

    /**
     * Returns the Settings object of the rich media annotation or @c 0 if it doesn't exist.
     */
    RichMediaAnnotation::Settings* settings() const;

    /**
     * Returns the Content object of the rich media annotation or @c 0 if it doesn't exist.
     */
    RichMediaAnnotation::Content* content() const;

  private:
    void setSettings( RichMediaAnnotation::Settings *settings );
    void setContent( RichMediaAnnotation::Content *content );

    RichMediaAnnotation();
    RichMediaAnnotation( const QDomNode &node );
    RichMediaAnnotation( RichMediaAnnotationPrivate &dd );
    void store( QDomNode &parentNode, QDomDocument &document ) const override;
    Q_DECLARE_PRIVATE( RichMediaAnnotation )
    Q_DISABLE_COPY( RichMediaAnnotation )
};

}

#endif
