/*
 * Copyright (C) 2007 Carlos Garcia Campos  <carlosgc@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 <gtk/gtk.h>
#include <cairo.h>

#include "render.h"

typedef struct {
	PopplerDocument *doc;

	/* Properties */
	gint             page;
	gdouble          scale;
	gint             rotate;
	GdkRectangle     slice;
	gboolean         printing;

	GtkWidget       *swindow;
	GtkWidget       *darea;
	GtkWidget       *slice_x;
	GtkWidget       *slice_y;
	GtkWidget       *slice_w;
	GtkWidget       *slice_h;
	GtkWidget       *timer_label;

	cairo_surface_t *surface;
} PgdRenderDemo;

static void
pgd_render_free (PgdRenderDemo *demo)
{
	if (!demo)
		return;

	if (demo->doc) {
		g_object_unref (demo->doc);
		demo->doc = NULL;
	}

	if (demo->surface) {
		cairo_surface_destroy (demo->surface);
		demo->surface = NULL;
	}

	g_free (demo);
}

static gboolean
pgd_render_drawing_area_draw (GtkWidget     *area,
                              cairo_t       *cr,
                              PgdRenderDemo *demo)
{
	if (!demo->surface)
		return FALSE;

        cairo_set_source_surface (cr, demo->surface, 0, 0);
        cairo_paint (cr);

	return TRUE;
}

static void
pgd_render_start (GtkButton     *button,
		  PgdRenderDemo *demo)
{
	PopplerPage *page;
	gdouble      page_width, page_height;
	gdouble      width, height;
	gint         x, y;
	gchar       *str;
	GTimer      *timer;
        cairo_t     *cr;

	page = poppler_document_get_page (demo->doc, demo->page);
	if (!page)
		return;

	if (demo->surface)
		cairo_surface_destroy (demo->surface);
	demo->surface = NULL;

	poppler_page_get_size (page, &page_width, &page_height);

	if (demo->rotate == 0 || demo->rotate == 180) {
		width = demo->slice.width * demo->scale;
		height = demo->slice.height * demo->scale;
		x = demo->slice.x * demo->scale;
		y = demo->slice.y * demo->scale;
	} else {
		width = demo->slice.height * demo->scale;
		height = demo->slice.width * demo->scale;
		x = demo->slice.y * demo->scale;
		y = demo->slice.x * demo->scale;
	}

        timer = g_timer_new ();
        demo->surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32,
                                                    width, height);
        cr = cairo_create (demo->surface);

        cairo_save (cr);
        switch (demo->rotate) {
        case 90:
                cairo_translate (cr, x + width, -y);
                break;
        case 180:
                cairo_translate (cr, x + width, y + height);
                break;
        case 270:
                cairo_translate (cr, -x, y + height);
                break;
        default:
                cairo_translate (cr, -x, -y);
        }

        if (demo->scale != 1.0)
                cairo_scale (cr, demo->scale, demo->scale);

        if (demo->rotate != 0)
                cairo_rotate (cr, demo->rotate * G_PI / 180.0);

        if (demo->printing)
                poppler_page_render_for_printing (page, cr);
        else
                poppler_page_render (page, cr);
        cairo_restore (cr);

        cairo_set_operator (cr, CAIRO_OPERATOR_DEST_OVER);
        cairo_set_source_rgb (cr, 1., 1., 1.);
        cairo_paint (cr);

        g_timer_stop (timer);

        cairo_destroy (cr);
	g_object_unref (page);

	str = g_strdup_printf ("<i>Page rendered in %.4f seconds</i>",
			       g_timer_elapsed (timer, NULL));
	gtk_label_set_markup (GTK_LABEL (demo->timer_label), str);
	g_free (str);

	g_timer_destroy (timer);

	gtk_widget_set_size_request (demo->darea, width, height);
	gtk_widget_queue_draw (demo->darea);
}

