/* poppler-annot.cc: glib interface to poppler
 *
 * Copyright (C) 2007 Inigo Martinez <inigomartinez@gmail.com>
 * Copyright (C) 2009 Carlos Garcia Campos <carlosgc@gnome.org>
 * Copyright (C) 2013 German Poo-Caamano <gpoo@gnome.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.
 */

#include "config.h"
#include "poppler.h"
#include "poppler-private.h"

/**
 * SECTION:poppler-annot
 * @short_description: Annotations
 * @title: PopplerAnnot
 */

typedef struct _PopplerAnnotClass               PopplerAnnotClass;
typedef struct _PopplerAnnotMarkupClass         PopplerAnnotMarkupClass;
typedef struct _PopplerAnnotFreeTextClass       PopplerAnnotFreeTextClass;
typedef struct _PopplerAnnotTextClass           PopplerAnnotTextClass;
typedef struct _PopplerAnnotTextMarkupClass     PopplerAnnotTextMarkupClass;
typedef struct _PopplerAnnotFileAttachmentClass PopplerAnnotFileAttachmentClass;
typedef struct _PopplerAnnotMovieClass          PopplerAnnotMovieClass;
typedef struct _PopplerAnnotScreenClass         PopplerAnnotScreenClass;
typedef struct _PopplerAnnotLineClass           PopplerAnnotLineClass;
typedef struct _PopplerAnnotCircleClass         PopplerAnnotCircleClass;
typedef struct _PopplerAnnotSquareClass         PopplerAnnotSquareClass;

struct _PopplerAnnotClass
{
  GObjectClass parent_class;
};

struct _PopplerAnnotMarkup
{
  PopplerAnnot parent_instance;
};

struct _PopplerAnnotMarkupClass
{
  PopplerAnnotClass parent_class;
};

struct _PopplerAnnotText
{
  PopplerAnnotMarkup parent_instance;
};

struct _PopplerAnnotTextClass
{
  PopplerAnnotMarkupClass parent_class;
};

struct _PopplerAnnotTextMarkup
{
  PopplerAnnotMarkup parent_instance;
};

struct _PopplerAnnotTextMarkupClass
{
  PopplerAnnotMarkupClass parent_class;
};

struct _PopplerAnnotFreeText
{
  PopplerAnnotMarkup parent_instance;
};

struct _PopplerAnnotFreeTextClass
{
  PopplerAnnotMarkupClass parent_class;
};

struct _PopplerAnnotFileAttachment
{
  PopplerAnnotMarkup parent_instance;
};

struct _PopplerAnnotFileAttachmentClass
{
  PopplerAnnotMarkupClass parent_class;
};

struct _PopplerAnnotMovie
{
  PopplerAnnot  parent_instance;

  PopplerMovie *movie;
};

struct _PopplerAnnotMovieClass
{
  PopplerAnnotClass parent_class;
};

struct _PopplerAnnotScreen
{
  PopplerAnnot  parent_instance;

  PopplerAction *action;
};

struct _PopplerAnnotScreenClass
{
  PopplerAnnotClass parent_class;
};

struct _PopplerAnnotLine
{
  PopplerAnnotMarkup parent_instance;
};

struct _PopplerAnnotLineClass
{
  PopplerAnnotMarkupClass parent_class;
};

struct _PopplerAnnotCircle
{
  PopplerAnnotMarkup parent_instance;
};

struct _PopplerAnnotCircleClass
{
  PopplerAnnotMarkupClass parent_class;
};

struct _PopplerAnnotSquare
{
  PopplerAnnotMarkup parent_instance;
};

struct _PopplerAnnotSquareClass
{
  PopplerAnnotMarkupClass parent_class;
};

G_DEFINE_TYPE (PopplerAnnot, poppler_annot, G_TYPE_OBJECT)
G_DEFINE_TYPE (PopplerAnnotMarkup, poppler_annot_markup, POPPLER_TYPE_ANNOT)
G_DEFINE_TYPE (PopplerAnnotTextMarkup, poppler_annot_text_markup, POPPLER_TYPE_ANNOT_MARKUP)
G_DEFINE_TYPE (PopplerAnnotText, poppler_annot_text, POPPLER_TYPE_ANNOT_MARKUP)
G_DEFINE_TYPE (PopplerAnnotFreeText, poppler_annot_free_text, POPPLER_TYPE_ANNOT_MARKUP)
G_DEFINE_TYPE (PopplerAnnotFileAttachment, poppler_annot_file_attachment, POPPLER_TYPE_ANNOT_MARKUP)
G_DEFINE_TYPE (PopplerAnnotMovie, poppler_annot_movie, POPPLER_TYPE_ANNOT)
G_DEFINE_TYPE (PopplerAnnotScreen, poppler_annot_screen, POPPLER_TYPE_ANNOT)
G_DEFINE_TYPE (PopplerAnnotLine, poppler_annot_line, POPPLER_TYPE_ANNOT_MARKUP)
G_DEFINE_TYPE (PopplerAnnotCircle, poppler_annot_circle, POPPLER_TYPE_ANNOT_MARKUP)
G_DEFINE_TYPE (PopplerAnnotSquare, poppler_annot_square, POPPLER_TYPE_ANNOT_MARKUP)

static PopplerAnnot *
_poppler_create_annot (GType annot_type, Annot *annot)
{
  PopplerAnnot *poppler_annot;

  poppler_annot = POPPLER_ANNOT (g_object_new (annot_type, NULL));
  poppler_annot->annot = annot;
  annot->incRefCnt();

  return poppler_annot;
}

static void
poppler_annot_finalize (GObject *object)
{
  PopplerAnnot *poppler_annot = POPPLER_ANNOT (object);

  if (poppler_annot->annot) {
    poppler_annot->annot->decRefCnt();
    poppler_annot->annot = NULL;
  }

  G_OBJECT_CLASS (poppler_annot_parent_class)->finalize (object);
}

static void
poppler_annot_init (PopplerAnnot *poppler_annot)
{
}

static void
poppler_annot_class_init (PopplerAnnotClass *klass)
{
  GObjectClass *gobject_class = G_OBJECT_CLASS (klass);

  gobject_class->finalize = poppler_annot_finalize;
}

PopplerAnnot *
_poppler_annot_new (Annot *annot)
{
  return _poppler_create_annot (POPPLER_TYPE_ANNOT, annot);
}

static void
poppler_annot_markup_init (PopplerAnnotMarkup *poppler_annot)
{
}

static void
poppler_annot_markup_class_init (PopplerAnnotMarkupClass *klass)
{
}

static void
poppler_annot_text_init (PopplerAnnotText *poppler_annot)
{
}

static void
poppler_annot_text_class_init (PopplerAnnotTextClass *klass)
{
}

PopplerAnnot *
_poppler_annot_text_new (Annot *annot)
{
  return _poppler_create_annot (POPPLER_TYPE_ANNOT_TEXT, annot);
}

/**
 * poppler_annot_text_new:
 * @doc: a #PopplerDocument
 * @rect: a #PopplerRectangle
 *
 * Creates a new Text annotation that will be
 * located on @rect when added to a page. See
 * poppler_page_add_annot()
 *
 * Return value: A newly created #PopplerAnnotText annotation
 *
 * Since: 0.16
 */
PopplerAnnot *
poppler_annot_text_new (PopplerDocument  *doc,
			PopplerRectangle *rect)
{
  Annot *annot;
  PDFRectangle pdf_rect(rect->x1, rect->y1,
			rect->x2, rect->y2);

  annot = new AnnotText (doc->doc, &pdf_rect);

  return _poppler_annot_text_new (annot);
}

PopplerAnnot *
_poppler_annot_text_markup_new (Annot *annot)
{
  return _poppler_create_annot (POPPLER_TYPE_ANNOT_TEXT_MARKUP, annot);
}

static AnnotQuadrilaterals *
create_annot_quads_from_poppler_quads (GArray *quads)
{
  AnnotQuadrilaterals::AnnotQuadrilateral **quads_array;

  g_assert (quads->len > 0);

  quads_array = (AnnotQuadrilaterals::AnnotQuadrilateral **) g_malloc0_n (
    sizeof (AnnotQuadrilaterals::AnnotQuadrilateral *),
    quads->len);

  for (guint i = 0; i < quads->len; i++) {
    PopplerQuadrilateral *quadrilateral = &g_array_index (quads, PopplerQuadrilateral, i);

    quads_array[i] = new AnnotQuadrilaterals::AnnotQuadrilateral (
      quadrilateral->p1.x, quadrilateral->p1.y,
      quadrilateral->p2.x, quadrilateral->p2.y,
      quadrilateral->p3.x, quadrilateral->p3.y,
      quadrilateral->p4.x, quadrilateral->p4.y);
  }

  return new AnnotQuadrilaterals (quads_array, quads->len);
}

