/* poppler-page.cc: glib wrapper for poppler
 * Copyright (C) 2005, Red Hat, Inc.
 *
 * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 */

#include "config.h"
#include <math.h>

#include <goo/GooList.h>
#include <splash/SplashBitmap.h>
#include <GlobalParams.h>
#include <PDFDoc.h>
#include <Outline.h>
#include <ErrorCodes.h>
#include <UnicodeMap.h>
#include <GfxState.h>
#include <PageTransition.h>

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

enum
{
  PROP_0,
  PROP_LABEL
};

typedef struct _PopplerPageClass PopplerPageClass;
struct _PopplerPageClass
{
  GObjectClass parent_class;
};

G_DEFINE_TYPE (PopplerPage, poppler_page, G_TYPE_OBJECT);

PopplerPage *
_poppler_page_new (PopplerDocument *document, Page *page, int index)
{
  PopplerPage *poppler_page;

  g_return_val_if_fail (POPPLER_IS_DOCUMENT (document), NULL);

  poppler_page = (PopplerPage *) g_object_new (POPPLER_TYPE_PAGE, NULL, NULL);
  poppler_page->document = (PopplerDocument *) g_object_ref (document);
  poppler_page->page = page;
  poppler_page->index = index;

  return poppler_page;
}

static void
poppler_page_finalize (GObject *object)
{
  PopplerPage *page = POPPLER_PAGE (object);

  g_object_unref (page->document);
  page->document = NULL;

  if (page->gfx != NULL)
    delete page->gfx;
  if (page->text_dev != NULL)
    delete page->text_dev;
#if defined (HAVE_CAIRO)
  if (page->image_dev != NULL)
    delete page->image_dev;
#endif
  /* page->page is owned by the document */
}

/**
 * poppler_page_get_size:
 * @page: A #PopplerPage
 * @width: return location for the width of @page
 * @height: return location for the height of @page
 * 
 * Gets the size of @page at the current scale and rotation.
 **/
void
poppler_page_get_size (PopplerPage *page,
		       double      *width,
		       double      *height)
{
  double page_width, page_height;
  int rotate;

  g_return_if_fail (POPPLER_IS_PAGE (page));

  rotate = page->page->getRotate ();
  if (rotate == 90 || rotate == 270) {
    page_height = page->page->getCropWidth ();
    page_width = page->page->getCropHeight ();
  } else {
    page_width = page->page->getCropWidth ();
    page_height = page->page->getCropHeight ();
  }

  if (width != NULL)
    *width = page_width;
  if (height != NULL)
    *height = page_height;
}

/**
 * poppler_page_get_index:
 * @page: a #PopplerPage
 * 
 * Returns the index of @page
 * 
 * Return value: index value of @page
 **/
int
poppler_page_get_index (PopplerPage *page)
{
  g_return_val_if_fail (POPPLER_IS_PAGE (page), 0);

  return page->index;
}

/**
 * poppler_page_get_duration:
 * @page: a #PopplerPage
 *
 * Returns the duration of @page
 *
 * Return value: duration in seconds of @page or -1.
 **/
double
poppler_page_get_duration (PopplerPage *page)
{
  g_return_val_if_fail (POPPLER_IS_PAGE (page), -1);

  return page->page->getDuration ();
}

/**
 * poppler_page_get_transition:
 * @page: a #PopplerPage
 *
 * Returns the transition effect of @page
 *
 * Return value: a #PopplerPageTransition or NULL.
 **/
PopplerPageTransition *
poppler_page_get_transition (PopplerPage *page)
{
  PageTransition *trans;
  PopplerPageTransition *transition;
  Object obj;
  
  g_return_val_if_fail (POPPLER_IS_PAGE (page), NULL);

  trans = new PageTransition (page->page->getTrans (&obj));
  obj.free ();

  if (!trans->isOk ()) {
    delete trans;
    return NULL;
  }

  transition = poppler_page_transition_new ();

  switch (trans->getType ())
    {
      case transitionReplace:
        transition->type = POPPLER_PAGE_TRANSITION_REPLACE;
	break;
      case transitionSplit:
	transition->type = POPPLER_PAGE_TRANSITION_SPLIT;
	break;
      case transitionBlinds:
        transition->type = POPPLER_PAGE_TRANSITION_BLINDS;
	break;
      case transitionBox:
        transition->type = POPPLER_PAGE_TRANSITION_BOX;
	break;
      case transitionWipe:
        transition->type = POPPLER_PAGE_TRANSITION_WIPE;
	break;
      case transitionDissolve:
        transition->type = POPPLER_PAGE_TRANSITION_DISSOLVE;
	break;
      case transitionGlitter:
        transition->type = POPPLER_PAGE_TRANSITION_GLITTER;
	break;
      case transitionFly:
        transition->type = POPPLER_PAGE_TRANSITION_FLY;
	break;
      case transitionPush:
        transition->type = POPPLER_PAGE_TRANSITION_PUSH;
	break;
      case transitionCover:
        transition->type = POPPLER_PAGE_TRANSITION_COVER;
	break;
      case transitionUncover:
        transition->type = POPPLER_PAGE_TRANSITION_UNCOVER;
        break;
      case transitionFade:
        transition->type = POPPLER_PAGE_TRANSITION_FADE;
	break;
      default:
        g_assert_not_reached ();
    }

  transition->alignment = (trans->getAlignment() == transitionHorizontal) ?
	  POPPLER_PAGE_TRANSITION_HORIZONTAL :
	  POPPLER_PAGE_TRANSITION_VERTICAL;

  transition->direction = (trans->getDirection() == transitionInward) ?
	  POPPLER_PAGE_TRANSITION_INWARD :
	  POPPLER_PAGE_TRANSITION_OUTWARD;

  transition->duration = trans->getDuration();
  transition->angle = trans->getAngle();
  transition->scale = trans->getScale();
  transition->rectangular = trans->isRectangular();
  
  delete trans;
  
  return transition;
}