static void
pgd_render_slice_selector_setup (PgdRenderDemo *demo)
{
	PopplerPage *page;
	gdouble      width, height;

	page = poppler_document_get_page (demo->doc, demo->page);
	if (!page)
		return;

	poppler_page_get_size (page, &width, &height);

	gtk_spin_button_set_range (GTK_SPIN_BUTTON (demo->slice_x), 0, width);
	gtk_spin_button_set_range (GTK_SPIN_BUTTON (demo->slice_y), 0, height);
	gtk_spin_button_set_range (GTK_SPIN_BUTTON (demo->slice_w), 0, width);
	gtk_spin_button_set_range (GTK_SPIN_BUTTON (demo->slice_h), 0, height);

	gtk_spin_button_set_value (GTK_SPIN_BUTTON (demo->slice_x), 0);
	gtk_spin_button_set_value (GTK_SPIN_BUTTON (demo->slice_y), 0);
	gtk_spin_button_set_value (GTK_SPIN_BUTTON (demo->slice_w), width);
	gtk_spin_button_set_value (GTK_SPIN_BUTTON (demo->slice_h), height);

	g_object_unref (page);
}

static void
pgd_render_page_selector_value_changed (GtkSpinButton *spinbutton,
					PgdRenderDemo *demo)
{
	demo->page = (gint)gtk_spin_button_get_value (spinbutton) - 1;
	pgd_render_slice_selector_setup (demo);
}

static void
pgd_render_scale_selector_value_changed (GtkSpinButton *spinbutton,
					 PgdRenderDemo *demo)
{
	demo->scale = gtk_spin_button_get_value (spinbutton);
}

static void
pgd_render_rotate_selector_changed (GtkComboBox   *combobox,
				    PgdRenderDemo *demo)
{
	demo->rotate = gtk_combo_box_get_active (combobox) * 90;
}

static void
pgd_render_printing_selector_changed (GtkToggleButton *tooglebutton,
				      PgdRenderDemo *demo)
{
	demo->printing = gtk_toggle_button_get_active (tooglebutton);
}

static void
pgd_render_slice_selector_value_changed (GtkSpinButton *spinbutton,
					 PgdRenderDemo *demo)
{
	demo->slice.x = (gint)gtk_spin_button_get_value (GTK_SPIN_BUTTON (demo->slice_x));
	demo->slice.y = (gint)gtk_spin_button_get_value (GTK_SPIN_BUTTON (demo->slice_y));
	demo->slice.width = (gint)gtk_spin_button_get_value (GTK_SPIN_BUTTON (demo->slice_w));
	demo->slice.height = (gint)gtk_spin_button_get_value (GTK_SPIN_BUTTON (demo->slice_h));
}

