/* poppler-qt.h: qt interface to poppler
 * Copyright (C) 2005, Net Integration Technologies, Inc.
 * Copyright (C) 2005, 2007, Brad Hards <bradh@frogmouth.net>
 * Copyright (C) 2005-2008, Albert Astals Cid <aacid@kde.org>
 * Copyright (C) 2005, Stefan Kebekus <stefan.kebekus@math.uni-koeln.de>
 * Copyright (C) 2006-2008, Pino Toscano <pino@kde.org>
 *
 * 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_QT_H__
#define __POPPLER_QT_H__

#include "poppler-annotation.h"
#include "poppler-link.h"
#include "poppler-optcontent.h"
#include "poppler-page-transition.h"

#include <QtCore/QByteArray>
#include <QtCore/QDateTime>
#include <QtCore/QSet>
#include <QtXml/QDomDocument>
#include "poppler-export.h"

class EmbFile;
class Sound;
class AnnotMovie;

/**
   The %Poppler Qt4 binding.
*/
namespace Poppler {

    class Document;
    class DocumentData;

    class PageData;

    class FormField;

    class TextBoxData;

    class PDFConverter;
    class PSConverter;

    /**
        Describes the physical location of text on a document page
       
        This very simple class describes the physical location of text
	on the page. It consists of
	- a QString that contains the text
	- a QRectF that gives a box that describes where on the page
	the text is found.
    */
    class POPPLER_QT4_EXPORT TextBox {
    friend class Page;
    public:
      /**
	 The default constructor sets the \p text and the rectangle that
	 contains the text. Coordinated for the \p bBox are in points =
	 1/72 of an inch.
      */
      TextBox(const QString& text, const QRectF &bBox);
      /**
	Destructor.
      */
      ~TextBox();

      /**
	  Returns the text of this text box
      */
      QString text() const;

      /**
	  Returns the position of the text, in point, i.e., 1/72 of
	 an inch

	 \since 0.8
      */
      QRectF boundingBox() const;

      /**
	  Returns the pointer to the next text box, if there is one.

	  Otherwise, it returns a null pointer.
      */
      TextBox *nextWord() const;

      /**
	  Returns the bounding box of the \p i -th characted of the word.
      */
      QRectF charBoundingBox(int i) const;

      /**
	  Returns whether there is a space character after this text box
      */
      bool hasSpaceAfter() const;

    private:
        Q_DISABLE_COPY(TextBox)

	TextBoxData *m_data;
    };


    class FontInfoData;
    /**
       Container class for information about a font within a PDF
       document
    */
    class POPPLER_QT4_EXPORT FontInfo {
    friend class Document;
    public:
	/**
	   The type of font.
	*/
	enum Type {
		unknown,
		Type1,
		Type1C,
		Type1COT,
		Type3,
		TrueType,
		TrueTypeOT,
		CIDType0,
		CIDType0C,
		CIDType0COT,
		CIDTrueType,
		CIDTrueTypeOT
	};
	
	/// \cond PRIVATE
	/**
	   Create a new font information container.
	*/
	FontInfo();
	
	/**
	   Create a new font information container.
	*/
	FontInfo( const FontInfoData &fid );
	/// \endcond
	
	/**
	   Copy constructor.
	*/
	FontInfo( const FontInfo &fi );
	
	/**
	   Destructor.
	*/
	~FontInfo();

	/**
	   The name of the font. Can be QString::null if the font has no name
	*/
	QString name() const;

	/**
	   The path of the font file used to represent this font on this system,
	   or a null string is the font is embedded
	*/
	QString file() const;

	/**
	   Whether the font is embedded in the file, or not

	   \return true if the font is embedded
	*/
	bool isEmbedded() const;

	/**
	   Whether the font provided is only a subset of the full
	   font or not. This only has meaning if the font is embedded.

	   \return true if the font is only a subset
	*/
	bool isSubset() const;

	/**
	   The type of font encoding

	   \return a enumerated value corresponding to the font encoding used

	   \sa typeName for a string equivalent
	*/
	Type type() const;

	/**
	   The name of the font encoding used

	   \note if you are looking for the name of the font (as opposed to the
	   encoding format used), you probably want name().

	   \sa type for a enumeration version
	*/
	QString typeName() const;