#if defined (HAVE_CAIRO)

typedef struct {
  unsigned char *cairo_data;
  cairo_surface_t *surface;
  cairo_t *cairo;
} OutputDevData;

static void
poppler_page_prepare_output_dev (PopplerPage *page,
				 double scale,
				 int rotation,
				 gboolean transparent,
				 OutputDevData *output_dev_data)
{
  CairoOutputDev *output_dev;
  cairo_surface_t *surface;
  double width, height;
  int cairo_width, cairo_height, cairo_rowstride, rotate;
  unsigned char *cairo_data;

  rotate = rotation + page->page->getRotate ();
  if (rotate == 90 || rotate == 270) {
    height = page->page->getCropWidth ();
    width = page->page->getCropHeight ();
  } else {
    width = page->page->getCropWidth ();
    height = page->page->getCropHeight ();
  }

  cairo_width = (int) ceil(width * scale);
  cairo_height = (int) ceil(height * scale);

  output_dev = page->document->output_dev;
  cairo_rowstride = cairo_width * 4;
  cairo_data = (guchar *) gmalloc (cairo_height * cairo_rowstride);
  if (transparent)
      memset (cairo_data, 0x00, cairo_height * cairo_rowstride);
  else
      memset (cairo_data, 0xff, cairo_height * cairo_rowstride);

  surface = cairo_image_surface_create_for_data(cairo_data,
						CAIRO_FORMAT_ARGB32,
	  					cairo_width, cairo_height, 
						cairo_rowstride);

  output_dev_data->cairo_data = cairo_data;
  output_dev_data->surface = surface;
  output_dev_data->cairo = cairo_create (surface);
  output_dev->setCairo (output_dev_data->cairo);
}

static void
copy_cairo_surface_to_pixbuf (cairo_surface_t *surface,
			      unsigned char   *data,
			      GdkPixbuf       *pixbuf)
{
  int cairo_width, cairo_height, cairo_rowstride;
  unsigned char *pixbuf_data, *dst, *cairo_data;
  int pixbuf_rowstride, pixbuf_n_channels;
  unsigned int *src;
  int x, y;

  cairo_width = cairo_image_surface_get_width (surface);
  cairo_height = cairo_image_surface_get_height (surface);
  cairo_rowstride = cairo_width * 4;
  cairo_data = data;

  pixbuf_data = gdk_pixbuf_get_pixels (pixbuf);
  pixbuf_rowstride = gdk_pixbuf_get_rowstride (pixbuf);
  pixbuf_n_channels = gdk_pixbuf_get_n_channels (pixbuf);

  if (cairo_width > gdk_pixbuf_get_width (pixbuf))
    cairo_width = gdk_pixbuf_get_width (pixbuf);
  if (cairo_height > gdk_pixbuf_get_height (pixbuf))
    cairo_height = gdk_pixbuf_get_height (pixbuf);
  for (y = 0; y < cairo_height; y++)
    {
      src = (unsigned int *) (cairo_data + y * cairo_rowstride);
      dst = pixbuf_data + y * pixbuf_rowstride;
      for (x = 0; x < cairo_width; x++) 
	{
	  dst[0] = (*src >> 16) & 0xff;
	  dst[1] = (*src >> 8) & 0xff; 
	  dst[2] = (*src >> 0) & 0xff;
	  if (pixbuf_n_channels == 4)
	      dst[3] = (*src >> 24) & 0xff;
	  dst += pixbuf_n_channels;
	  src++;
	}
    }
}	

static void
poppler_page_copy_to_pixbuf (PopplerPage *page,
			     GdkPixbuf *pixbuf,
			     OutputDevData *output_dev_data)
{
  copy_cairo_surface_to_pixbuf (output_dev_data->surface,
				output_dev_data->cairo_data,
				pixbuf);
  
  page->document->output_dev->setCairo (NULL);
  cairo_surface_destroy (output_dev_data->surface);
  cairo_destroy (output_dev_data->cairo);
  gfree (output_dev_data->cairo_data);
}

#elif defined (HAVE_SPLASH)
 
typedef struct {
} OutputDevData;

static void
poppler_page_prepare_output_dev (PopplerPage *page,
				 double scale,
				 int rotation,
				 gboolean transparent,
				 OutputDevData *output_dev_data)
{
  /* pft */
}

static void
poppler_page_copy_to_pixbuf(PopplerPage *page,
			    GdkPixbuf *pixbuf,
			    OutputDevData *data)
{
  SplashOutputDev *output_dev;
  SplashBitmap *bitmap;
  SplashColorPtr color_ptr;
  int splash_width, splash_height, splash_rowstride;
  int pixbuf_rowstride, pixbuf_n_channels;
  guchar *pixbuf_data, *dst;
  int x, y;

  output_dev = page->document->output_dev;

  bitmap = output_dev->getBitmap ();
  color_ptr = bitmap->getDataPtr ();

  splash_width = bitmap->getWidth ();
  splash_height = bitmap->getHeight ();
  splash_rowstride = bitmap->getRowSize ();

  pixbuf_data = gdk_pixbuf_get_pixels (pixbuf);
  pixbuf_rowstride = gdk_pixbuf_get_rowstride (pixbuf);
  pixbuf_n_channels = gdk_pixbuf_get_n_channels (pixbuf);

  if (splash_width > gdk_pixbuf_get_width (pixbuf))
    splash_width = gdk_pixbuf_get_width (pixbuf);
  if (splash_height > gdk_pixbuf_get_height (pixbuf))
    splash_height = gdk_pixbuf_get_height (pixbuf);

  SplashColorPtr pixel = new Guchar[4];
  for (y = 0; y < splash_height; y++)
  {
    dst = pixbuf_data + y * pixbuf_rowstride;
    for (x = 0; x < splash_width; x++)
    {
      output_dev->getBitmap()->getPixel(x, y, pixel);
      dst[0] = pixel[0];
      dst[1] = pixel[1];
      dst[2] = pixel[2];
      if (pixbuf_n_channels == 4)
        dst[3] = 0xff;
      dst += pixbuf_n_channels;
    }
  }
  delete [] pixel;
}