static GArray *
create_poppler_quads_from_annot_quads (AnnotQuadrilaterals *quads_array)
{
  GArray *quads;
  guint   quads_len;

  quads_len = quads_array->getQuadrilateralsLength();
  quads = g_array_sized_new (FALSE, FALSE,
                             sizeof (PopplerQuadrilateral),
                             quads_len);
  g_array_set_size (quads, quads_len);

  for (guint i = 0; i < quads_len; ++i) {
    PopplerQuadrilateral *quadrilateral = &g_array_index (quads, PopplerQuadrilateral, i);

    quadrilateral->p1.x = quads_array->getX1(i);
    quadrilateral->p1.y = quads_array->getY1(i);
    quadrilateral->p2.x = quads_array->getX2(i);
    quadrilateral->p2.y = quads_array->getY2(i);
    quadrilateral->p3.x = quads_array->getX3(i);
    quadrilateral->p3.y = quads_array->getY3(i);
    quadrilateral->p4.x = quads_array->getX4(i);
    quadrilateral->p4.y = quads_array->getY4(i);
  }

  return quads;
}

static void
poppler_annot_text_markup_init (PopplerAnnotTextMarkup *poppler_annot)
{
}

static void
poppler_annot_text_markup_class_init (PopplerAnnotTextMarkupClass *klass)
{
}

/**
 * poppler_annot_text_markup_new_highlight:
 * @doc: a #PopplerDocument
 * @rect: a #PopplerRectangle
 * @quadrilaterals: (element-type PopplerQuadrilateral): A #GArray of
 *   #PopplerQuadrilateral<!-- -->s
 *
 * Creates a new Highlight Text annotation that will be
 * located on @rect when added to a page. See poppler_page_add_annot()
 *
 * Return value: (transfer full): A newly created #PopplerAnnotTextMarkup annotation
 *
 * Since: 0.26
 */
PopplerAnnot *
poppler_annot_text_markup_new_highlight (PopplerDocument  *doc,
                                         PopplerRectangle *rect,
                                         GArray           *quadrilaterals)
{
  PopplerAnnot *poppler_annot;
  AnnotTextMarkup *annot;
  PDFRectangle pdf_rect(rect->x1, rect->y1,
			rect->x2, rect->y2);

  annot = new AnnotTextMarkup (doc->doc, &pdf_rect, Annot::typeHighlight);

  poppler_annot = _poppler_annot_text_markup_new (annot);
  poppler_annot_text_markup_set_quadrilaterals (POPPLER_ANNOT_TEXT_MARKUP (poppler_annot),
                                                quadrilaterals);
  return poppler_annot;
}

/**
 * poppler_annot_text_markup_new_squiggly:
 * @doc: a #PopplerDocument
 * @rect: a #PopplerRectangle
 * @quadrilaterals: (element-type PopplerQuadrilateral): A #GArray of
 *   #PopplerQuadrilateral<!-- -->s
 *
 * Creates a new Squiggly Text annotation that will be
 * located on @rect when added to a page. See poppler_page_add_annot()
 *
 * Return value: (transfer full): A newly created #PopplerAnnotTextMarkup annotation
 *
 * Since: 0.26
 */
PopplerAnnot *
poppler_annot_text_markup_new_squiggly (PopplerDocument  *doc,
                                        PopplerRectangle *rect,
                                        GArray           *quadrilaterals)
{
  PopplerAnnot *poppler_annot;
  AnnotTextMarkup *annot;
  PDFRectangle pdf_rect(rect->x1, rect->y1,
			rect->x2, rect->y2);

  g_return_val_if_fail (quadrilaterals != NULL && quadrilaterals->len > 0, NULL);

  annot = new AnnotTextMarkup (doc->doc, &pdf_rect, Annot::typeSquiggly);

  poppler_annot = _poppler_annot_text_markup_new (annot);
  poppler_annot_text_markup_set_quadrilaterals (POPPLER_ANNOT_TEXT_MARKUP (poppler_annot),
                                                quadrilaterals);
  return poppler_annot;
}

/**
 * poppler_annot_text_markup_new_strikeout:
 * @doc: a #PopplerDocument
 * @rect: a #PopplerRectangle
 * @quadrilaterals: (element-type PopplerQuadrilateral): A #GArray of
 *   #PopplerQuadrilateral<!-- -->s
 *
 * Creates a new Strike Out Text annotation that will be
 * located on @rect when added to a page. See poppler_page_add_annot()
 *
 * Return value: (transfer full): A newly created #PopplerAnnotTextMarkup annotation
 *
 * Since: 0.26
 */
PopplerAnnot *
poppler_annot_text_markup_new_strikeout (PopplerDocument  *doc,
                                         PopplerRectangle *rect,
                                         GArray           *quadrilaterals)
{
  PopplerAnnot *poppler_annot;
  AnnotTextMarkup *annot;
  PDFRectangle pdf_rect(rect->x1, rect->y1,
			rect->x2, rect->y2);

  g_return_val_if_fail (quadrilaterals != NULL && quadrilaterals->len > 0, NULL);

  annot = new AnnotTextMarkup (doc->doc, &pdf_rect, Annot::typeStrikeOut);

  poppler_annot = _poppler_annot_text_markup_new (annot);
  poppler_annot_text_markup_set_quadrilaterals (POPPLER_ANNOT_TEXT_MARKUP (poppler_annot),
                                                quadrilaterals);
  return poppler_annot;
}

/**
 * poppler_annot_text_markup_new_underline:
 * @doc: a #PopplerDocument
 * @rect: a #PopplerRectangle
 * @quadrilaterals: (element-type PopplerQuadrilateral): A #GArray of
 *   #PopplerQuadrilateral<!-- -->s
 *
 * Creates a new Underline Text annotation that will be
 * located on @rect when added to a page. See poppler_page_add_annot()
 *
 * Return value: (transfer full): A newly created #PopplerAnnotTextMarkup annotation
 *
 * Since: 0.26
 */
PopplerAnnot *
poppler_annot_text_markup_new_underline (PopplerDocument  *doc,
                                         PopplerRectangle *rect,
                                         GArray           *quadrilaterals)
{
  PopplerAnnot *poppler_annot;
  AnnotTextMarkup *annot;
  PDFRectangle pdf_rect(rect->x1, rect->y1,
			rect->x2, rect->y2);

  g_return_val_if_fail (quadrilaterals != NULL && quadrilaterals->len > 0, NULL);

  annot = new AnnotTextMarkup (doc->doc, &pdf_rect, Annot::typeUnderline);

  poppler_annot = _poppler_annot_text_markup_new (annot);
  poppler_annot_text_markup_set_quadrilaterals (POPPLER_ANNOT_TEXT_MARKUP (poppler_annot),
                                                quadrilaterals);
  return poppler_annot;
}

static void
poppler_annot_free_text_init (PopplerAnnotFreeText *poppler_annot)
{
}

static void
poppler_annot_free_text_class_init (PopplerAnnotFreeTextClass *klass)
{
}

PopplerAnnot *
_poppler_annot_free_text_new (Annot *annot)
{
  return _poppler_create_annot (POPPLER_TYPE_ANNOT_FREE_TEXT, annot);
}

static void
poppler_annot_file_attachment_init (PopplerAnnotFileAttachment *poppler_annot)
{
}

static void
poppler_annot_file_attachment_class_init (PopplerAnnotFileAttachmentClass *klass)
{
}

PopplerAnnot *
_poppler_annot_file_attachment_new (Annot *annot)
{
  return _poppler_create_annot (POPPLER_TYPE_ANNOT_FILE_ATTACHMENT, annot);
}


static void
poppler_annot_movie_finalize (GObject *object)
{
  PopplerAnnotMovie *annot_movie = POPPLER_ANNOT_MOVIE (object);

  if (annot_movie->movie) {
    g_object_unref (annot_movie->movie);
    annot_movie->movie = NULL;
  }

  G_OBJECT_CLASS (poppler_annot_movie_parent_class)->finalize (object);
}

static void
poppler_annot_movie_init (PopplerAnnotMovie *poppler_annot)
{
}

