//========================================================================
//
// GDKSplashOutputDev.cc
//
// Copyright 2003 Glyph & Cog, LLC
// Copyright 2004 Red Hat, Inc. (GDK port)
//
//========================================================================

#include <config.h>

#ifdef USE_GCC_PRAGMAS
#pragma implementation
#endif

#include <math.h>
#include <gdk/gdk.h>
#include <gtk/gtk.h>
#include <poppler.h>

typedef struct
{
  GtkWidget *window;
  GtkWidget *sw;
  GtkWidget *drawing_area;
  GtkWidget *spin_button;
  PopplerPage *page;
  PopplerDocument *document;
  cairo_surface_t *surface;
  int *window_count;
} View;

static void
drawing_area_expose (GtkWidget      *drawing_area,
                     GdkEventExpose *event,
                     void           *data)
{
  View *v = (View*) data;
  GdkRectangle document;
  GdkRectangle draw;
  cairo_t *cr;

  gdk_window_clear (drawing_area->window);
  cr = gdk_cairo_create (drawing_area->window);

  cairo_set_source_surface (cr, v->surface, 0, 0);
  cairo_paint (cr);
  cairo_destroy (cr);
}

static void
view_set_page (View *v, int page)
{
  int err;
  int w, h;
  double width, height;
  cairo_t *cr;

  v->page = poppler_document_get_page (v->document, page);
  poppler_page_get_size (v->page, &width, &height);
  w = (int) ceil(width);
  h = (int) ceil(height);
  cairo_surface_destroy (v->surface);
  v->surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, w, h);
  cr = cairo_create (v->surface);
  poppler_page_render (v->page, cr);
  cairo_destroy (cr);
  gtk_widget_set_size_request (v->drawing_area, w, h);
  gtk_widget_queue_draw (v->drawing_area);
  gtk_spin_button_set_value (GTK_SPIN_BUTTON (v->spin_button), page);
}

static void
redraw_callback (void *data)
{
  View *v = (View*) data;

  gtk_widget_queue_draw (v->drawing_area);
}

static void
page_changed_callback (GtkSpinButton *button, View *v)
{
    int page;

    page = gtk_spin_button_get_value_as_int (button);
    view_set_page (v, page);
}

static void
destroy_window_callback (GtkWindow *window, View *v)
{
    if (--(*v->window_count) == 0)
	gtk_main_quit();
}

static View*
view_new (const char *filename, int *window_count)
{
  View *v;
  GtkWidget *window;
  GtkWidget *drawing_area;
  GtkWidget *sw;
  GtkWidget *vbox, *hbox;
  GtkWidget *spin_button;
  int n_pages;

  v = g_new0 (View, 1);

  v->document = poppler_document_new_from_file (filename, NULL, NULL);
  if (v->document == NULL)
      return NULL;

  window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
  vbox = gtk_vbox_new(FALSE, 5);

  gtk_container_add (GTK_CONTAINER (window), vbox);
  drawing_area = gtk_drawing_area_new ();

  sw = gtk_scrolled_window_new (NULL, NULL);

  gtk_box_pack_end (GTK_BOX (vbox), sw, TRUE, TRUE, 0);
  gtk_scrolled_window_add_with_viewport (GTK_SCROLLED_WINDOW (sw),
					 drawing_area);

  n_pages = poppler_document_get_n_pages (v->document);
  spin_button = gtk_spin_button_new_with_range  (0, n_pages - 1, 1);
  g_signal_connect (G_OBJECT (spin_button), "value-changed",
		    G_CALLBACK (page_changed_callback), v);
  hbox = gtk_hbox_new (FALSE, 5);
  gtk_box_pack_end (GTK_BOX (hbox), spin_button, FALSE, TRUE, 0);

  gtk_box_pack_end (GTK_BOX (vbox), hbox, FALSE, TRUE, 0);

  gtk_widget_show_all (window);
  gtk_widget_realize (window);

  v->window = window;
  v->drawing_area = drawing_area;
  v->sw = sw;
  v->window_count = window_count;
  v->spin_button = spin_button;

  g_signal_connect (drawing_area,
                    "expose_event",
                    G_CALLBACK (drawing_area_expose),
                    (void*) v);
  
  g_signal_connect (window,
                    "destroy",
                    G_CALLBACK (destroy_window_callback),
                    (void*) v);

  return v;
}

static int option_page = 0;
static GOptionEntry demo_options[] = {
  { "page", 0, 0, G_OPTION_ARG_INT, &option_page, "Page number", "PAGE" },
  { NULL }
};
    
int
main (int argc, char *argv [])
{
  View *v;
  int i, window_count;
  GOptionContext *ctx;

  ctx = g_option_context_new("FILENAME ...");
  g_option_context_add_main_entries(ctx, demo_options, "main");
  g_option_context_parse(ctx, &argc, &argv, NULL);
  g_option_context_free(ctx);

  gtk_init (&argc, &argv);
   
  if (argc == 1)
    {
      fprintf (stderr, "usage: %s PDF-FILES...\n", g_basename (argv[0]));
      return -1;
    }
      
  window_count = 0;
  for (i = 1; i < argc; i++) {
      v = view_new (argv[i], &window_count);
      if (v == NULL) {
	  g_printerr ("Error loading %s\n", argv[i]);
	  continue;
      }
      
      view_set_page (v, option_page);
      window_count++;
  }
  
  if (window_count > 0)
    gtk_main ();
  
  return 0;
}