#endif

#if defined (HAVE_CAIRO)

/**
 * poppler_page_render:
 * @page: the page to render from
 * @cairo: cairo context to render to
 *
 * Render the page to the given cairo context.
 **/
void
poppler_page_render (PopplerPage *page,
		     cairo_t *cairo)
{
  CairoOutputDev *output_dev;

  g_return_if_fail (POPPLER_IS_PAGE (page));

  output_dev = page->document->output_dev;
  output_dev->setCairo (cairo);

  page->page->displaySlice(output_dev,
			   72.0, 72.0, 0,
			   gFalse, /* useMediaBox */
			   gTrue, /* Crop */
			   0, 0,
			   (int) ceil (page->page->getCropWidth ()),
			   (int) ceil (page->page->getCropHeight ()),
			   gFalse, /* printing */
			   page->document->doc->getCatalog ());

  output_dev->setCairo (NULL);
}

#endif

/**
 * poppler_page_render:
 * @page: the page to render from
 * @src_x: x coordinate of upper left corner  
 * @src_y: y coordinate of upper left corner  
 * @src_width: width of rectangle to render  
 * @src_height: height of rectangle to render
 * @scale: scale specified as pixels per point
 * @rotation: rotate the document by the specified degree
 * @pixbuf: pixbuf to render into
 *
 * First scale the document to match the specified pixels per point,
 * then render the rectangle given by the upper left corner at
 * (src_x, src_y) and src_width and src_height.
 **/
void
poppler_page_render_to_pixbuf (PopplerPage *page,
			       int src_x, int src_y,
			       int src_width, int src_height,
			       double scale,
			       int rotation,
			       GdkPixbuf *pixbuf)
{
  OutputDevData data;

  g_return_if_fail (POPPLER_IS_PAGE (page));
  g_return_if_fail (scale > 0.0);
  g_return_if_fail (pixbuf != NULL);

  poppler_page_prepare_output_dev (page, scale, rotation, FALSE, &data);

  page->page->displaySlice(page->document->output_dev,
			   72.0 * scale, 72.0 * scale,
			   rotation,
			   gFalse, /* useMediaBox */
			   gTrue, /* Crop */
			   src_x, src_y,
			   src_width, src_height,
			   gFalse, /* printing */
			   page->document->doc->getCatalog ());
  
  poppler_page_copy_to_pixbuf (page, pixbuf, &data);
}

static TextOutputDev *
poppler_page_get_text_output_dev (PopplerPage *page)
{
  if (page->text_dev == NULL) {
    page->text_dev = new TextOutputDev (NULL, gTrue, gFalse, gFalse);

    if (page->gfx)
      delete page->gfx;
    page->gfx = page->page->createGfx(page->text_dev,
				      72.0, 72.0, 0,
				      gFalse, /* useMediaBox */
				      gTrue, /* Crop */
				      -1, -1, -1, -1,
				      gFalse, /* printing */
				      page->document->doc->getCatalog (),
				      NULL, NULL, NULL, NULL);

    page->page->display(page->gfx);

    page->text_dev->endPage();
  }

  return page->text_dev;
}

/**
 * poppler_page_get_selection_region:
 * @page: a #PopplerPage
 * @scale: scale specified as pixels per point
 * @selection: start and end point of selection as a rectangle
 * 
 * Returns a region containing the area that would be rendered by
 * poppler_page_render_selection() or
 * poppler_page_render_selection_to_pixbuf(). The returned
 * region must be freed with gdk_region_destroy().
 * 
 * Return value: a newly allocated #GdkRegion
 **/
GdkRegion *
poppler_page_get_selection_region (PopplerPage      *page,
				   gdouble           scale,
				   PopplerRectangle *selection)
{
  TextOutputDev *text_dev;
  PDFRectangle poppler_selection;
  GooList *list;
  GdkRectangle rect;
  GdkRegion *region;
  int i;

  poppler_selection.x1 = selection->x1;
  poppler_selection.y1 = selection->y1;
  poppler_selection.x2 = selection->x2;
  poppler_selection.y2 = selection->y2;

  text_dev = poppler_page_get_text_output_dev (page);
  list = text_dev->getSelectionRegion(&poppler_selection, scale);

  region = gdk_region_new();

  for (i = 0; i < list->getLength(); i++) {
    PDFRectangle *selection_rect = (PDFRectangle *) list->get(i);
    rect.x      = (gint) selection_rect->x1;
    rect.y      = (gint) selection_rect->y1;
    rect.width  = (gint) (selection_rect->x2 - selection_rect->x1);
    rect.height = (gint) (selection_rect->y2 - selection_rect->y1);
    gdk_region_union_with_rect (region, &rect);
    delete selection_rect;
  }

  delete list;

  return region;
}

#if defined (HAVE_CAIRO)

static void
poppler_page_set_selection_alpha (PopplerPage      *page,
				  double            scale,
				  GdkPixbuf        *pixbuf,
				  PopplerRectangle *selection)
{
  /* Cairo doesn't need this, since cairo generates an alpha channel. */ 
}

#elif defined (HAVE_SPLASH)