	/**
	   Standard assignment operator
	*/
	FontInfo& operator=( const FontInfo &fi );

    private:
	FontInfoData *m_data;
    };


    class EmbeddedFileData;
    /**
       Container class for an embedded file with a PDF document
    */
    class POPPLER_QT4_EXPORT EmbeddedFile {
    public:
	/// \cond PRIVATE
	EmbeddedFile(EmbFile *embfile);
	/// \endcond
	
	/**
	   Destructor.
	*/
	~EmbeddedFile();

	/**
	   The name associated with the file
	*/
	QString name() const;

	/**
	   The description associated with the file, if any.

	   This will return an empty QString if there is no description element
	*/
	QString description() const;

	/**
	   The size of the file.
	
	   This will return < 0 if there is no size element
	*/
	int size() const;

	/**
	   The modification date for the embedded file, if known.
	*/
	QDateTime modDate() const;

	/**
	   The creation date for the embedded file, if known.
	*/
	QDateTime createDate() const;
	
	/**
	   The MD5 checksum of the file.
		
	   This will return an empty QByteArray if there is no checksum element.
	*/
	QByteArray checksum() const;

	/**
	   The MIME type of the file, if known.
	
	   \since 0.8
	*/
	QString mimeType() const;

	/**
	   The data as a byte array
	*/
	QByteArray data();

	/**
	   A QDataStream for the actual data?
	*/
	//QDataStream dataStream() const;

    private:
	Q_DISABLE_COPY(EmbeddedFile)

	EmbeddedFileData *m_embeddedFile;
    };


    /**
       \brief A page in a document.

       The Page class represents a single page within a PDF document.

       You cannot construct a Page directly, but you have to use the Document
       functions that return a new Page out of an index or a label.
    */
    class POPPLER_QT4_EXPORT Page {
	friend class Document;
    public:
	/**
	   Destructor.
	*/
	~Page();

	/**
	   The type of rotation to apply for an operation
	*/
	enum Rotation { Rotate0 = 0,   ///< Do not rotate
			Rotate90 = 1,  ///< Rotate 90 degrees clockwise
			Rotate180 = 2, ///< Rotate 180 degrees
			Rotate270 = 3  ///< Rotate 270 degrees clockwise (90 degrees counterclockwise)
	};

	/**
	   The kinds of page actions
	*/
	enum PageAction {
	    Opening,   ///< The action when a page is "opened"
	    Closing    ///< The action when a page is "closed"
	};

	/** 
	   Render the page to a QImage using the current
	   \link Document::renderBackend() Document renderer\endlink.
	   
	   If \p x = \p y = \p w = \p h = -1, the method will automatically
           compute the size of the image from the horizontal and vertical
           resolutions specified in \p xres and \p yres. Otherwise, the
           method renders only a part of the page, specified by the
           parameters (\p x, \p y, \p w, \p h) in pixel coordinates. The returned
           QImage then has size (\p w, \p h), independent of the page
           size.

	   \param x specifies the left x-coordinate of the box, in
	   pixels.

	   \param y specifies the top y-coordinate of the box, in
	   pixels.

	   \param w specifies the width of the box, in pixels.

	   \param h specifies the height of the box, in pixels.

	   \param xres horizontal resolution of the graphics device,
	   in dots per inch

	   \param yres vertical resolution of the graphics device, in
	   dots per inch
	
	   \param rotate how to rotate the page

	   \warning The parameter (\p x, \p y, \p w, \p h) are not
	   well-tested. Unusual or meaningless parameters may lead to
	   rather unexpected results.

	   \returns a QImage of the page, or a null image on failure.

	   \since 0.6
        */
	QImage renderToImage(double xres=72.0, double yres=72.0, int x=-1, int y=-1, int w=-1, int h=-1, Rotation rotate = Rotate0) const;

	/**
	   Returns the text that is inside a specified rectangle

	   \param rect the rectangle specifying the area of interest,
	   with coordinates given in points, i.e., 1/72th of an inch.
	   If rect is null, all text on the page is given
	**/
	QString text(const QRectF &rect) const;
	