static void
poppler_annot_movie_class_init (PopplerAnnotMovieClass *klass)
{
  GObjectClass *gobject_class = G_OBJECT_CLASS (klass);

  gobject_class->finalize = poppler_annot_movie_finalize;
}

PopplerAnnot *
_poppler_annot_movie_new (Annot *annot)
{
  PopplerAnnot *poppler_annot;
  AnnotMovie   *annot_movie;

  poppler_annot = _poppler_create_annot (POPPLER_TYPE_ANNOT_MOVIE, annot);
  annot_movie = static_cast<AnnotMovie *>(poppler_annot->annot);
  POPPLER_ANNOT_MOVIE (poppler_annot)->movie = _poppler_movie_new (annot_movie->getMovie());

  return poppler_annot;
}

static void
poppler_annot_screen_finalize (GObject *object)
{
  PopplerAnnotScreen *annot_screen = POPPLER_ANNOT_SCREEN (object);

  if (annot_screen->action) {
    poppler_action_free (annot_screen->action);
    annot_screen->action = NULL;
  }

  G_OBJECT_CLASS (poppler_annot_screen_parent_class)->finalize (object);
}

static void
poppler_annot_screen_init (PopplerAnnotScreen *poppler_annot)
{
}

static void
poppler_annot_screen_class_init (PopplerAnnotScreenClass *klass)
{
  GObjectClass *gobject_class = G_OBJECT_CLASS (klass);

  gobject_class->finalize = poppler_annot_screen_finalize;
}

PopplerAnnot *
_poppler_annot_screen_new (Annot *annot)
{
  PopplerAnnot *poppler_annot;
  AnnotScreen  *annot_screen;
  LinkAction   *action;

  poppler_annot = _poppler_create_annot (POPPLER_TYPE_ANNOT_SCREEN, annot);
  annot_screen = static_cast<AnnotScreen *>(poppler_annot->annot);
  action = annot_screen->getAction();
  if (action)
    POPPLER_ANNOT_SCREEN (poppler_annot)->action = _poppler_action_new (NULL, action, NULL);

  return poppler_annot;
}

PopplerAnnot *
_poppler_annot_line_new (Annot *annot)
{
  return _poppler_create_annot (POPPLER_TYPE_ANNOT_LINE, annot);
}

static void
poppler_annot_line_init (PopplerAnnotLine *poppler_annot)
{
}

static void
poppler_annot_line_class_init (PopplerAnnotLineClass *klass)
{
}

/**
 * poppler_annot_line_new:
 * @doc: a #PopplerDocument
 * @rect: a #PopplerRectangle
 * @start: a #PopplerPoint of the starting vertice
 * @end: a #PopplerPoint of the ending vertice
 *
 * Creates a new Line annotation that will be
 * located on @rect when added to a page. See
 * poppler_page_add_annot()
 *
 * Return value: A newly created #PopplerAnnotLine annotation
 *
 * Since: 0.26
 */
PopplerAnnot *
poppler_annot_line_new (PopplerDocument  *doc,
			PopplerRectangle *rect,
                        PopplerPoint     *start,
                        PopplerPoint     *end)
{
  PopplerAnnot *poppler_annot;
  Annot *annot;
  PDFRectangle pdf_rect(rect->x1, rect->y1,
			rect->x2, rect->y2);

  annot = new AnnotLine (doc->doc, &pdf_rect);

  poppler_annot = _poppler_annot_line_new (annot);
  poppler_annot_line_set_vertices (POPPLER_ANNOT_LINE (poppler_annot),
                                   start, end);
  return poppler_annot;
}

PopplerAnnot *
_poppler_annot_circle_new (Annot *annot)
{
  return _poppler_create_annot (POPPLER_TYPE_ANNOT_CIRCLE, annot);
}

static void
poppler_annot_circle_init (PopplerAnnotCircle *poppler_annot)
{
}

static void
poppler_annot_circle_class_init (PopplerAnnotCircleClass *klass)
{
}

/**
 * poppler_annot_circle_new:
 * @doc: a #PopplerDocument
 * @rect: a #PopplerRectangle
 *
 * Creates a new Circle annotation that will be
 * located on @rect when added to a page. See
 * poppler_page_add_annot()
 *
 * Return value: a newly created #PopplerAnnotCircle annotation
 *
 * Since: 0.26
 **/
PopplerAnnot *
poppler_annot_circle_new (PopplerDocument  *doc,
			  PopplerRectangle *rect)
{
  Annot *annot;
  PDFRectangle pdf_rect(rect->x1, rect->y1,
			rect->x2, rect->y2);

  annot = new AnnotGeometry (doc->doc, &pdf_rect, Annot::typeCircle);

  return _poppler_annot_circle_new (annot);
}

PopplerAnnot *
_poppler_annot_square_new (Annot *annot)
{
  return _poppler_create_annot (POPPLER_TYPE_ANNOT_SQUARE, annot);
}

static void
poppler_annot_square_init (PopplerAnnotSquare *poppler_annot)
{
}

static void
poppler_annot_square_class_init (PopplerAnnotSquareClass *klass)
{
}

/**
 * poppler_annot_square_new:
 * @doc: a #PopplerDocument
 * @rect: a #PopplerRectangle
 *
 * Creates a new Square annotation that will be
 * located on @rect when added to a page. See
 * poppler_page_add_annot()
 *
 * Return value: a newly created #PopplerAnnotSquare annotation
 *
 * Since: 0.26
**/
PopplerAnnot *
poppler_annot_square_new (PopplerDocument  *doc,
			  PopplerRectangle *rect)
{
  Annot *annot;
  PDFRectangle pdf_rect(rect->x1, rect->y1,
			rect->x2, rect->y2);

  annot = new AnnotGeometry (doc->doc, &pdf_rect, Annot::typeSquare);

  return _poppler_annot_square_new (annot);
}

/* Public methods */
/**
 * poppler_annot_get_annot_type:
 * @poppler_annot: a #PopplerAnnot
 *
 * Gets the type of @poppler_annot
 *
 * Return value: #PopplerAnnotType of @poppler_annot.
 **/ 
PopplerAnnotType
poppler_annot_get_annot_type (PopplerAnnot *poppler_annot)
{
  g_return_val_if_fail (POPPLER_IS_ANNOT (poppler_annot), POPPLER_ANNOT_UNKNOWN);

  switch (poppler_annot->annot->getType ())
    {
    case Annot::typeText:
      return POPPLER_ANNOT_TEXT;
    case Annot::typeLink:
      return POPPLER_ANNOT_LINK;
    case Annot::typeFreeText:
      return POPPLER_ANNOT_FREE_TEXT;
    case Annot::typeLine:
      return POPPLER_ANNOT_LINE;
    case Annot::typeSquare:
      return POPPLER_ANNOT_SQUARE;
    case Annot::typeCircle:
      return POPPLER_ANNOT_CIRCLE;
    case Annot::typePolygon:
      return POPPLER_ANNOT_POLYGON;
    case Annot::typePolyLine:
      return POPPLER_ANNOT_POLY_LINE;
    case Annot::typeHighlight:
      return POPPLER_ANNOT_HIGHLIGHT;
    case Annot::typeUnderline:
      return POPPLER_ANNOT_UNDERLINE;
    case Annot::typeSquiggly:
      return POPPLER_ANNOT_SQUIGGLY;
    case Annot::typeStrikeOut:
      return POPPLER_ANNOT_STRIKE_OUT;
    case Annot::typeStamp:
      return POPPLER_ANNOT_STAMP;
    case Annot::typeCaret:
      return POPPLER_ANNOT_CARET;
    case Annot::typeInk:
      return POPPLER_ANNOT_INK;
    case Annot::typePopup:
      return POPPLER_ANNOT_POPUP;
    case Annot::typeFileAttachment:
      return POPPLER_ANNOT_FILE_ATTACHMENT;
    case Annot::typeSound:
      return POPPLER_ANNOT_SOUND;
    case Annot::typeMovie:
      return POPPLER_ANNOT_MOVIE;
    case Annot::typeWidget:
      return POPPLER_ANNOT_WIDGET;
    case Annot::typeScreen:
      return POPPLER_ANNOT_SCREEN;
    case Annot::typePrinterMark:
      return POPPLER_ANNOT_PRINTER_MARK;
    case Annot::typeTrapNet:
      return POPPLER_ANNOT_TRAP_NET;
    case Annot::typeWatermark:
      return POPPLER_ANNOT_WATERMARK;
    case Annot::type3D:
      return POPPLER_ANNOT_3D;
    default:
      g_warning ("Unsupported Annot Type");
    }

  return POPPLER_ANNOT_UNKNOWN;
}