static void
poppler_page_set_selection_alpha (PopplerPage      *page,
				  double            scale,
				  GdkPixbuf        *pixbuf,
				  PopplerRectangle *selection)
{
  GdkRegion *region;
  gint n_rectangles, i, x, y, width, height;
  GdkRectangle *rectangles;
  int pixbuf_rowstride, pixbuf_n_channels;
  guchar *pixbuf_data, *dst;

  pixbuf_data = gdk_pixbuf_get_pixels (pixbuf);
  pixbuf_rowstride = gdk_pixbuf_get_rowstride (pixbuf);
  pixbuf_n_channels = gdk_pixbuf_get_n_channels (pixbuf);
  width = gdk_pixbuf_get_width (pixbuf);
  height = gdk_pixbuf_get_height (pixbuf);

  if (pixbuf_n_channels != 4)
    return;

  for (y = 0; y < height; y++) {
      dst = pixbuf_data + y * pixbuf_rowstride;
      for (x = 0; x < width; x++) {
	  dst[3] = 0x00;
	  dst += pixbuf_n_channels;
      }
  }

  region = poppler_page_get_selection_region (page, scale, selection);

  gdk_region_get_rectangles (region, &rectangles, &n_rectangles);
  for (i = 0; i < n_rectangles; i++) {
    for (y = 0; y < rectangles[i].height; y++) {
      dst = pixbuf_data + (rectangles[i].y + y) * pixbuf_rowstride +
	rectangles[i].x * pixbuf_n_channels;
      for (x = 0; x < rectangles[i].width; x++) {
	  dst[3] = 0xff;
	  dst += pixbuf_n_channels;
      }
    }
  }

  g_free (rectangles);

  gdk_region_destroy (region);
}

#endif

#if defined (HAVE_CAIRO)
/**
 * poppler_page_render_selection:
 * @page: the #PopplerPage for which to render selection
 * @cairo: cairo context to render to
 * @selection: start and end point of selection as a rectangle
 * @old_selection: previous selection
 * @glyph_color: color to use for drawing glyphs
 * @background_color: color to use for the selection background
 *
 * Render the selection specified by @selection for @page to
 * the given cairo context.  The selection will be rendered, using
 * @glyph_color for the glyphs and @background_color for the selection
 * background.
 *
 * If non-NULL, @old_selection specifies the selection that is already
 * rendered to @cairo, in which case this function will (some day)
 * only render the changed part of the selection.
 **/
void
poppler_page_render_selection (PopplerPage           *page,
			       cairo_t               *cairo,
			       PopplerRectangle      *selection,
			       PopplerRectangle      *old_selection,
			       PopplerSelectionStyle  style, 
			       GdkColor              *glyph_color,
			       GdkColor              *background_color)
{
  TextOutputDev *text_dev;
  CairoOutputDev *output_dev;
  PDFRectangle pdf_selection(selection->x1, selection->y1,
			     selection->x2, selection->y2);

  GfxColor gfx_background_color = {
      {
	  background_color->red,
	  background_color->green,
	  background_color->blue
      }
  };
  GfxColor gfx_glyph_color = {
      {
	  glyph_color->red,
	  glyph_color->green,
	  glyph_color->blue
      }
  };

  text_dev = poppler_page_get_text_output_dev (page);
  output_dev = page->document->output_dev;
  output_dev->setCairo (cairo);

  text_dev->drawSelection (output_dev, 1.0, 0, &pdf_selection,
			   &gfx_glyph_color, &gfx_background_color);

  output_dev->setCairo (NULL);

  /* We'll need a function to destroy page->text_dev and page->gfx
   * when the application wants to get rid of them.
   *
   * Two improvements: 1) make GfxFont refcounted and let TextPage and
   * friends hold a reference to the GfxFonts they need so we can free
   * up Gfx early.  2) use a TextPage directly when rendering the page
   * so we don't have to use TextOutputDev and render a second
   * time. */
}
#endif

/**
 * poppler_page_render_selection_to_pixbuf:
 * @page: the #PopplerPage for which to render selection
 * @scale: scale specified as pixels per point
 * @rotation: rotate the document by the specified degree
 * @pixbuf: pixbuf to render to
 * @selection: start and end point of selection as a rectangle
 * @old_selection: previous selection
 * @glyph_color: color to use for drawing glyphs
 * @background_color: color to use for the selection background
 * 
 * Render the selection specified by @selection for @page into
 * @pixbuf.  The selection will be rendered at @scale, using
 * @glyph_color for the glyphs and @background_color for the selection
 * background.
 *
 * If non-NULL, @old_selection specifies the selection that is already
 * rendered in @pixbuf, in which case this function will (some day)
 * only render the changed part of the selection.
 **/
void
poppler_page_render_selection_to_pixbuf (PopplerPage           *page,
                                         gdouble                scale,
                                         int                    rotation,
                                         GdkPixbuf             *pixbuf,
                                         PopplerRectangle      *selection,
                                         PopplerRectangle      *old_selection,
					 PopplerSelectionStyle  style,
                                         GdkColor              *glyph_color,
                                         GdkColor              *background_color)
{
  TextOutputDev *text_dev;
  OutputDev *output_dev;
  OutputDevData data;
  PDFRectangle pdf_selection(selection->x1, selection->y1,
			     selection->x2, selection->y2);

  GfxColor gfx_background_color = { 
      {
	  background_color->red,
	  background_color->green,
	  background_color->blue
      }
  };
  GfxColor gfx_glyph_color = {
      {
	  glyph_color->red,
	  glyph_color->green,
	  glyph_color->blue
      }
  };

  text_dev = poppler_page_get_text_output_dev (page);
  output_dev = page->document->output_dev;

  poppler_page_prepare_output_dev (page, scale, rotation, TRUE, &data);

  text_dev->drawSelection (output_dev, scale, rotation, &pdf_selection,
			   &gfx_glyph_color, &gfx_background_color);

  poppler_page_copy_to_pixbuf (page, pixbuf, &data);

  poppler_page_set_selection_alpha (page, scale, pixbuf, selection);

  /* We'll need a function to destroy page->text_dev and page->gfx
   * when the application wants to get rid of them.
   *
   * Two improvements: 1) make GfxFont refcounted and let TextPage and
   * friends hold a reference to the GfxFonts they need so we can free
   * up Gfx early.  2) use a TextPage directly when rendering the page
   * so we don't have to use TextOutputDev and render a second
   * time. */
}