	/**
	   The starting point for a search
	*/
	enum SearchDirection { FromTop,        ///< Start sorting at the top of the document
			       NextResult,     ///< Find the next result, moving "down the page"
			       PreviousResult  ///< Find the previous result, moving "up the page"
	};

	/**
	   The type of search to perform
	*/
	enum SearchMode { CaseSensitive,   ///< Case differences cause no match in searching
			  CaseInsensitive  ///< Case differences are ignored in matching
	};
	
	/**
	   Returns true if the specified text was found.

	   \param text the text the search
	   \param rect in all directions is used to return where the text was found, for NextResult and PreviousResult
	               indicates where to continue searching for
	   \param direction in which direction do the search
	   \param caseSensitive be case sensitive?
	   \param rotate the rotation to apply for the search order
	**/
	bool search(const QString &text, QRectF &rect, SearchDirection direction, SearchMode caseSensitive, Rotation rotate = Rotate0) const;
	

	/**
	   Returns a list of text of the page

	   This method returns a QList of TextBoxes that contain all
	   the text of the page, with roughly one text word of text
	   per TextBox item.
	   
	   For text written in western languages (left-to-right and
	   up-to-down), the QList contains the text in the proper
	   order.

	   \note The caller owns the text boxes and they should
	         be deleted when no longer required.

	   \warning This method is not tested with Asian scripts
	*/
	QList<TextBox*> textList(Rotation rotate = Rotate0) const;

	/**
	   \return The dimensions of the page, in points (i.e. 1/72th on an inch)
	*/
	QSizeF pageSizeF() const;

	/**
	   \return The dimensions of the page, in points (i.e. 1/72th on an inch)
	*/
	QSize pageSize() const;

	/**
	  Returns the transition of this page

	  \returns a pointer to a PageTransition structure that
	  defines how transition to this page shall be performed.

	  \note The PageTransition structure is owned by this page, and will
	  automatically be destroyed when this page class is
	  destroyed.
	**/
	PageTransition *transition() const;
	
	/**
	  Gets the page action specified, or NULL if there is no action.

	  \since 0.6
	**/
	Link *action( PageAction act ) const;
	
	/**
	   Types of orientations that are possible
	*/
	enum Orientation {
	    Landscape, ///< Landscape orientation (portrait, with 90 degrees clockwise rotation )
	    Portrait, ///< Normal portrait orientation
	    Seascape, ///< Seascape orientation (portrait, with 270 degrees clockwise rotation)
	    UpsideDown ///< Upside down orientation (portrait, with 180 degrees rotation)
	};

	/**
	   The orientation of the page
	*/
	Orientation orientation() const;
	
	/**
	  The default CTM
	*/
	void defaultCTM(double *CTM, double dpiX, double dpiY, int rotate, bool upsideDown);
	
	/**
	  Gets the links of the page
	*/
	QList<Link*> links() const;
	
	/**
	 Returns the annotations of the page
	*/
	QList<Annotation*> annotations() const;

	/**
	 Returns the form fields on the page

	 \since 0.6
	*/
	QList<FormField*> formFields() const;

	/**
	 Returns the page duration. That is the time, in seconds, that the page
	 should be displayed before the presentation automatically advances to the next page.
	 Returns < 0 if duration is not set.

	 \since 0.6
	*/
	double duration() const;
	
	/**
	   Returns the label of the page, or a null string is the page has no label.

	 \since 0.6
	**/
	QString label() const;
	
    private:
	Q_DISABLE_COPY(Page)