/**
 * poppler_annot_get_contents:
 * @poppler_annot: a #PopplerAnnot
 *
 * Retrieves the contents of @poppler_annot.
 *
 * Return value: a new allocated string with the contents of @poppler_annot. It
 *               must be freed with g_free() when done.
 **/
gchar *
poppler_annot_get_contents (PopplerAnnot *poppler_annot)
{
  GooString *contents;

  g_return_val_if_fail (POPPLER_IS_ANNOT (poppler_annot), NULL);

  contents = poppler_annot->annot->getContents ();

  return contents && contents->getLength() > 0 ? _poppler_goo_string_to_utf8 (contents) : NULL;
}

/**
 * poppler_annot_set_contents:
 * @poppler_annot: a #PopplerAnnot
 * @contents: a text string containing the new contents
 *
 * Sets the contents of @poppler_annot to the given value,
 * replacing the current contents.
 *
 * Since: 0.12
 **/
void
poppler_annot_set_contents (PopplerAnnot *poppler_annot,
			    const gchar  *contents)
{
  GooString *goo_tmp;
  gchar *tmp;
  gsize length = 0;
  
  g_return_if_fail (POPPLER_IS_ANNOT (poppler_annot));

  tmp = contents ? g_convert (contents, -1, "UTF-16BE", "UTF-8", NULL, &length, NULL) : NULL;
  goo_tmp = new GooString (tmp, length);
  g_free (tmp);
  poppler_annot->annot->setContents (goo_tmp);
  delete (goo_tmp);
}

/**
 * poppler_annot_get_name:
 * @poppler_annot: a #PopplerAnnot
 *
 * Retrieves the name of @poppler_annot.
 *
 * Return value: a new allocated string with the name of @poppler_annot. It must
 *               be freed with g_free() when done.
 **/
gchar *
poppler_annot_get_name (PopplerAnnot *poppler_annot)
{
  GooString *name;

  g_return_val_if_fail (POPPLER_IS_ANNOT (poppler_annot), NULL);

  name = poppler_annot->annot->getName ();

  return name ? _poppler_goo_string_to_utf8 (name) : NULL;
}

/**
 * poppler_annot_get_modified:
 * @poppler_annot: a #PopplerAnnot
 *
 * Retrieves the last modification data of @poppler_annot. The returned
 * string will be either a PDF format date or a text string.
 * See also #poppler_date_parse()
 *
 * Return value: a new allocated string with the last modification data of
 *               @poppler_annot. It must be freed with g_free() when done.
 **/
gchar *
poppler_annot_get_modified (PopplerAnnot *poppler_annot)
{
  GooString *text;

  g_return_val_if_fail (POPPLER_IS_ANNOT (poppler_annot), NULL);

  text = poppler_annot->annot->getModified ();

  return text ? _poppler_goo_string_to_utf8 (text) : NULL;
}

/**
 * poppler_annot_get_flags:
 * @poppler_annot: a #PopplerAnnot
 *
 * Retrieves the flag field specifying various characteristics of the
 * @poppler_annot.
 *
 * Return value: the flag field of @poppler_annot.
 **/
PopplerAnnotFlag
poppler_annot_get_flags (PopplerAnnot *poppler_annot)
{
  g_return_val_if_fail (POPPLER_IS_ANNOT (poppler_annot), (PopplerAnnotFlag) 0);

  return (PopplerAnnotFlag) poppler_annot->annot->getFlags ();
}

/**
 * poppler_annot_set_flags:
 * @poppler_annot: a #PopplerAnnot
 * @flags: a #PopplerAnnotFlag
 *
 * Sets the flag field specifying various characteristics of the
 * @poppler_annot.
 *
 * Since: 0.22
 **/
void
poppler_annot_set_flags (PopplerAnnot *poppler_annot, PopplerAnnotFlag flags)
{
  g_return_if_fail (POPPLER_IS_ANNOT (poppler_annot));

  if (poppler_annot_get_flags (poppler_annot) == flags)
    return;

  poppler_annot->annot->setFlags ((guint) flags);
}

static PopplerColor *
create_poppler_color_from_annot_color (AnnotColor *color)
{
  PopplerColor *poppler_color = NULL;

  if (color) {
    const double *values = color->getValues ();

    switch (color->getSpace ())
      {
      case AnnotColor::colorGray:
        poppler_color = g_new (PopplerColor, 1);
	
        poppler_color->red = (guint16) (values[0] * 65535);
        poppler_color->green = poppler_color->red;
        poppler_color->blue = poppler_color->red;

	break;
      case AnnotColor::colorRGB:
        poppler_color = g_new (PopplerColor, 1);
	
        poppler_color->red = (guint16) (values[0] * 65535);
        poppler_color->green = (guint16) (values[1] * 65535);
        poppler_color->blue = (guint16) (values[2] * 65535);

	break;
      case AnnotColor::colorCMYK:
        g_warning ("Unsupported Annot Color: colorCMYK");
      case AnnotColor::colorTransparent:
        break;
      }
  }

  return poppler_color;
}

static AnnotColor *
create_annot_color_from_poppler_color (PopplerColor *poppler_color)
{
  if (!poppler_color)
    return NULL;

  return new AnnotColor ((double)poppler_color->red / 65535,
                         (double)poppler_color->green / 65535,
                         (double)poppler_color->blue / 65535);
}

/**
 * poppler_annot_get_color:
 * @poppler_annot: a #PopplerAnnot
 *
 * Retrieves the color of @poppler_annot.
 *
 * Return value: a new allocated #PopplerColor with the color values of
 *               @poppler_annot, or %NULL. It must be freed with g_free() when done.
 **/
PopplerColor *
poppler_annot_get_color (PopplerAnnot *poppler_annot)
{
  g_return_val_if_fail (POPPLER_IS_ANNOT (poppler_annot), NULL);

  return create_poppler_color_from_annot_color (poppler_annot->annot->getColor ());
}

/**
 * poppler_annot_set_color:
 * @poppler_annot: a #PopplerAnnot
 * @poppler_color: (allow-none): a #PopplerColor, or %NULL
 *
 * Sets the color of @poppler_annot.
 *
 * Since: 0.16
 */
void
poppler_annot_set_color (PopplerAnnot *poppler_annot,
			 PopplerColor *poppler_color)
{
  /* Annot takes ownership of the color */
  poppler_annot->annot->setColor (create_annot_color_from_poppler_color (poppler_color));
}

/**
 * poppler_annot_get_page_index:
 * @poppler_annot: a #PopplerAnnot
 *
 * Returns the page index to which @poppler_annot is associated, or -1 if unknown
 *
 * Return value: page index or -1
 *
 * Since: 0.14
 **/
gint
poppler_annot_get_page_index (PopplerAnnot *poppler_annot)
{
  gint page_num;

  g_return_val_if_fail (POPPLER_IS_ANNOT (poppler_annot), -1);

  page_num = poppler_annot->annot->getPageNum();
  return page_num <= 0 ? -1 : page_num - 1;
}

/**
 * poppler_annot_get_rectangle:
 * @poppler_annot: a #PopplerAnnot
 * @poppler_rect: (out): a #PopplerRectangle to store the annotation's coordinates
 *
 * Retrieves the rectangle representing the page coordinates where the
 * annotation @poppler_annot is placed.
 *
 * Since: 0.26
 */
void
poppler_annot_get_rectangle (PopplerAnnot     *poppler_annot,
                             PopplerRectangle *poppler_rect)
{
  PDFRectangle *annot_rect;

  g_return_if_fail (POPPLER_IS_ANNOT (poppler_annot));
  g_return_if_fail (poppler_rect != NULL);

  annot_rect = poppler_annot->annot->getRect ();
  poppler_rect->x1 = annot_rect->x1;
  poppler_rect->x2 = annot_rect->x2;
  poppler_rect->y1 = annot_rect->y1;
  poppler_rect->y2 = annot_rect->y2;
}

/**
 * poppler_annot_set_rectangle:
 * @poppler_annot: a #PopplerAnnot
 * @poppler_rect: a #PopplerRectangle with the new annotation's coordinates
 *
 * Move the annotation to the rectangle representing the page coordinates
 * where the annotation @poppler_annot should be placed.
 *
 * Since: 0.26
 */