static void
destroy_thumb_data (guchar *pixels, gpointer data)
{
  gfree (pixels);
}

/**
 * poppler_page_get_thumbnail:
 * @page: the #PopperPage to get the thumbnail for
 * 
 * Get the embedded thumbnail for the specified page.  If the document
 * doesn't have an embedded thumbnail for the page, this function
 * returns %NULL.
 * 
 * Return value: the tumbnail as a #GdkPixbuf or %NULL if the document
 * doesn't have a thumbnail for this page.
 **/
GdkPixbuf *
poppler_page_get_thumbnail (PopplerPage *page)
{
  unsigned char *data;
  int width, height, rowstride;

  g_return_val_if_fail (POPPLER_IS_PAGE (page), FALSE);

  if (!page->page->loadThumb (&data, &width, &height, &rowstride))
    return NULL;

  return gdk_pixbuf_new_from_data (data, GDK_COLORSPACE_RGB,
				   FALSE, 8, width, height, rowstride,
				   destroy_thumb_data, NULL);
}

/**
 * poppler_page_get_thumbnail_size:
 * @page: A #PopplerPage
 * @width: return location for width
 * @height: return location for height
 *
 * Returns %TRUE if @page has a thumbnail associated with it.  It also
 * fills in @width and @height with the width and height of the
 * thumbnail.  The values of width and height are not changed if no
 * appropriate thumbnail exists.
 *
 * Return value: %TRUE, if @page has a thumbnail associated with it.
 **/
gboolean
poppler_page_get_thumbnail_size (PopplerPage *page,
				 int         *width,
				 int         *height)
{
  Object thumb;
  Dict *dict;
  gboolean retval = FALSE;

  g_return_val_if_fail (POPPLER_IS_PAGE (page), FALSE);
  g_return_val_if_fail (width != NULL, FALSE);
  g_return_val_if_fail (height != NULL, FALSE);

  page->page->getThumb (&thumb);
  if (thumb.isNull ())
    {
      thumb.free ();
      return FALSE;
    }

  dict = thumb.streamGetDict();

  /* Theoretically, this could succeed and you would still fail when
   * loading the thumb */
  if (dict->lookupInt ("Width", "W", width)  &&
      dict->lookupInt ("Height", "H", height))
    retval = TRUE;

  thumb.free ();

  return retval;
}

/**
 * poppler_page_get_text:
 * @page: a #PopplerPage
 * @rect: the rectangle including the text
 * 
 * Retrieves the contents of the specified rectangle as text 
 * 
 * Return value: a pointer to the contents of the rectangle
 *               as a string
 **/
char *
poppler_page_get_text (PopplerPage      *page,
		       PopplerRectangle *selection)
{
  TextOutputDev *text_dev;
  PDFDoc *doc;
  GooString *sel_text;
  double height, y1, y2;
  char *result;
  PDFRectangle pdf_selection;

  g_return_val_if_fail (POPPLER_IS_PAGE (page), FALSE);
  g_return_val_if_fail (selection != NULL, NULL);

  text_dev = poppler_page_get_text_output_dev (page);
  poppler_page_get_size (page, NULL, &height);

  pdf_selection.x1 = selection->x1;
  pdf_selection.y1 = height - selection->y2;
  pdf_selection.x2 = selection->x2;
  pdf_selection.y2 = height - selection->y1;
  
  sel_text = text_dev->getSelectionText (&pdf_selection);
  result = g_strdup (sel_text->getCString ());
  delete sel_text;

  return result;
}

/**
 * poppler_page_find_text:
 * @page: a #PopplerPage
 * @text: the text to search for (UTF-8 encoded)
 * 
 * A #GList of rectangles for each occurance of the text on the page.
 * The coordinates are in PDF points.
 * 
 * Return value: a #GList of PopplerRectangle, 
 **/
GList *
poppler_page_find_text (PopplerPage *page,
			const char  *text)
{
  PopplerRectangle *match;
  TextOutputDev *output_dev;
  PDFDoc *doc;
  GList *matches;
  double xMin, yMin, xMax, yMax;
  gunichar *ucs4;
  glong ucs4_len;
  double height;

  g_return_val_if_fail (POPPLER_IS_PAGE (page), FALSE);
  g_return_val_if_fail (text != NULL, FALSE);

  ucs4 = g_utf8_to_ucs4_fast (text, -1, &ucs4_len);

  output_dev = new TextOutputDev (NULL, gTrue, gFalse, gFalse);
  doc = page->document->doc;

  poppler_page_get_size (page, NULL, &height);
  page->page->display (output_dev, 72, 72, 0, gFalse,
		       gTrue, gFalse, doc->getCatalog());
  
  matches = NULL;
  xMin = 0;
  yMin = 0;

  while (output_dev->findText (ucs4, ucs4_len,
			       gFalse, gTrue, // startAtTop, stopAtBottom
			       gTrue, gFalse, // startAtLast, stopAtLast
			       gFalse, gFalse, // caseSensitive, backwards
			       &xMin, &yMin, &xMax, &yMax))
    {
      match = g_new (PopplerRectangle, 1);
      match->x1 = xMin;
      match->y1 = height - yMax;
      match->x2 = xMax;
      match->y2 = height - yMin;
      matches = g_list_prepend (matches, match);
    }

  delete output_dev;
  g_free (ucs4);

  return g_list_reverse (matches);
}

#if defined (HAVE_CAIRO)

static CairoImageOutputDev *
poppler_page_get_image_output_dev (PopplerPage *page)
{
  if (page->image_dev == NULL) {
    page->image_dev = new CairoImageOutputDev ();

    if (page->gfx)
      delete page->gfx;
    page->gfx = page->page->createGfx(page->image_dev,
				      72.0, 72.0, 0,
				      gFalse, /* useMediaBox */
				      gTrue, /* Crop */
				      -1, -1, -1, -1,
				      gFalse, /* printing */
				      page->document->doc->getCatalog (),
				      NULL, NULL, NULL, NULL);
    page->page->display(page->gfx);
  }

  return page->image_dev;
}