	Page(DocumentData *doc, int index);
	PageData *m_page;
    };

/**
   \brief PDF document.

   The Document class represents a PDF document: its pages, and all the global
   properties, metadata, etc.

   \section ownership Ownership of the returned objects

   All the functions that returns class pointers create new object, and the
   responsability of those is given to the callee.

   The only exception is \link Poppler::Page::transition() Page::transition()\endlink.

   \section document-loading Loading

   To get a Document, you have to load it via the load() & loadFromData()
   functions.

   In all the functions that have passwords as arguments, they \b must be Latin1
   encoded. If you have a password that is a UTF-8 string, you need to use
   QString::toLatin1() (or similar) to convert the password first.
   If you have a UTF-8 character array, consider converting it to a QString first
   (QString::fromUtf8(), or similar) before converting to Latin1 encoding.

   \section document-rendering Rendering

   To render pages of a document, you have different Document functions to set
   various options.

   \subsection document-rendering-backend Backends

   %Poppler offers a different backends for rendering the pages. Currently
   there two backends (see #RenderBackend), but only the Splash engine works
   well and has been tested.

   The available rendering backends can be discovered via availableRenderBackends().
   The current rendering backend can be changed using setRenderBackend().
   Please note that setting a backend not listed in the available ones
   will always result in null QImage's.
*/
    class POPPLER_QT4_EXPORT Document {
	friend class Page;
	friend class DocumentData;
  
    public:
	/**
	   The page mode
	*/
	enum PageMode {
	    UseNone,     ///< No mode - neither document outline nor thumbnail images are visible
	    UseOutlines, ///< Document outline visible
	    UseThumbs,   ///< Thumbnail images visible
	    FullScreen,  ///< Fullscreen mode (no menubar, windows controls etc)
	    UseOC,       ///< Optional content group panel visible
	    UseAttach    ///< Attachments panel visible
	};
  
	/**
	   The page layout
	*/
	enum PageLayout {
	    NoLayout,   ///< Layout not specified
	    SinglePage, ///< Display a single page
	    OneColumn,  ///< Display a single column of pages
	    TwoColumnLeft, ///< Display the pages in two columns, with odd-numbered pages on the left
	    TwoColumnRight, ///< Display the pages in two columns, with odd-numbered pages on the right
	    TwoPageLeft, ///< Display the pages two at a time, with odd-numbered pages on the left
	    TwoPageRight ///< Display the pages two at a time, with odd-numbered pages on the right
	};

	/**
	   The render backends available

	   \since 0.6
	*/
	enum RenderBackend {
	    SplashBackend,   ///< Splash backend
	    ArthurBackend   ///< Arthur (Qt4) backend
	};

	/**
	   The render hints available

	   \since 0.6
	*/
	enum RenderHint {
	    Antialiasing = 0x00000001,      ///< Antialiasing for graphics
	    TextAntialiasing = 0x00000002   ///< Antialiasing for text
	};
	Q_DECLARE_FLAGS( RenderHints, RenderHint )

	/**
	   Load the document from a file on disk

	   \param filePath the name (and path, if required) of the file to load
	   \param ownerPassword the Latin1-encoded owner password to use in
	   loading the file
	   \param userPassword the Latin1-encoded user ("open") password
	   to use in loading the file

	   \return the loaded document, or NULL on error

	   \note The caller owns the pointer to Document, and this should
	   be deleted when no longer required.
	
	   \warning The returning document may be locked if a password is required
	   to open the file, and one is not provided (as the userPassword).
	*/
	static Document *load(const QString & filePath,
			      const QByteArray &ownerPassword=QByteArray(),
			      const QByteArray &userPassword=QByteArray());
	
	/**
	   Load the document from memory

	   \param fileContents the file contents. They are copied so there is no need 
	                       to keep the byte array around for the full life time of 
	                       the document.
	   \param ownerPassword the Latin1-encoded owner password to use in
	   loading the file
	   \param userPassword the Latin1-encoded user ("open") password
	   to use in loading the file

	   \return the loaded document, or NULL on error

	   \note The caller owns the pointer to Document, and this should
	   be deleted when no longer required.
	
	   \warning The returning document may be locked if a password is required
	   to open the file, and one is not provided (as the userPassword).

	   \since 0.6
	*/
	static Document *loadFromData(const QByteArray &fileContents,
			      const QByteArray &ownerPassword=QByteArray(),
			      const QByteArray &userPassword=QByteArray());
  
	/**
	   Get a specified Page
     
	   Note that this follows the PDF standard of being zero based - if you
	   want the first page, then you need an index of zero.

	   \param index the page number index
	*/
	Page *page(int index) const;

	/**
	   \overload


	   The intent is that you can pass in a label like \c "ix" and
	   get the page with that label (which might be in the table of
	   contents), or pass in \c "1" and get the page that the user
	   expects (which might not be the first page, if there is a
	   title page and a table of contents).

	   \param label the page label
	*/
	Page *page(const QString &label) const;