void
poppler_annot_set_rectangle (PopplerAnnot     *poppler_annot,
                             PopplerRectangle *poppler_rect)
{
  g_return_if_fail (POPPLER_IS_ANNOT (poppler_annot));
  g_return_if_fail (poppler_rect != NULL);

  poppler_annot->annot->setRect (poppler_rect->x1, poppler_rect->y1,
                                 poppler_rect->x2, poppler_rect->y2);
}

/* PopplerAnnotMarkup */
/**
 * poppler_annot_markup_get_label:
 * @poppler_annot: a #PopplerAnnotMarkup
 *
 * Retrieves the label text of @poppler_annot.
 *
 * Return value: the label text of @poppler_annot.
 */
gchar *
poppler_annot_markup_get_label (PopplerAnnotMarkup *poppler_annot)
{
  AnnotMarkup *annot;
  GooString *text;

  g_return_val_if_fail (POPPLER_IS_ANNOT_MARKUP (poppler_annot), NULL);

  annot = static_cast<AnnotMarkup *>(POPPLER_ANNOT (poppler_annot)->annot);

  text = annot->getLabel ();

  return text ? _poppler_goo_string_to_utf8 (text) : NULL;
}

/**
 * poppler_annot_markup_set_label:
 * @poppler_annot: a #PopplerAnnotMarkup
 * @label: (allow-none): a text string containing the new label, or %NULL
 *
 * Sets the label text of @poppler_annot, replacing the current one
 *
 * Since: 0.16
 */
void
poppler_annot_markup_set_label (PopplerAnnotMarkup *poppler_annot,
				const gchar        *label)
{
  AnnotMarkup *annot;
  GooString *goo_tmp;
  gchar *tmp;
  gsize length = 0;

  g_return_if_fail (POPPLER_IS_ANNOT_MARKUP (poppler_annot));

  annot = static_cast<AnnotMarkup *>(POPPLER_ANNOT (poppler_annot)->annot);

  tmp = label ? g_convert (label, -1, "UTF-16BE", "UTF-8", NULL, &length, NULL) : NULL;
  goo_tmp = new GooString (tmp, length);
  g_free (tmp);
  annot->setLabel (goo_tmp);
  delete goo_tmp;
}

/**
 * poppler_annot_markup_has_popup:
 * @poppler_annot: a #PopplerAnnotMarkup
 *
 * Return %TRUE if the markup annotation has a popup window associated
 *
 * Return value: %TRUE, if @poppler_annot has popup, %FALSE otherwise
 *
 * Since: 0.12
 **/
gboolean
poppler_annot_markup_has_popup (PopplerAnnotMarkup *poppler_annot)
{
  AnnotMarkup *annot;

  g_return_val_if_fail (POPPLER_IS_ANNOT_MARKUP (poppler_annot), FALSE);

  annot = static_cast<AnnotMarkup *>(POPPLER_ANNOT (poppler_annot)->annot);

  return annot->getPopup () != NULL;
}

/**
 * poppler_annot_markup_set_popup:
 * @poppler_annot: a #PopplerAnnotMarkup
 * @popup_rect: a #PopplerRectangle
 *
 * Associates a new popup window for editing contents of @poppler_annot.
 * Popup window shall be displayed by viewers at @popup_rect on the page.
 *
 * Since: 0.16
 */
void
poppler_annot_markup_set_popup (PopplerAnnotMarkup *poppler_annot,
				PopplerRectangle   *popup_rect)
{
  AnnotMarkup *annot;
  AnnotPopup  *popup;
  PDFRectangle pdf_rect(popup_rect->x1, popup_rect->y1,
			popup_rect->x2, popup_rect->y2);

  g_return_if_fail (POPPLER_IS_ANNOT_MARKUP (poppler_annot));

  annot = static_cast<AnnotMarkup *>(POPPLER_ANNOT (poppler_annot)->annot);
  popup = new AnnotPopup (annot->getDoc(), &pdf_rect);
  annot->setPopup (popup);
}

/**
 * poppler_annot_markup_get_popup_is_open:
 * @poppler_annot: a #PopplerAnnotMarkup
 *
 * Retrieves the state of the popup window related to @poppler_annot.
 *
 * Return value: the state of @poppler_annot. %TRUE if it's open, %FALSE in
 *               other case.
 **/
gboolean
poppler_annot_markup_get_popup_is_open (PopplerAnnotMarkup *poppler_annot)
{
  AnnotMarkup *annot;
  AnnotPopup *annot_popup;

  g_return_val_if_fail (POPPLER_IS_ANNOT_MARKUP (poppler_annot), FALSE);

  annot = static_cast<AnnotMarkup *>(POPPLER_ANNOT (poppler_annot)->annot);

  if ((annot_popup = annot->getPopup ()))
    return annot_popup->getOpen ();

  return FALSE;
}

/**
 * poppler_annot_markup_set_popup_is_open:
 * @poppler_annot: a #PopplerAnnotMarkup
 * @is_open: whether popup window should initially be displayed open
 *
 * Sets the state of the popup window related to @poppler_annot.
 *
 * Since: 0.16
 **/
void
poppler_annot_markup_set_popup_is_open (PopplerAnnotMarkup *poppler_annot,
					gboolean            is_open)
{
  AnnotMarkup *annot;
  AnnotPopup *annot_popup;

  g_return_if_fail (POPPLER_IS_ANNOT_MARKUP (poppler_annot));

  annot = static_cast<AnnotMarkup *>(POPPLER_ANNOT (poppler_annot)->annot);

  annot_popup = annot->getPopup ();
  if (!annot_popup)
    return;

  if (annot_popup->getOpen () != is_open)
    annot_popup->setOpen (is_open);
}

/**
 * poppler_annot_markup_get_popup_rectangle:
 * @poppler_annot: a #PopplerAnnotMarkup
 * @poppler_rect: (out): a #PopplerRectangle to store the popup rectangle
 *
 * Retrieves the rectangle of the popup window related to @poppler_annot.
 *
 * Return value: %TRUE if #PopplerRectangle was correctly filled, %FALSE otherwise
 *
 * Since: 0.12
 **/
gboolean
poppler_annot_markup_get_popup_rectangle (PopplerAnnotMarkup *poppler_annot,
					  PopplerRectangle   *poppler_rect)
{
  AnnotMarkup *annot;
  Annot *annot_popup;
  PDFRectangle *annot_rect;

  g_return_val_if_fail (POPPLER_IS_ANNOT_MARKUP (poppler_annot), FALSE);
  g_return_val_if_fail (poppler_rect != NULL, FALSE);

  annot = static_cast<AnnotMarkup *>(POPPLER_ANNOT (poppler_annot)->annot);
  annot_popup = annot->getPopup ();
  if (!annot_popup)
    return FALSE;

  annot_rect = annot_popup->getRect ();
  poppler_rect->x1 = annot_rect->x1;
  poppler_rect->x2 = annot_rect->x2;
  poppler_rect->y1 = annot_rect->y1;
  poppler_rect->y2 = annot_rect->y2;

  return TRUE;
}

/**
 * poppler_annot_markup_get_opacity:
 * @poppler_annot: a #PopplerAnnotMarkup
 *
 * Retrieves the opacity value of @poppler_annot.
 *
 * Return value: the opacity value of @poppler_annot,
 *               between 0 (transparent) and 1 (opaque)
 */
gdouble
poppler_annot_markup_get_opacity (PopplerAnnotMarkup *poppler_annot)
{
  AnnotMarkup *annot;

  g_return_val_if_fail (POPPLER_IS_ANNOT_MARKUP (poppler_annot), 0);

  annot = static_cast<AnnotMarkup *>(POPPLER_ANNOT (poppler_annot)->annot);
  
  return annot->getOpacity ();
}

/**
 * poppler_annot_markup_set_opacity:
 * @poppler_annot: a #PopplerAnnotMarkup
 * @opacity: a constant opacity value, between 0 (transparent) and 1 (opaque)
 *
 * Sets the opacity of @poppler_annot. This value applies to
 * all visible elements of @poppler_annot in its closed state,
 * but not to the pop-up window that appears when it's openened
 *
 * Since: 0.16
 */
void
poppler_annot_markup_set_opacity (PopplerAnnotMarkup *poppler_annot,
				  gdouble             opacity)
{
  AnnotMarkup *annot;

  g_return_if_fail (POPPLER_IS_ANNOT_MARKUP (poppler_annot));

  annot = static_cast<AnnotMarkup *>(POPPLER_ANNOT (poppler_annot)->annot);
  annot->setOpacity(opacity);
}