static GdkPixbuf *
poppler_page_image_pixbuf_create (PopplerPage *page,
				  CairoImage  *image)
{
  GdkPixbuf *pixbuf;
  cairo_surface_t *surface;

  surface = image->getImage ();
  
  pixbuf = gdk_pixbuf_new (GDK_COLORSPACE_RGB,
			   FALSE, 8,
			   cairo_image_surface_get_width (surface),
			   cairo_image_surface_get_height (surface));
  
  copy_cairo_surface_to_pixbuf (surface,
				cairo_image_surface_get_data (surface),
				pixbuf);

  return pixbuf;
}

/**
 * poppler_page_get_image_mapping:
 * @page: A #PopplerPage
 *
 * Returns a list of #PopplerImageMapping items that map from a
 * location on @page to a #GdkPixbuf.  This list must be freed
 * with poppler_page_free_image_mapping() when done.
 *
 * Return value: A #GList of #PopplerImageMapping
 **/
GList *
poppler_page_get_image_mapping (PopplerPage *page)
{
  GList *map_list = NULL;
  CairoImageOutputDev *out;
  gint i;
  
  g_return_val_if_fail (POPPLER_IS_PAGE (page), NULL);

  out = poppler_page_get_image_output_dev (page);

  for (i = 0; i < out->getNumImages (); i++) {
    PopplerImageMapping *mapping;
    CairoImage *image;

    image = out->getImage (i);

    /* Create the mapping */
    mapping = g_new (PopplerImageMapping, 1);

    image->getRect (&(mapping->area.x1), &(mapping->area.y1),
		    &(mapping->area.x2), &(mapping->area.y2));
    mapping->image = poppler_page_image_pixbuf_create (page, image);
    
    mapping->area.x1 -= page->page->getCropBox()->x1;
    mapping->area.x2 -= page->page->getCropBox()->x1;
    mapping->area.y1 -= page->page->getCropBox()->y1;
    mapping->area.y2 -= page->page->getCropBox()->y1;

    map_list = g_list_prepend (map_list, mapping);
  }

  return map_list;	
}

static void
poppler_images_mapping_free (PopplerImageMapping *mapping)
{
  g_object_unref (mapping->image);
  g_free (mapping);
}

/**
 * poppler_page_free_image_mapping:
 * @list: A list of #PopplerImageMapping<!-- -->s
 *
 * Frees a list of #PopplerImageMapping<!-- -->s allocated by
 * poppler_page_get_image_mapping().
 **/
void
poppler_page_free_image_mapping (GList *list)
{
  if (list == NULL)
    return;

  g_list_foreach (list, (GFunc) (poppler_images_mapping_free), NULL);
  g_list_free (list);
}

#else

GList *
poppler_page_get_image_mapping (PopplerPage *page)
{
  return NULL;
}

void
poppler_page_free_image_mapping (GList *list)
{
}

#endif /* HAVE_CAIRO */

/**
 * poppler_page_render_to_ps:
 * @page: a #PopplerPage
 * @ps_file: the PopplerPSFile to render to
 * 
 * Render the page on a postscript file
 * 
 **/
void
poppler_page_render_to_ps (PopplerPage   *page,
			   PopplerPSFile *ps_file)
{
  g_return_if_fail (POPPLER_IS_PAGE (page));
  g_return_if_fail (ps_file != NULL);

  if (!ps_file->out)
    ps_file->out = new PSOutputDev (ps_file->filename,
                                    ps_file->document->doc->getXRef(),
                                    ps_file->document->doc->getCatalog(),
                                    NULL,
                                    ps_file->first_page, ps_file->last_page,
                                    psModePS, (int)ps_file->paper_width,
                                    (int)ps_file->paper_height, ps_file->duplex,
                                    0, 0, 0, 0, gFalse, gFalse);


  ps_file->document->doc->displayPage (ps_file->out, page->index + 1, 72.0, 72.0,
				       0, gFalse, gTrue, gFalse);
}

static void
poppler_page_get_property (GObject *object,
			   guint prop_id,
			   GValue *value,
			   GParamSpec *pspec)
{
  PopplerPage *page = POPPLER_PAGE (object);
  GooString label;

  switch (prop_id)
    {
    case PROP_LABEL:
      page->document->doc->getCatalog ()->indexToLabel (page->index, &label);
      g_value_take_string (value, _poppler_goo_string_to_utf8(&label));
      break;
    }
}

static void
poppler_page_class_init (PopplerPageClass *klass)
{
  GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
  GParamSpec *pspec;

  gobject_class->finalize = poppler_page_finalize;
  gobject_class->get_property = poppler_page_get_property;

  pspec = g_param_spec_string ("label",
			       "Page Label",
			       "The label of the page",
			       NULL,
			       G_PARAM_READABLE);
  g_object_class_install_property (G_OBJECT_CLASS (klass),
				   PROP_LABEL,
				   pspec);
}

static void
poppler_page_init (PopplerPage *page)
{
}

/**
 * poppler_page_get_link_mapping:
 * @page: A #PopplerPage
 * 
 * Returns a list of #PopplerLinkMapping items that map from a
 * location on @page to a #PopplerAction.  This list must be freed
 * with poppler_page_free_link_mapping() when done.
 * 
 * Return value: A #GList of #PopplerLinkMapping
 **/
