//========================================================================
//
// 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 <goo/gmem.h>
#include <splash/SplashTypes.h>
#include <splash/SplashBitmap.h>
#include "Object.h"
#include "GfxState.h"

#include <gdk/gdk.h>
#include <gdk/gdkx.h>
#include "CairoOutputDev.h"
#include <cairo-xlib.h>
#include <X11/Xutil.h>

#include "PDFDoc.h"
#include "GlobalParams.h"
#include "ErrorCodes.h"
#include <gtk/gtk.h>

class GDKCairoOutputDev: public CairoOutputDev {
public:

  GDKCairoOutputDev(GdkDrawable *drawable,
		    void (*redrawCbkA)(void *data),
		    void *redrawCbkDataA);
  
  virtual ~GDKCairoOutputDev();

  // Start a page.
  virtual void startPage(int pageNum, GfxState *state);

  //----- special access

  // Clear out the document (used when displaying an empty window).
  void clear();

  // Copy the rectangle (srcX, srcY, width, height) to (destX, destY)
  // in destDC.
  void redraw(int srcX, int srcY,
              GdkDrawable *drawable,
	      int destX, int destY,
	      int width, int height);

  int getPixmapWidth (void) { return pixmapWidth; }
  int getPixmapHeight (void) { return pixmapHeight; }

private:

  int incrementalUpdate;
  void (*redrawCbk)(void *data);
  void *redrawCbkData;
  int pixmapWidth, pixmapHeight;
  GdkPixmap *pixmap, *drawable;
};

GDKCairoOutputDev::GDKCairoOutputDev(GdkDrawable *drawableA,
				     void (*redrawCbkA)(void *data),
				     void *redrawCbkDataA):
  CairoOutputDev()
{
  drawable = drawableA;
  redrawCbk = redrawCbkA;
  redrawCbkData = redrawCbkDataA;
  pixmap = NULL;
}

GDKCairoOutputDev::~GDKCairoOutputDev() {
}

void
GDKCairoOutputDev::startPage(int pageNum, GfxState *state) {
  Display *display;
  Drawable xid;
  GdkGC *gc;
  GdkColor white;
  cairo_surface_t *surface;
  int w, h;

  w = state ? (int)(state->getPageWidth() + 0.5) : 1;
  h = state ? (int)(state->getPageHeight() + 0.5) : 1;

  if (!pixmap || pixmapWidth != w || h != pixmapHeight != h) {
    if (pixmap)
      g_object_unref (G_OBJECT (pixmap));

    pixmap = gdk_pixmap_new (drawable, w, h, -1);
    pixmapWidth = w;
    pixmapHeight = h;

    gc = gdk_gc_new (pixmap);
    white.red = 0xffff;
    white.green = 0xffff;
    white.blue = 0xffff;
    gdk_gc_set_rgb_fg_color (gc, &white);
    gdk_draw_rectangle (pixmap, gc, TRUE, 0, 0, w, h);
    g_object_unref (G_OBJECT (gc));
  }

  if (pixmap) {
    display = gdk_x11_drawable_get_xdisplay (pixmap);
    xid = gdk_x11_drawable_get_xid (pixmap);

    surface = cairo_xlib_surface_create(display, xid,
					DefaultVisual(display, DefaultScreen(display)),
					w, h);
    setSurface(surface);
    cairo_surface_destroy (surface);
  }

  CairoOutputDev::startPage(pageNum, state);
}

void GDKCairoOutputDev::redraw(int srcX, int srcY,
			       GdkDrawable *drawable,
			       int destX, int destY,
			       int width, int height) {
  GdkGC *gc;

  gc = gdk_gc_new (drawable);
  gdk_draw_drawable (drawable, gc,
		     pixmap, srcX, srcY,
		     destX, destY, width, height);
  g_object_unref (gc);
}

typedef struct
{
  GtkWidget *window;
  GtkWidget *sw;
  GtkWidget *drawing_area;
  GDKCairoOutputDev *out;
  PDFDoc *doc;
} View;

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

  gdk_window_clear (drawing_area->window);
  
  document.x = 0;
  document.y = 0;
  document.width = v->out->getPixmapWidth();
  document.height = v->out->getPixmapHeight();

  if (gdk_rectangle_intersect (&document, &event->area, &draw))
    {
      v->out->redraw (draw.x, draw.y,
                      drawing_area->window,
                      draw.x, draw.y,
                      draw.width, draw.height);
    }
}

static int
view_load (View       *v,
           const char *filename)
{
  PDFDoc *newDoc;
  int err;
  GooString *filename_g;
  int w, h;

  filename_g = new GooString (filename);

  // open the PDF file
  newDoc = new PDFDoc(filename_g, 0, 0);

  delete filename_g;
  
  if (!newDoc->isOk())
    {
      err = newDoc->getErrorCode();
      delete newDoc;
      return err;
    }

  if (v->doc)
    delete v->doc;
  v->doc = newDoc;
  
  v->out->startDoc(v->doc->getXRef());

  v->doc->displayPage (v->out, 1, 72, 72, 0, gTrue, gTrue);
  
  w = v->out->getPixmapWidth();
  h = v->out->getPixmapHeight();
  
  gtk_widget_set_size_request (v->drawing_area, w, h);

  return errNone;
}

static void
view_show (View *v)
{
  gtk_widget_show (v->window);
}

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

  gtk_widget_queue_draw (v->drawing_area);
}

static View*
view_new (void)
{
  View *v;
  GtkWidget *window;
  GtkWidget *drawing_area;
  GtkWidget *sw;

  window = gtk_window_new (GTK_WINDOW_TOPLEVEL);

  drawing_area = gtk_drawing_area_new ();

  sw = gtk_scrolled_window_new (NULL, NULL);

  gtk_container_add (GTK_CONTAINER (window), sw);
  gtk_scrolled_window_add_with_viewport (GTK_SCROLLED_WINDOW (sw), drawing_area);

  gtk_widget_show_all (sw);
  gtk_widget_realize (window);

  v = g_new0 (View, 1);

  v->window = window;
  v->drawing_area = drawing_area;
  v->sw = sw;
  v->out = new GDKCairoOutputDev (window->window, redraw_callback, (void*) v);
  v->doc = 0;

  g_signal_connect (drawing_area,
                    "expose_event",
                    G_CALLBACK (drawing_area_expose),
                    (void*) v);
  
  return v;
}

int
main (int argc, char *argv [])
{
  View *v;
  int i;
  
  gtk_init (&argc, &argv);
  
  globalParams = new GlobalParams("/etc/xpdfrc");
  
  if (argc == 1)
    {
      fprintf (stderr, "usage: %s PDF-FILES...\n", argv[0]);
      return -1;
    }
      

  i = 1;
  while (i < argc)
    {
      int err;
      
      v = view_new ();

      err = view_load (v, argv[i]);

      if (err != errNone)
        g_printerr ("Error loading document!\n");
      
      view_show (v);

      ++i;
    }
  
  gtk_main ();
  
  delete globalParams;
  
  return 0;
}