	/**
	   The number of pages in the document
	*/
	int numPages() const;
  
	/**
	   The type of mode that should be used by the application
	   when the document is opened. Note that while this is 
	   called page mode, it is really viewer application mode.
	*/
	PageMode pageMode() const;

	/**
	   The layout that pages should be shown in when the document
	   is first opened.  This basically describes how pages are
	   shown relative to each other.
	*/
	PageLayout pageLayout() const;

	/**
	   Provide the passwords required to unlock the document

	   \param ownerPassword the Latin1-encoded owner password to use in
	   loading the file
	   \param userPassword the Latin1-encoded user ("open") password
	   to use in loading the file
	*/
	bool unlock(const QByteArray &ownerPassword, const QByteArray &userPassword);

	/**
	   Determine if the document is locked
	*/
	bool isLocked() const;

	/**
	   The date associated with the document

	   You would use this method with something like:
	   \code
QDateTime created = m_doc->date("CreationDate");
QDateTime modified = m_doc->date("ModDate");
	   \endcode

	   The available dates are:
	   - CreationDate: the date of creation of the document
	   - ModDate: the date of the last change in the document

	   \param data the type of date that is required
	*/
	QDateTime date( const QString & data ) const;

	/**
	   Get specified information associated with the document

	   You would use this method with something like:
	   \code
QString title = m_doc->info("Title");
QString subject = m_doc->info("Subject");
	   \endcode

	   In addition to \c Title and \c Subject, other information that may
	   be available include \c Author, \c Keywords, \c Creator and \c Producer.

	   \param data the information that is required

	   \sa infoKeys() to get a list of the available keys
	*/
	QString info( const QString & data ) const;

	/**
	   Obtain a list of the available string information keys.
	*/
	QStringList infoKeys() const;

	/**
	   Test if the document is encrypted
	*/
	bool isEncrypted() const;

	/**
	   Test if the document is linearised

	   In some cases, this is called "fast web view", since it
	   is mostly an optimisation for viewing over the Web.
	*/
	bool isLinearized() const;

	/**
	   Test if the permissions on the document allow it to be
	   printed
	*/
	bool okToPrint() const;

	/**
	   Test if the permissions on the document allow it to be
	   printed at high resolution
	*/
	bool okToPrintHighRes() const;

	/**
	   Test if the permissions on the document allow it to be
	   changed.

	   \note depending on the type of change, it may be more
	   appropriate to check other properties as well.
	*/
	bool okToChange() const;

	/**
	   Test if the permissions on the document allow the
	   contents to be copied / extracted
	*/
	bool okToCopy() const;

	/**
	   Test if the permissions on the document allow annotations
	   to be added or modified, and interactive form fields (including
	   signature fields) to be completed.
	*/
	bool okToAddNotes() const;

	/**
	   Test if the permissions on the document allow interactive
	   form fields (including signature fields) to be completed.

	   \note this can be true even if okToAddNotes() is false - this
	   means that only form completion is permitted.
	*/
	bool okToFillForm() const;

	/**
	   Test if the permissions on the document allow interactive
	   form fields (including signature fields) to be set, created and
	   modified
	*/
	bool okToCreateFormFields() const;

	/**
	   Test if the permissions on the document allow content extraction
	   (text and perhaps other content) for accessibility usage (eg for
	   a screen reader)
	*/
	bool okToExtractForAccessibility() const;

	/**
	   Test if the permissions on the document allow it to be
	   "assembled" - insertion, rotation and deletion of pages;
	   or creation of bookmarks and thumbnail images.

	   \note this can be true even if okToChange() is false
	*/
	bool okToAssemble() const;

	/**
	   The version of the PDF specification that the document
	   conforms to
	*/
	double pdfVersion() const;
  
	/**
	   The fonts within the PDF document.

	   \note this can take a very long time to run with a large
	   document. You may wish to use the call below if you have more
	   than say 20 pages
	*/
	QList<FontInfo> fonts() const;