GList *
poppler_page_get_link_mapping (PopplerPage *page)
{
  GList *map_list = NULL;
  gint i;
  Links *links;
  Object obj;
  double width, height;
  
  g_return_val_if_fail (POPPLER_IS_PAGE (page), NULL);
  
  links = new Links (page->page->getAnnots (&obj),
		     page->document->doc->getCatalog ()->getBaseURI ());
  obj.free ();
  
  if (links == NULL)
    return NULL;
  
  poppler_page_get_size (page, &width, &height);
  
  for (i = 0; i < links->getNumLinks (); i++)
    {
      PopplerLinkMapping *mapping;
      PopplerRectangle rect;
      LinkAction *link_action;
      Link *link;
      
      link = links->getLink (i);
      link_action = link->getAction ();
      
      /* Create the mapping */
      mapping = g_new (PopplerLinkMapping, 1);
      mapping->action = _poppler_action_new (page->document, link_action, NULL);
      
      link->getRect (&rect.x1, &rect.y1, &rect.x2, &rect.y2);
      
      switch (page->page->getRotate ())
        {
        case 90:
	  mapping->area.x1 = rect.y1;
	  mapping->area.y1 = height - rect.x2;
	  mapping->area.x2 = mapping->area.x1 + (rect.y2 - rect.y1);
	  mapping->area.y2 = mapping->area.y1 + (rect.x2 - rect.x1);
	  
	  break;
	case 180:
	  mapping->area.x1 = width - rect.x2;
	  mapping->area.y1 = height - rect.y2;
	  mapping->area.x2 = mapping->area.x1 + (rect.x2 - rect.x1);
	  mapping->area.y2 = mapping->area.y1 + (rect.y2 - rect.y1);
	  
	  break;
	case 270:
	  mapping->area.x1 = width - rect.y2;
	  mapping->area.y1 = rect.x1;
	  mapping->area.x2 = mapping->area.x1 + (rect.y2 - rect.y1);
	  mapping->area.y2 = mapping->area.y1 + (rect.x2 - rect.x1);
	  
	  break;
	default:
	  mapping->area.x1 = rect.x1;
	  mapping->area.y1 = rect.y1;
	  mapping->area.x2 = rect.x2;
	  mapping->area.y2 = rect.y2;
	}
			
      mapping->area.x1 -= page->page->getCropBox()->x1;
      mapping->area.x2 -= page->page->getCropBox()->x1;
      mapping->area.y1 -= page->page->getCropBox()->y1;
      mapping->area.y2 -= page->page->getCropBox()->y1;
      
      map_list = g_list_prepend (map_list, mapping);
    }
  
  delete links;
  
  return map_list;
}

static void
poppler_mapping_free (PopplerLinkMapping *mapping)
{
  poppler_action_free (mapping->action);
  g_free (mapping);
}

/**
 * poppler_page_free_link_mapping:
 * @list: A list of #PopplerLinkMapping<!-- -->s
 * 
 * Frees a list of #PopplerLinkMapping<!-- -->s allocated by
 * poppler_page_get_link_mapping().  It also frees the #PopplerAction<!-- -->s
 * that each mapping contains, so if you want to keep them around, you need to
 * copy them with poppler_action_copy().
 **/
void
poppler_page_free_link_mapping (GList *list)
{
  if (list == NULL)
    return;

  g_list_foreach (list, (GFunc) (poppler_mapping_free), NULL);
  g_list_free (list);
}

/* PopplerRectangle type */

GType
poppler_rectangle_get_type (void)
{
  static GType our_type = 0;

  if (our_type == 0)
    our_type = g_boxed_type_register_static ("PopplerRectangle",
					     (GBoxedCopyFunc) poppler_rectangle_copy,
					     (GBoxedFreeFunc) poppler_rectangle_free);

  return our_type;
}

PopplerRectangle *
poppler_rectangle_new (void)
{
  return g_new0 (PopplerRectangle, 1);
}

PopplerRectangle *
poppler_rectangle_copy (PopplerRectangle *rectangle)
{
  PopplerRectangle *new_rectangle;

  g_return_val_if_fail (rectangle != NULL, NULL);
  
  new_rectangle = g_new0 (PopplerRectangle, 1);
  *new_rectangle = *rectangle;

  return new_rectangle;
}

void
poppler_rectangle_free (PopplerRectangle *rectangle)
{
  g_free (rectangle);
}

/* PopplerLinkMapping type */
GType
poppler_link_mapping_get_type (void)
{
  static GType our_type = 0;

  if (our_type == 0)
    our_type = g_boxed_type_register_static ("PopplerLinkMapping",
					     (GBoxedCopyFunc) poppler_link_mapping_copy,
					     (GBoxedFreeFunc) poppler_link_mapping_free);

  return our_type;
}

PopplerLinkMapping *
poppler_link_mapping_new (void)
{
  return (PopplerLinkMapping *) g_new0 (PopplerLinkMapping, 1);
}

PopplerLinkMapping *
poppler_link_mapping_copy (PopplerLinkMapping *mapping)
{
  PopplerLinkMapping *new_mapping;

  new_mapping = poppler_link_mapping_new ();
	
  *new_mapping = *mapping;
  if (new_mapping->action)
    new_mapping->action = poppler_action_copy (new_mapping->action);

  return new_mapping;
}

void
poppler_link_mapping_free (PopplerLinkMapping *mapping)
{
  if (mapping->action)
    poppler_action_free (mapping->action);

  g_free (mapping);
}

/* Poppler Image mapping type */
GType
poppler_image_mapping_get_type (void)
{
  static GType our_type = 0;

  if (our_type == 0)
    our_type = g_boxed_type_register_static ("PopplerImageMapping",
					     (GBoxedCopyFunc) poppler_image_mapping_copy,
					     (GBoxedFreeFunc) poppler_image_mapping_free);

  return our_type;
}

PopplerImageMapping *
poppler_image_mapping_new (void)
{
  return (PopplerImageMapping *) g_new0 (PopplerImageMapping, 1);
}

PopplerImageMapping *
poppler_image_mapping_copy (PopplerImageMapping *mapping)
{
  PopplerImageMapping *new_mapping;

  new_mapping = poppler_image_mapping_new ();

  *new_mapping = *mapping;
  if (new_mapping->image)
    new_mapping->image = gdk_pixbuf_copy (new_mapping->image);

  return new_mapping;
}