GtkWidget *
pgd_render_properties_selector_create (PgdRenderDemo *demo)
{
	GtkWidget *hbox, *vbox;
	GtkWidget *label;
	GtkWidget *page_hbox, *page_selector;
	GtkWidget *scale_hbox, *scale_selector;
	GtkWidget *rotate_hbox, *rotate_selector;
	GtkWidget *printing_selector;
	GtkWidget *slice_hbox;
	GtkWidget *button;
	gint       n_pages;
	gchar     *str;

	n_pages = poppler_document_get_n_pages (demo->doc);

	vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 6);

	hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 12);
	gtk_box_pack_start (GTK_BOX (vbox), hbox, TRUE, TRUE, 0);
	gtk_widget_show (hbox);

	page_hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6);

	label = gtk_label_new ("Page:");
	gtk_box_pack_start (GTK_BOX (page_hbox), label, TRUE, TRUE, 0);
	gtk_widget_show (label);

	page_selector = gtk_spin_button_new_with_range (1, n_pages, 1);
	g_signal_connect (G_OBJECT (page_selector), "value-changed",
			  G_CALLBACK (pgd_render_page_selector_value_changed),
			  (gpointer)demo);
	gtk_box_pack_start (GTK_BOX (page_hbox), page_selector, TRUE, TRUE, 0);
	gtk_widget_show (page_selector);

	str = g_strdup_printf ("of %d", n_pages);
	label = gtk_label_new (str);
	gtk_box_pack_start (GTK_BOX (page_hbox), label, TRUE, TRUE, 0);
	gtk_widget_show (label);
	g_free (str);

	gtk_box_pack_start (GTK_BOX (hbox), page_hbox, FALSE, TRUE, 0);
	gtk_widget_show (page_hbox);

	scale_hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6);

	label = gtk_label_new ("Scale:");
	gtk_box_pack_start (GTK_BOX (scale_hbox), label, TRUE, TRUE, 0);
	gtk_widget_show (label);

	scale_selector = gtk_spin_button_new_with_range (0, 10.0, 0.1);
	gtk_spin_button_set_value (GTK_SPIN_BUTTON (scale_selector), 1.0);
	g_signal_connect (G_OBJECT (scale_selector), "value-changed",
			  G_CALLBACK (pgd_render_scale_selector_value_changed),
			  (gpointer)demo);
	gtk_box_pack_start (GTK_BOX (scale_hbox), scale_selector, TRUE, TRUE, 0);
	gtk_widget_show (scale_selector);

	gtk_box_pack_start (GTK_BOX (hbox), scale_hbox, FALSE, TRUE, 0);
	gtk_widget_show (scale_hbox);

	rotate_hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6);

	label = gtk_label_new ("Rotate:");
	gtk_box_pack_start (GTK_BOX (rotate_hbox), label, TRUE, TRUE, 0);
	gtk_widget_show (label);

	rotate_selector = gtk_combo_box_text_new ();
	gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (rotate_selector), "0");
	gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (rotate_selector), "90");
	gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (rotate_selector), "180");
	gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (rotate_selector), "270");
	gtk_combo_box_set_active (GTK_COMBO_BOX (rotate_selector), 0);
	g_signal_connect (G_OBJECT (rotate_selector), "changed",
			  G_CALLBACK (pgd_render_rotate_selector_changed),
			  (gpointer)demo);
	gtk_box_pack_start (GTK_BOX (rotate_hbox), rotate_selector, TRUE, TRUE, 0);
	gtk_widget_show (rotate_selector);

	gtk_box_pack_start (GTK_BOX (hbox), rotate_hbox, FALSE, TRUE, 0);
	gtk_widget_show (rotate_hbox);

	printing_selector = gtk_check_button_new_with_label ("Printing");
	g_signal_connect (printing_selector, "toggled",
			  G_CALLBACK (pgd_render_printing_selector_changed),
			  (gpointer)demo);
	gtk_box_pack_start (GTK_BOX (hbox), printing_selector, FALSE, TRUE, 0);
	gtk_widget_show (printing_selector);

	hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 12);
	gtk_box_pack_start (GTK_BOX (vbox), hbox, TRUE, TRUE, 0);
	gtk_widget_show (hbox);

	slice_hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6);

	label = gtk_label_new ("x:");
	gtk_box_pack_start (GTK_BOX (slice_hbox), label, TRUE, TRUE, 0);
	gtk_widget_show (label);

	demo->slice_x = gtk_spin_button_new_with_range (0, 0, 1.0);
	g_signal_connect (G_OBJECT (demo->slice_x), "value-changed",
			  G_CALLBACK (pgd_render_slice_selector_value_changed),
			  (gpointer)demo);
	gtk_box_pack_start (GTK_BOX (slice_hbox), demo->slice_x, TRUE, TRUE, 0);
	gtk_widget_show (demo->slice_x);

	gtk_box_pack_start (GTK_BOX (hbox), slice_hbox, FALSE, TRUE, 0);
	gtk_widget_show (slice_hbox);

	slice_hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6);

	label = gtk_label_new ("y:");
	gtk_box_pack_start (GTK_BOX (slice_hbox), label, TRUE, TRUE, 0);
	gtk_widget_show (label);

	demo->slice_y = gtk_spin_button_new_with_range (0, 0, 1.0);
	g_signal_connect (G_OBJECT (demo->slice_y), "value-changed",
			  G_CALLBACK (pgd_render_slice_selector_value_changed),
			  (gpointer)demo);
	gtk_box_pack_start (GTK_BOX (slice_hbox), demo->slice_y, TRUE, TRUE, 0);
	gtk_widget_show (demo->slice_y);

	gtk_box_pack_start (GTK_BOX (hbox), slice_hbox, FALSE, TRUE, 0);
	gtk_widget_show (slice_hbox);

	slice_hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6);

	label = gtk_label_new ("width:");
	gtk_box_pack_start (GTK_BOX (slice_hbox), label, TRUE, TRUE, 0);
	gtk_widget_show (label);

	demo->slice_w = gtk_spin_button_new_with_range (0, 0, 1.0);
	g_signal_connect (G_OBJECT (demo->slice_w), "value-changed",
			  G_CALLBACK (pgd_render_slice_selector_value_changed),
			  (gpointer)demo);
	gtk_box_pack_start (GTK_BOX (slice_hbox), demo->slice_w, TRUE, TRUE, 0);
	gtk_widget_show (demo->slice_w);

	gtk_box_pack_start (GTK_BOX (hbox), slice_hbox, FALSE, TRUE, 0);
	gtk_widget_show (slice_hbox);

	slice_hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6);

	label = gtk_label_new ("height:");
	gtk_box_pack_start (GTK_BOX (slice_hbox), label, TRUE, TRUE, 0);
	gtk_widget_show (label);

	demo->slice_h = gtk_spin_button_new_with_range (0, 0, 1.0);
	g_signal_connect (G_OBJECT (demo->slice_h), "value-changed",
			  G_CALLBACK (pgd_render_slice_selector_value_changed),
			  (gpointer)demo);
	gtk_box_pack_start (GTK_BOX (slice_hbox), demo->slice_h, TRUE, TRUE, 0);
	gtk_widget_show (demo->slice_h);

	gtk_box_pack_start (GTK_BOX (hbox), slice_hbox, FALSE, TRUE, 0);
	gtk_widget_show (slice_hbox);

	pgd_render_slice_selector_setup (demo);

	button = gtk_button_new_with_label ("Render");
	g_signal_connect (G_OBJECT (button), "clicked",
			  G_CALLBACK (pgd_render_start),
			  (gpointer)demo);
	gtk_box_pack_end (GTK_BOX (hbox), button, FALSE, TRUE, 0);
	gtk_widget_show (button);

	demo->timer_label = gtk_label_new (NULL);
	gtk_label_set_markup (GTK_LABEL (demo->timer_label), "<i>No page rendered</i>");
	g_object_set (G_OBJECT (demo->timer_label), "xalign", 1.0, NULL);
	gtk_box_pack_end (GTK_BOX (vbox), demo->timer_label, FALSE, TRUE, 0);
	gtk_widget_show (demo->timer_label);

	return vbox;
}