	/**
	   \overload


	   \param numPages the number of pages to scan
	   \param fontList pointer to the list where the font information
	   should be placed

	   \return false if the end of the document has been reached
	*/
	bool scanForFonts( int numPages, QList<FontInfo> *fontList ) const; 

	/**
	   The font data if the font is an embedded one.

	   \since 0.10
	*/
	QByteArray fontData(const FontInfo &font) const;

	/**
	   The documents embedded within the PDF document.

	   \note there are two types of embedded document - this call
	   only accesses documents that are embedded at the document level.
	*/
	QList<EmbeddedFile*> embeddedFiles() const;

	/**
	   Whether there are any documents embedded in this PDF document.
	*/
	bool hasEmbeddedFiles() const;
	
	/**
	  Gets the table of contents (TOC) of the Document.
	
	  The caller is responsable for the returned object.
	
	  In the tree the tag name is the 'screen' name of the entry. A tag can have
	  attributes. Here follows the list of tag attributes with meaning:
	  - Destination: A string description of the referred destination
	  - DestinationName: A 'named reference' to the viewport
	  - ExternalFileName: A link to a external filename
	  - Open: A bool value that tells whether the subbranch of the item is open or not
	
	  Resolving the final destination for each item can be done in the following way:
	  - first, checking for 'Destination': if not empty, then a LinkDestination
	    can be constructed straight with it
	  - as second step, if the 'DestinationName' is not empty, then the destination
	    can be resolved using linkDestination()
	
	  Note also that if 'ExternalFileName' is not emtpy, then the destination refers
	  to that document (and not to the current one).
	
	  \returns the TOC, or NULL if the Document does not have one
	*/
	QDomDocument *toc() const;
	
	/**
	   Tries to resolve the named destination \p name.
	
	   \note this operation starts a search through the whole document
	
	   \returns a new LinkDestination object if the named destination was
	   actually found, or NULL otherwise
	*/
	LinkDestination *linkDestination( const QString &name );
	
	/**
	  Sets the paper color

	  \param color the new paper color
	 */
	void setPaperColor(const QColor &color);
	/**
	  The paper color

	  The default color is white.
	 */
	QColor paperColor() const;

	/**
	 Sets the backend used to render the pages.

	 \param backend the new rendering backend

	 \since 0.6
	 */
	void setRenderBackend( RenderBackend backend );
	/**
	  The currently set render backend

	  The default backend is \ref SplashBackend

	  \since 0.6
	 */
	RenderBackend renderBackend() const;

	/**
	  The available rendering backends.

	  \since 0.6
	 */
	static QSet<RenderBackend> availableRenderBackends();

	/**
	 Sets the render \p hint .

	 \note some hints may not be supported by some rendering backends.

	 \param on whether the flag should be added or removed.

	 \since 0.6
	 */
	void setRenderHint( RenderHint hint, bool on = true );
	/**
	  The currently set render hints.

	  \since 0.6
	 */
	RenderHints renderHints() const;
	
	/**
	  Gets a new PS converter for this document.

	  The caller gets the ownership of the returned converter.

	  \since 0.6
	 */
	PSConverter *psConverter() const;
	
	/**
	  Gets a new PDF converter for this document.

	  The caller gets the ownership of the returned converter.

	  \since 0.8
	 */
	PDFConverter *pdfConverter() const;
	
	/**
	  Gets the metadata stream contents

	  \since 0.6
	*/
	QString metadata() const;

	/**
	   Test whether this document has "optional content".

	   Optional content is used to optionally turn on (display)
	   and turn off (not display) some elements of the document.
	   The most common use of this is for layers in design
	   applications, but it can be used for a range of things,
	   such as not including some content in printing, and
	   displaying content in the appropriate language.

	   \since 0.8
	*/
	bool hasOptionalContent() const;

	/**
	   Itemviews model for optional content.

	   The model is owned by the document.

	   \since 0.8
	*/
	OptContentModel *optionalContentModel();

	/**
	   Document-level JavaScript scripts.

	   Returns the list of document level JavaScript scripts to be always
	   executed before any other script.

	   \since 0.10
	*/
	QStringList scripts() const;

	/**
	   Destructor.
	*/
	~Document();
  