/**
 * poppler_annot_markup_get_date:
 * @poppler_annot: a #PopplerAnnotMarkup
 *
 * Returns the date and time when the annotation was created
 *
 * Return value: (transfer full): a #GDate representing the date and time
 *               when the annotation was created, or %NULL
 */
GDate *
poppler_annot_markup_get_date (PopplerAnnotMarkup *poppler_annot)
{
  AnnotMarkup *annot;
  GooString *annot_date;
  time_t timet;

  g_return_val_if_fail (POPPLER_IS_ANNOT_MARKUP (poppler_annot), NULL);

  annot = static_cast<AnnotMarkup *>(POPPLER_ANNOT (poppler_annot)->annot);
  annot_date = annot->getDate ();
  if (!annot_date)
    return NULL;

  if (_poppler_convert_pdf_date_to_gtime (annot_date, &timet)) {
    GDate *date;

    date = g_date_new ();
    g_date_set_time_t (date, timet);

    return date;
  }

  return NULL;
}

/**
* poppler_annot_markup_get_subject:
* @poppler_annot: a #PopplerAnnotMarkup
*
* Retrives the subject text of @poppler_annot.
*
* Return value: the subject text of @poppler_annot.
*/
gchar *
poppler_annot_markup_get_subject (PopplerAnnotMarkup *poppler_annot)
{
  AnnotMarkup *annot;
  GooString *text;

  g_return_val_if_fail (POPPLER_IS_ANNOT_MARKUP (poppler_annot), NULL);

  annot = static_cast<AnnotMarkup *>(POPPLER_ANNOT (poppler_annot)->annot);

  text = annot->getSubject ();

  return text ? _poppler_goo_string_to_utf8 (text) : NULL;
}

/**
* poppler_annot_markup_get_reply_to:
* @poppler_annot: a #PopplerAnnotMarkup
*
* Gets the reply type of @poppler_annot.
*
* Return value: #PopplerAnnotMarkupReplyType of @poppler_annot.
*/
PopplerAnnotMarkupReplyType
poppler_annot_markup_get_reply_to (PopplerAnnotMarkup *poppler_annot)
{
  AnnotMarkup *annot;

  g_return_val_if_fail (POPPLER_IS_ANNOT_MARKUP (poppler_annot), POPPLER_ANNOT_MARKUP_REPLY_TYPE_R);

  annot = static_cast<AnnotMarkup *>(POPPLER_ANNOT (poppler_annot)->annot);
  
  switch (annot->getReplyTo ())
  {
    case AnnotMarkup::replyTypeR:
      return POPPLER_ANNOT_MARKUP_REPLY_TYPE_R;
    case AnnotMarkup::replyTypeGroup:
      return POPPLER_ANNOT_MARKUP_REPLY_TYPE_GROUP;
    default:
      g_warning ("Unsupported Annot Markup Reply To Type");
  }

  return POPPLER_ANNOT_MARKUP_REPLY_TYPE_R;
}

/**
* poppler_annot_markup_get_external_data:
* @poppler_annot: a #PopplerAnnotMarkup
*
* Gets the external data type of @poppler_annot.
*
* Return value: #PopplerAnnotExternalDataType of @poppler_annot.
*/
PopplerAnnotExternalDataType
poppler_annot_markup_get_external_data (PopplerAnnotMarkup *poppler_annot)
{
  AnnotMarkup *annot;

  g_return_val_if_fail (POPPLER_IS_ANNOT_MARKUP (poppler_annot), POPPLER_ANNOT_EXTERNAL_DATA_MARKUP_UNKNOWN);

  annot = static_cast<AnnotMarkup *>(POPPLER_ANNOT (poppler_annot)->annot);

  switch (annot->getExData ())
    {
    case annotExternalDataMarkup3D:
      return POPPLER_ANNOT_EXTERNAL_DATA_MARKUP_3D;
    case annotExternalDataMarkupUnknown:
      return POPPLER_ANNOT_EXTERNAL_DATA_MARKUP_UNKNOWN;
    default:
      g_warning ("Unsupported Annot Markup External Data");
    }

  return POPPLER_ANNOT_EXTERNAL_DATA_MARKUP_UNKNOWN;
}

/* PopplerAnnotText */
/**
 * poppler_annot_text_get_is_open:
 * @poppler_annot: a #PopplerAnnotText
 *
 * Retrieves the state of @poppler_annot.
 *
 * Return value: the state of @poppler_annot. %TRUE if it's open, %FALSE in
 *               other case.
 **/
gboolean
poppler_annot_text_get_is_open (PopplerAnnotText *poppler_annot)
{
  AnnotText *annot;

  g_return_val_if_fail (POPPLER_IS_ANNOT_TEXT (poppler_annot), FALSE);

  annot = static_cast<AnnotText *>(POPPLER_ANNOT (poppler_annot)->annot);

  return annot->getOpen ();
}

/**
 * poppler_annot_text_set_is_open:
 * @poppler_annot: a #PopplerAnnotText
 * @is_open: whether annotation should initially be displayed open
 *
 * Sets whether @poppler_annot should initially be displayed open
 *
 * Since: 0.16
 */
void
poppler_annot_text_set_is_open (PopplerAnnotText *poppler_annot,
				gboolean          is_open)
{
  AnnotText *annot;

  g_return_if_fail (POPPLER_IS_ANNOT_TEXT (poppler_annot));

  annot = static_cast<AnnotText *>(POPPLER_ANNOT (poppler_annot)->annot);
  annot->setOpen(is_open);
}

/**
 * poppler_annot_text_get_icon:
 * @poppler_annot: a #PopplerAnnotText
 *
 * Gets name of the icon of @poppler_annot.
 *
 * Return value: a new allocated string containing the icon name
 */
gchar *
poppler_annot_text_get_icon (PopplerAnnotText *poppler_annot)
{
  AnnotText *annot;
  GooString *text;

  g_return_val_if_fail (POPPLER_IS_ANNOT_TEXT (poppler_annot), NULL);

  annot = static_cast<AnnotText *>(POPPLER_ANNOT (poppler_annot)->annot);

  text = annot->getIcon ();

  return text ? _poppler_goo_string_to_utf8 (text) : NULL;
}

/**
 * poppler_annot_text_set_icon:
 * @poppler_annot: a #PopplerAnnotText
 * @icon: the name of an icon
 *
 * Sets the icon of @poppler_annot. The following predefined
 * icons are currently supported:
 * <variablelist>
 *  <varlistentry>
 *   <term>#POPPLER_ANNOT_TEXT_ICON_NOTE</term>
 *  </varlistentry>
 *  <varlistentry>
 *   <term>#POPPLER_ANNOT_TEXT_ICON_COMMENT</term>
 *  </varlistentry>
 *  <varlistentry>
 *   <term>#POPPLER_ANNOT_TEXT_ICON_KEY</term>
 *  </varlistentry>
 *  <varlistentry>
 *   <term>#POPPLER_ANNOT_TEXT_ICON_HELP</term>
 *  </varlistentry>
 *  <varlistentry>
 *   <term>#POPPLER_ANNOT_TEXT_ICON_NEW_PARAGRAPH</term>
 *  </varlistentry>
 *  <varlistentry>
 *   <term>#POPPLER_ANNOT_TEXT_ICON_PARAGRAPH</term>
 *  </varlistentry>
 *  <varlistentry>
 *   <term>#POPPLER_ANNOT_TEXT_ICON_INSERT</term>
 *  </varlistentry>
 *  <varlistentry>
 *   <term>#POPPLER_ANNOT_TEXT_ICON_CROSS</term>
 *  </varlistentry>
 *  <varlistentry>
 *   <term>#POPPLER_ANNOT_TEXT_ICON_CIRCLE</term>
 *  </varlistentry>
 * </variablelist>
 *
 * Since: 0.16
 */
void
poppler_annot_text_set_icon (PopplerAnnotText *poppler_annot,
			     const gchar      *icon)
{
  AnnotText *annot;
  GooString *text;

  g_return_if_fail (POPPLER_IS_ANNOT_TEXT (poppler_annot));

  annot = static_cast<AnnotText *>(POPPLER_ANNOT (poppler_annot)->annot);

  text = new GooString(icon);
  annot->setIcon(text);
  delete text;
}