GtkWidget *
pgd_render_create_widget (PopplerDocument *document)
{
	PgdRenderDemo *demo;
	GtkWidget     *vbox, *hbox;

	demo = g_new0 (PgdRenderDemo, 1);

	demo->doc = g_object_ref (document);
	demo->scale = 1.0;

	vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 6);

	hbox = pgd_render_properties_selector_create (demo);
	gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, TRUE, 6);
	gtk_widget_show (hbox);

	demo->darea = gtk_drawing_area_new ();
	g_signal_connect (G_OBJECT (demo->darea), "draw",
			  G_CALLBACK (pgd_render_drawing_area_draw),
			  (gpointer)demo);

	demo->swindow = gtk_scrolled_window_new (NULL, NULL);
	gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (demo->swindow),
					GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
#if GTK_CHECK_VERSION(3, 7, 8)
	gtk_container_add (GTK_CONTAINER (demo->swindow), demo->darea);
#else
	gtk_scrolled_window_add_with_viewport (GTK_SCROLLED_WINDOW (demo->swindow),
					       demo->darea);
#endif
	gtk_widget_show (demo->darea);

	gtk_box_pack_start (GTK_BOX (vbox), demo->swindow, TRUE, TRUE, 0);
	gtk_widget_show (demo->swindow);

	g_object_weak_ref (G_OBJECT (demo->swindow),
			   (GWeakNotify)pgd_render_free,
			   (gpointer)demo);

	return vbox;
}