    private:
	Q_DISABLE_COPY(Document)

	DocumentData *m_doc;
	
	Document(DocumentData *dataA);
    };
    
    class BaseConverterPrivate;
    class PSConverterPrivate;
    class PDFConverterPrivate;
    /**
       \brief Base converter.

       This is the base class for the converters.

       \since 0.8
    */
    class POPPLER_QT4_EXPORT BaseConverter
    {
        friend class Document;
        public:
            /**
              Destructor.
            */
            virtual ~BaseConverter();

            /** Sets the output file name. You must set this or the output device. */
            void setOutputFileName(const QString &outputFileName);

            /**
             * Sets the output device. You must set this or the output file name.
             *
             * \since 0.8
             */
            void setOutputDevice(QIODevice *device);

            /**
              Does the conversion.

              \return whether the conversion succeeded
            */
            virtual bool convert() = 0;

        protected:
            /// \cond PRIVATE
            BaseConverter(BaseConverterPrivate &dd);
            Q_DECLARE_PRIVATE(BaseConverter)
            BaseConverterPrivate *d_ptr;
            /// \endcond

        private:
            Q_DISABLE_COPY(BaseConverter)
    };

    /**
       Converts a PDF to PS

       Sizes have to be in Points (1/72 inch)

       If you are using QPrinter you can get paper size by doing:
       \code
QPrinter dummy(QPrinter::PrinterResolution);
dummy.setFullPage(true);
dummy.setPageSize(myPageSize);
width = dummy.width();
height = dummy.height();
       \endcode

       \since 0.6
    */
    class POPPLER_QT4_EXPORT PSConverter : public BaseConverter
    {
        friend class Document;
        public:
            /**
              Options for the PS export.

              \since 0.10
             */
            enum PSOption {
                Printing = 0x00000001,              ///< The PS is generated for priting purpouses
                StrictMargins = 0x00000002,
                ForceRasterization = 0x00000004
            };
            Q_DECLARE_FLAGS( PSOptions, PSOption )

            /**
              Destructor.
            */
            ~PSConverter();

            /** Sets the list of pages to print. Mandatory. */
            void setPageList(const QList<int> &pageList);

            /**
              Sets the title of the PS Document. Optional
            */
            void setTitle(const QString &title);

            /**
              Sets the horizontal DPI. Defaults to 72.0
            */
            void setHDPI(double hDPI);

            /**
              Sets the vertical DPI. Defaults to 72.0
            */
            void setVDPI(double vDPI);

            /**
              Sets the rotate. Defaults to not rotated
            */
            void setRotate(int rotate);

            /**
              Sets the output paper width. Has to be set.
            */
            void setPaperWidth(int paperWidth);

            /**
              Sets the output paper height. Has to be set.
            */
            void setPaperHeight(int paperHeight);

            /**
              Sets the output right margin. Defaults to 0
            */
            void setRightMargin(int marginRight);

            /**
              Sets the output bottom margin. Defaults to 0
            */
            void setBottomMargin(int marginBottom);

            /**
              Sets the output left margin. Defaults to 0
            */
            void setLeftMargin(int marginLeft);

            /**
              Sets the output top margin. Defaults to 0
            */
            void setTopMargin(int marginTop);

            /**
              Defines if margins have to be strictly followed (even if that
              means changing aspect ratio), or if the margins can be adapted
              to keep aspect ratio.

              Defaults to false.
            */
            void setStrictMargins(bool strictMargins);

            /** Defines if the page will be rasterized to an image before printing. Defaults to false */
            void setForceRasterize(bool forceRasterize);

            /**
              Sets the options for the PS export.

              \since 0.10
             */
            void setPSOptions(PSOptions options);
            /**
              The currently set options for the PS export.

              The default flags are: Printing.

              \since 0.10
             */
            PSOptions psOptions() const;

            bool convert();

        private:
            Q_DECLARE_PRIVATE(PSConverter)
            Q_DISABLE_COPY(PSConverter)

            PSConverter(DocumentData *document);
    };