void
poppler_image_mapping_free (PopplerImageMapping *mapping)
{
  if (mapping->image)
    g_object_unref (mapping->image);

  g_free (mapping);
}

/* Page Transition */
GType
poppler_page_transition (void)
{
  static GType our_type = 0;
  if (our_type == 0)
    our_type = g_boxed_type_register_static("PopplerPageTransition",
					    (GBoxedCopyFunc) poppler_page_transition_copy,
					    (GBoxedFreeFunc) poppler_page_transition_free);
  return our_type;
}

PopplerPageTransition *
poppler_page_transition_new (void)
{
  return (PopplerPageTransition *) g_new0 (PopplerPageTransition, 1);
}

PopplerPageTransition *
poppler_page_transition_copy (PopplerPageTransition *transition)
{
  PopplerPageTransition *new_transition;

  new_transition = poppler_page_transition_new ();
  *new_transition = *transition;
  
  return new_transition;
}

void
poppler_page_transition_free (PopplerPageTransition *transition)
{
  g_free (transition);
}

/* Form Type */
GType
poppler_form_field_get_type (void)
{
  static GType our_type = 0;
  if (our_type == 0)
    our_type = g_boxed_type_register_static("PopplerFormField",
					    (GBoxedCopyFunc) poppler_form_field_copy,
					    (GBoxedFreeFunc) poppler_form_field_free);
  return our_type;
}

PopplerFormField*
poppler_form_field_new (void)
{
  return (PopplerFormField *) g_new0 (PopplerFormField, 1);
}

PopplerFormField*
poppler_form_field_copy (PopplerFormField *field)
{
  PopplerFormField *new_field;
  
  new_field = poppler_form_field_new ();
  *new_field = *field;

  if (field->type == POPPLER_FORM_FIELD_TEXT && field->text.content)
    new_field->text.content = g_strdup (field->text.content);
	    
  return new_field;
}

void
poppler_form_field_free (PopplerFormField *field)
{
  if (field->type == POPPLER_FORM_FIELD_TEXT)
    g_free (field->text.content);
  
  g_free (field);
}

PopplerFormField *
_form_field_new_from_widget (FormWidget *field)
{
  PopplerFormField *poppler_field;

  poppler_field = g_new0 (PopplerFormField, 1);
  
  field->getRect (&(poppler_field->area.x1), &(poppler_field->area.y1),
                  &(poppler_field->area.x2), &(poppler_field->area.y2));

  poppler_field->type = (PopplerFormFieldType)field->getType ();
  poppler_field->id = field->getID ();
  poppler_field->font_size = field->getFontSize ();
  
  switch (poppler_field->type)
    {
    case POPPLER_FORM_FIELD_TEXT:
      {
        FormWidgetText* wid = static_cast<FormWidgetText*>(field);
	GooString *tmp = wid->getContentCopy();
	
	poppler_field->text.content = (tmp) ? g_strdup (tmp->getCString ()) : NULL;
	poppler_field->text.length = (tmp) ? tmp->getLength () : 0;
	poppler_field->text.multiline = wid->isMultiline ();
	poppler_field->text.password = wid->isPassword ();
	poppler_field->text.fileselect = wid->isFileSelect ();
	poppler_field->text.do_not_spell_check = wid->noSpellCheck ();
	poppler_field->text.do_not_scroll = wid->noScroll ();
	poppler_field->text.rich_text = wid->isRichText ();
	
	if (tmp)
          delete tmp;
      }
      break;
    case POPPLER_FORM_FIELD_BUTTON:
      poppler_field->button.state = (gboolean)static_cast<FormWidgetButton*>(field)->getState ();
      break;
    case POPPLER_FORM_FIELD_CHOICE:
      {
        FormWidgetChoice* wid = static_cast<FormWidgetChoice*>(field);
	
	poppler_field->choice.combo = wid->isCombo ();
	poppler_field->choice.edit = wid->hasEdit ();
	poppler_field->choice.multi_select = wid->isMultiSelect ();
	poppler_field->choice.do_not_spell_check = wid->noSpellCheck ();
      }
      break;
    default:
      g_assert_not_reached ();
    }
  
  return poppler_field;
}

/**
 * poppler_page_get_form_fields:
 * @page: A #PopplerPage
 *
 * Returns a list of #PopplerFormField items that map from a
 * location on @page to a form field.  This list must be freed
 * with poppler_page_free_form_fields() when done.
 *
 * Return value: A #GList of #PopplerFormField
 **/
GList *
poppler_page_get_form_fields (PopplerPage *page)
{
  GList *field_list = NULL;
  FormPageWidgets *forms;
  gint i;
  
  g_return_val_if_fail (POPPLER_IS_PAGE (page), NULL);

  forms = page->page->getPageWidgets ();
  if (forms == NULL)
    return NULL;
  
  for (i = 0; i < forms->getNumWidgets (); i++) {
    PopplerFormField *poppler_field;
    FormWidget *field;
    
    field = forms->getWidget (i);
    poppler_field = _form_field_new_from_widget (field);
    field_list = g_list_prepend (field_list, poppler_field);
  }
  
  return field_list;
}

/**
 * poppler_page_free_form_fields:
 * @list: A list of #PopplerFormField<!-- -->s
 *
 * Frees a list of #PopplerFormField<!-- -->s allocated by
 * poppler_page_get_form_fields().
 **/
void
poppler_page_free_form_fields (GList *list)
{
  if (list == NULL)
    return;

  g_list_foreach (list, (GFunc) poppler_form_field_free, NULL);
  g_list_free (list);
}

void 
poppler_page_get_crop_box (PopplerPage *page, PopplerRectangle *rect)
{
  PDFRectangle* cropBox = page->page->getCropBox ();
  
  rect->x1 = cropBox->x1;
  rect->x2 = cropBox->x2;
  rect->y1 = cropBox->y1;
  rect->y2 = cropBox->y2;
}