/**
 * poppler_annot_text_get_state:
 * @poppler_annot: a #PopplerAnnotText
 *
 * Retrieves the state of @poppler_annot.
 *
 * Return value: #PopplerAnnotTextState of @poppler_annot.
 **/ 
PopplerAnnotTextState
poppler_annot_text_get_state (PopplerAnnotText *poppler_annot)
{
  AnnotText *annot;

  g_return_val_if_fail (POPPLER_IS_ANNOT_TEXT (poppler_annot), POPPLER_ANNOT_TEXT_STATE_UNKNOWN);

  annot = static_cast<AnnotText *>(POPPLER_ANNOT (poppler_annot)->annot);

  switch (annot->getState ())
    {
    case AnnotText::stateUnknown:
      return POPPLER_ANNOT_TEXT_STATE_UNKNOWN;
    case AnnotText::stateMarked:
      return POPPLER_ANNOT_TEXT_STATE_MARKED;
    case AnnotText::stateUnmarked:
      return POPPLER_ANNOT_TEXT_STATE_UNMARKED;
    case AnnotText::stateAccepted:
      return POPPLER_ANNOT_TEXT_STATE_ACCEPTED;
    case AnnotText::stateRejected:
      return POPPLER_ANNOT_TEXT_STATE_REJECTED;
    case AnnotText::stateCancelled:
      return POPPLER_ANNOT_TEXT_STATE_CANCELLED;
    case AnnotText::stateCompleted:
      return POPPLER_ANNOT_TEXT_STATE_COMPLETED;
    case AnnotText::stateNone:
      return POPPLER_ANNOT_TEXT_STATE_NONE;
    default:
      g_warning ("Unsupported Annot Text State");
    }

  return POPPLER_ANNOT_TEXT_STATE_UNKNOWN;
}

/* PopplerAnnotTextMarkup */
/**
 * poppler_annot_text_markup_set_quadrilaterals:
 * @poppler_annot: A #PopplerAnnotTextMarkup
 * @quadrilaterals: (element-type PopplerQuadrilateral): A #GArray of
 *   #PopplerQuadrilateral<!-- -->s
 *
 * Set the regions (Quadrilaterals) to apply the text markup in @poppler_annot.
 *
 * Since: 0.26
 **/
void
poppler_annot_text_markup_set_quadrilaterals (PopplerAnnotTextMarkup *poppler_annot,
                                              GArray                 *quadrilaterals)
{
  AnnotTextMarkup *annot;

  g_return_if_fail (POPPLER_IS_ANNOT_TEXT_MARKUP (poppler_annot));
  g_return_if_fail (quadrilaterals != NULL && quadrilaterals->len > 0);

  annot = static_cast<AnnotTextMarkup *>(POPPLER_ANNOT (poppler_annot)->annot);
  AnnotQuadrilaterals *quads = create_annot_quads_from_poppler_quads (quadrilaterals);
  annot->setQuadrilaterals (quads);
  delete quads;
}

/**
 * poppler_annot_text_markup_get_quadrilaterals:
 * @poppler_annot: A #PopplerAnnotTextMarkup
 *
 * Returns a #GArray of #PopplerQuadrilateral items that map from a
 * location on @page to a #PopplerAnnotTextMarkup.  This array must be freed
 * when done.
 *
 * Return value: (element-type PopplerQuadrilateral) (transfer full): A #GArray of #PopplerQuadrilateral
 *
 * Since: 0.26
 **/
GArray *
poppler_annot_text_markup_get_quadrilaterals (PopplerAnnotTextMarkup *poppler_annot)
{
  AnnotTextMarkup *annot;

  g_return_val_if_fail (POPPLER_IS_ANNOT_TEXT_MARKUP (poppler_annot), NULL);

  annot = static_cast<AnnotTextMarkup *>(POPPLER_ANNOT (poppler_annot)->annot);

  return create_poppler_quads_from_annot_quads (annot->getQuadrilaterals());
}

/* PopplerAnnotFreeText */
/**
 * poppler_annot_free_text_get_quadding:
 * @poppler_annot: a #PopplerAnnotFreeText
 *
 * Retrieves the justification of the text of @poppler_annot.
 *
 * Return value: #PopplerAnnotFreeTextQuadding of @poppler_annot.
 **/ 
PopplerAnnotFreeTextQuadding
poppler_annot_free_text_get_quadding (PopplerAnnotFreeText *poppler_annot)
{
  AnnotFreeText *annot;

  g_return_val_if_fail (POPPLER_IS_ANNOT_FREE_TEXT (poppler_annot), POPPLER_ANNOT_FREE_TEXT_QUADDING_LEFT_JUSTIFIED);

  annot = static_cast<AnnotFreeText *>(POPPLER_ANNOT (poppler_annot)->annot);

  switch (annot->getQuadding ())
  {
    case AnnotFreeText::quaddingLeftJustified:
      return POPPLER_ANNOT_FREE_TEXT_QUADDING_LEFT_JUSTIFIED;
    case AnnotFreeText::quaddingCentered:
      return POPPLER_ANNOT_FREE_TEXT_QUADDING_CENTERED;
    case AnnotFreeText::quaddingRightJustified:
      return POPPLER_ANNOT_FREE_TEXT_QUADDING_RIGHT_JUSTIFIED;
    default:
      g_warning ("Unsupported Annot Free Text Quadding");
  }

  return POPPLER_ANNOT_FREE_TEXT_QUADDING_LEFT_JUSTIFIED;
}

/**
 * poppler_annot_free_text_get_callout_line:
 * @poppler_annot: a #PopplerAnnotFreeText
 *
 * Retrieves a #PopplerAnnotCalloutLine of four or six numbers specifying a callout
 * line attached to the @poppler_annot.
 *
 * Return value: a new allocated #PopplerAnnotCalloutLine if the annot has a callout
 *               line, %NULL in other case. It must be freed with g_free() when
 *               done.
 **/
PopplerAnnotCalloutLine *
poppler_annot_free_text_get_callout_line (PopplerAnnotFreeText *poppler_annot)
{
  AnnotFreeText *annot;
  AnnotCalloutLine *line;

  g_return_val_if_fail (POPPLER_IS_ANNOT_FREE_TEXT (poppler_annot), NULL);

  annot = static_cast<AnnotFreeText *>(POPPLER_ANNOT (poppler_annot)->annot);

  if ((line = annot->getCalloutLine ())) {
    AnnotCalloutMultiLine *multiline;
    PopplerAnnotCalloutLine *callout = g_new0 (PopplerAnnotCalloutLine, 1);

    callout->x1 = line->getX1();
    callout->y1 = line->getY1();
    callout->x2 = line->getX2();
    callout->y2 = line->getY2();

    if ((multiline = static_cast<AnnotCalloutMultiLine *>(line))) {
      callout->multiline = TRUE;
      callout->x3 = multiline->getX3();
      callout->y3 = multiline->getY3();
      return callout;
    }

    callout->multiline = FALSE;
    return callout;
  }

  return NULL;
}

/* PopplerAnnotFileAttachment */
/**
 * poppler_annot_file_attachment_get_attachment:
 * @poppler_annot: a #PopplerAnnotFileAttachment
 *
 * Creates a #PopplerAttachment for the file of the file attachment annotation @annot.
 * The #PopplerAttachment must be unrefed with g_object_unref by the caller.
 *
 * Return value: (transfer full): @PopplerAttachment
 *
 * Since: 0.14
 **/
PopplerAttachment *
poppler_annot_file_attachment_get_attachment (PopplerAnnotFileAttachment *poppler_annot)
{
  AnnotFileAttachment *annot;
  PopplerAttachment *attachment;

  g_return_val_if_fail (POPPLER_IS_ANNOT_FILE_ATTACHMENT (poppler_annot), NULL);

  annot = static_cast<AnnotFileAttachment *>(POPPLER_ANNOT (poppler_annot)->annot);

  FileSpec *file = new FileSpec (annot->getFile());
  attachment = _poppler_attachment_new (file);
  delete file;

  return attachment;
}

/**
 * poppler_annot_file_attachment_get_name:
 * @poppler_annot: a #PopplerAnnotFileAttachment
 *
 * Retrieves the name of @poppler_annot.
 *
 * Return value: a new allocated string with the name of @poppler_annot. It must
 *               be freed with g_free() when done.
 * Since: 0.14
 **/