    /**
       Converts a PDF to PDF (thus saves a copy of the document).

       \since 0.8
    */
    class POPPLER_QT4_EXPORT PDFConverter : public BaseConverter
    {
        friend class Document;
        public:
            /**
              Options for the PDF export.
             */
            enum PDFOption {
                WithChanges = 0x00000001        ///< The changes done to the document are saved as well
            };
            Q_DECLARE_FLAGS( PDFOptions, PDFOption )

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

            /**
              Sets the options for the PDF export.
             */
            void setPDFOptions(PDFOptions options);
            /**
              The currently set options for the PDF export.
             */
            PDFOptions pdfOptions() const;

            bool convert();

        private:
            Q_DECLARE_PRIVATE(PDFConverter)
            Q_DISABLE_COPY(PDFConverter)

            PDFConverter(DocumentData *document);
    };

    /**
       Conversion from PDF date string format to QDateTime
    */
    POPPLER_QT4_EXPORT QDateTime convertDate( char *dateString );

    class SoundData;
    /**
       Container class for a sound file in a PDF document.

	A sound can be either External (in that case should be loaded the file
       whose url is represented by url() ), or Embedded, and the player has to
       play the data contained in data().

       \since 0.6
    */
    class POPPLER_QT4_EXPORT SoundObject {
    public:
	/**
	   The type of sound
	*/
	enum SoundType {
	    External,     ///< The real sound file is external
	    Embedded      ///< The sound is contained in the data
	};

	/**
	   The encoding format used for the sound
	*/
	enum SoundEncoding {
	    Raw,          ///< Raw encoding, with unspecified or unsigned values in the range [ 0, 2^B - 1 ]
	    Signed,       ///< Twos-complement values
	    muLaw,        ///< mu-law-encoded samples
	    ALaw          ///< A-law-encoded samples
	};

	/// \cond PRIVATE
	SoundObject(Sound *popplersound);
	/// \endcond
	
	~SoundObject();

	/**
	   Is the sound embedded (SoundObject::Embedded) or external (SoundObject::External)?
	*/
	SoundType soundType() const;

	/**
	   The URL of the sound file to be played, in case of SoundObject::External
	*/
	QString url() const;

	/**
	   The data of the sound, in case of SoundObject::Embedded
	*/
	QByteArray data() const;

	/**
	   The sampling rate of the sound
	*/
	double samplingRate() const;

	/**
	   The number of sound channels to use to play the sound
	*/
	int channels() const;

	/**
	   The number of bits per sample value per channel
	*/
	int bitsPerSample() const;

	/**
	   The encoding used for the sound
	*/
	SoundEncoding soundEncoding() const;

    private:
	Q_DISABLE_COPY(SoundObject)

	SoundData *m_soundData;
    };

    class MovieData;
    /**
       Container class for a movie object in a PDF document.

       \since 0.10
    */
    class POPPLER_QT4_EXPORT MovieObject {
    friend class Page;
    public:
	/**
	   The play mode for playing the movie
	*/
	enum PlayMode {
	    PlayOnce,         ///< Play the movie once, closing the movie controls at the end
	    PlayOpen,         ///< Like PlayOnce, but leaving the controls open
	    PlayRepeat,       ///< Play continuously until stopped
	    PlayPalindrome    ///< Play forward, then backward, then again foward and so on until stopped
	};

	~MovieObject();

	/**
	   The URL of the movie to be played
	*/
	QString url() const;

	/**
	   The size of the movie
	*/
	QSize size() const;

	/**
	   The rotation (either 0, 90, 180, or 270 degrees clockwise) for the movie,
	*/
	int rotation() const;

	/**
	   Whether show a bar with movie controls
	*/
	bool showControls() const;

	/**
	   How to play the movie
	*/
	PlayMode playMode() const;

    private:
	/// \cond PRIVATE
	MovieObject( AnnotMovie *ann );
	/// \endcond
	
	Q_DISABLE_COPY(MovieObject)

	MovieData *m_movieData;
    };

}

Q_DECLARE_OPERATORS_FOR_FLAGS(Poppler::Document::RenderHints)
Q_DECLARE_OPERATORS_FOR_FLAGS(Poppler::PDFConverter::PDFOptions)
Q_DECLARE_OPERATORS_FOR_FLAGS(Poppler::PSConverter::PSOptions)

#endif