gchar *
poppler_annot_file_attachment_get_name (PopplerAnnotFileAttachment *poppler_annot)
{
  AnnotFileAttachment *annot;
  GooString *name;

  g_return_val_if_fail (POPPLER_IS_ANNOT_FILE_ATTACHMENT (poppler_annot), NULL);

  annot = static_cast<AnnotFileAttachment *>(POPPLER_ANNOT (poppler_annot)->annot);
  name = annot->getName ();

  return name ? _poppler_goo_string_to_utf8 (name) : NULL;
}

/* PopplerAnnotCalloutLine */
POPPLER_DEFINE_BOXED_TYPE (PopplerAnnotCalloutLine, poppler_annot_callout_line,
			   poppler_annot_callout_line_copy,
			   poppler_annot_callout_line_free)

/**
 * poppler_annot_callout_line_new:
 *
 * Creates a new empty #PopplerAnnotCalloutLine.
 *
 * Return value: a new allocated #PopplerAnnotCalloutLine, %NULL in other case.
 *               It must be freed when done.
 **/
PopplerAnnotCalloutLine *
poppler_annot_callout_line_new (void)
{
  return g_new0 (PopplerAnnotCalloutLine, 1);
}

/**
 * poppler_annot_callout_line_copy:
 * @callout: the #PopplerAnnotCalloutLine to be copied.
 *
 * It does copy @callout to a new #PopplerAnnotCalloutLine.
 *
 * Return value: a new allocated #PopplerAnnotCalloutLine as exact copy of
 *               @callout, %NULL in other case. It must be freed when done.
 **/
PopplerAnnotCalloutLine *
poppler_annot_callout_line_copy (PopplerAnnotCalloutLine *callout)
{
  PopplerAnnotCalloutLine *new_callout;

  g_return_val_if_fail (callout != NULL, NULL);
  
  new_callout = g_new0 (PopplerAnnotCalloutLine, 1);
  *new_callout = *callout;

  return new_callout;
}

/**
 * poppler_annot_callout_line_free:
 * @callout: a #PopplerAnnotCalloutLine
 *
 * Frees the memory used by #PopplerAnnotCalloutLine.
 **/
void
poppler_annot_callout_line_free (PopplerAnnotCalloutLine *callout)
{
  g_free (callout);
}


/* PopplerAnnotMovie */
/**
 * poppler_annot_movie_get_title:
 * @poppler_annot: a #PopplerAnnotMovie
 *
 * Retrieves the movie title of @poppler_annot.
 *
 * Return value: the title text of @poppler_annot.
 *
 * Since: 0.14
 */
gchar *
poppler_annot_movie_get_title (PopplerAnnotMovie *poppler_annot)
{
  AnnotMovie *annot;
  GooString *title;

  g_return_val_if_fail (POPPLER_IS_ANNOT_MOVIE (poppler_annot), NULL);

  annot = static_cast<AnnotMovie *>(POPPLER_ANNOT (poppler_annot)->annot);

  title = annot->getTitle ();

  return title ? _poppler_goo_string_to_utf8 (title) : NULL;
}

/**
 * poppler_annot_movie_get_movie:
 * @poppler_annot: a #PopplerAnnotMovie
 *
 * Retrieves the movie object (PopplerMovie) stored in the @poppler_annot.
 *
 * Return value: (transfer none): the movie object stored in the @poppler_annot. The returned
 *               object is owned by #PopplerAnnotMovie and should not be freed
 *
 * Since: 0.14
 */
PopplerMovie *
poppler_annot_movie_get_movie (PopplerAnnotMovie *poppler_annot)
{
  return poppler_annot->movie;
}

/* PopplerAnnotScreen */
/**
 * poppler_annot_screen_get_action:
 * @poppler_annot: a #PopplerAnnotScreen
 *
 * Retrieves the action (#PopplerAction) that shall be performed when @poppler_annot is activated
 *
 * Return value: (transfer none): the action to perform. The returned
 *               object is owned by @poppler_annot and should not be freed
 *
 * Since: 0.14
 */
PopplerAction *
poppler_annot_screen_get_action (PopplerAnnotScreen *poppler_annot)
{
  return poppler_annot->action;
}

/* PopplerAnnotLine */
/**
 * poppler_annot_line_set_vertices:
 * @poppler_annot: a #PopplerAnnotLine
 * @start: a #PopplerPoint of the starting vertice
 * @end: a #PopplerPoint of the ending vertice
 *
 * Set the coordinate points where the @poppler_annot starts and ends.
 *
 * Since: 0.26
 */
void
poppler_annot_line_set_vertices (PopplerAnnotLine *poppler_annot,
				 PopplerPoint     *start,
				 PopplerPoint     *end)
{
  AnnotLine *annot;

  g_return_if_fail (POPPLER_IS_ANNOT_LINE (poppler_annot));
  g_return_if_fail (start != NULL);
  g_return_if_fail (end != NULL);

  annot = static_cast<AnnotLine *>(POPPLER_ANNOT (poppler_annot)->annot);
  annot->setVertices (start->x, start->y, end->x, end->y);
}

/* PopplerAnnotCircle and PopplerAnnotSquare helpers */
static PopplerColor *
poppler_annot_geometry_get_interior_color (PopplerAnnot *poppler_annot)
{
  AnnotGeometry *annot;

  annot = static_cast<AnnotGeometry *>(POPPLER_ANNOT (poppler_annot)->annot);

  return create_poppler_color_from_annot_color (annot->getInteriorColor ());
}

static void
poppler_annot_geometry_set_interior_color (PopplerAnnot *poppler_annot,
					    PopplerColor *poppler_color)
{
  AnnotGeometry *annot;

  annot = static_cast<AnnotGeometry *>(POPPLER_ANNOT (poppler_annot)->annot);

  /* Annot takes ownership of the color */
  annot->setInteriorColor (create_annot_color_from_poppler_color (poppler_color));
}

/* PopplerAnnotCircle */
/**
 * poppler_annot_circle_get_interior_color:
 * @poppler_annot: a #PopplerAnnotCircle
 *
 * Retrieves the interior color of @poppler_annot.
 *
 * Return value: a new allocated #PopplerColor with the color values of
 *               @poppler_annot, or %NULL. It must be freed with g_free() when done.
 *
 * Since: 0.26
 */
PopplerColor *
poppler_annot_circle_get_interior_color (PopplerAnnotCircle *poppler_annot)
{
  g_return_val_if_fail (POPPLER_IS_ANNOT_CIRCLE (poppler_annot), NULL);

  return poppler_annot_geometry_get_interior_color (POPPLER_ANNOT (poppler_annot));
}

/**
 * poppler_annot_circle_set_interior_color:
 * @poppler_annot: a #PopplerAnnotCircle
 * @poppler_color: (allow-none): a #PopplerColor, or %NULL
 *
 * Sets the interior color of @poppler_annot.
 *
 * Since: 0.26
 */
void
poppler_annot_circle_set_interior_color (PopplerAnnotCircle *poppler_annot,
					 PopplerColor       *poppler_color)
{
  g_return_if_fail (POPPLER_IS_ANNOT_CIRCLE (poppler_annot));

  poppler_annot_geometry_set_interior_color (POPPLER_ANNOT (poppler_annot), poppler_color);
}

/* PopplerAnnotSquare */
/**
 * poppler_annot_square_get_interior_color:
 * @poppler_annot: a #PopplerAnnotSquare
 *
 * Retrieves the interior color of @poppler_annot.
 *
 * Return value: a new allocated #PopplerColor with the color values of
 *               @poppler_annot, or %NULL. It must be freed with g_free() when done.
 *
 * Since: 0.26
 */
PopplerColor *
poppler_annot_square_get_interior_color (PopplerAnnotSquare *poppler_annot)
{
  g_return_val_if_fail (POPPLER_IS_ANNOT_SQUARE (poppler_annot), NULL);

  return poppler_annot_geometry_get_interior_color (POPPLER_ANNOT (poppler_annot));
}

/**
 * poppler_annot_square_set_interior_color:
 * @poppler_annot: a #PopplerAnnotSquare
 * @poppler_color: (allow-none): a #PopplerColor, or %NULL
 *
 * Sets the interior color of @poppler_annot.
 *
 * Since: 0.26
 */
void
poppler_annot_square_set_interior_color (PopplerAnnotSquare *poppler_annot,
					 PopplerColor       *poppler_color)
{
  g_return_if_fail (POPPLER_IS_ANNOT_SQUARE (poppler_annot));

  poppler_annot_geometry_set_interior_color (POPPLER_ANNOT (poppler_annot), poppler_color);
}
