/*  galeon-html-thumbnailer - generate thumbnails for html files
 *
 *  Copyright (C) 2004  Tommi Komulainen
 *
 *  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.
 */

/* BUGS:
 * 
 * - If GtkMozEmbed can't read the file (doesn't exist or something) it
 *   displays an error dialog!
 *
 * - If Galeon is running we can't thumbnail remote files (presumably because
 *   profile sharing isn't supported.)  We get the dialog instead.
 *
 * - Given a non-HTML file, the generated thumbnail is noise or a partial
 *   screenshot of the desktop.  It's a user error, but we should still
 *   probably try to detect the situation...
 */

#include <gtkmozembed.h>
#include <gtk/gtkwindow.h>
#include <gtk/gtkmain.h>
#include <glib/gfileutils.h>
#include <stdlib.h>

static const double aspect_ratio = 1.3333;

static int         thumbnail_width;
static int         thumbnail_height;
static const char *thumbnail_file;

/* fake_expose_event found from gnome-control-center
 * Thanks guys, this was the missing link.
 */
static void
fake_expose_event (GtkWidget *widget, GdkPixmap *pixmap)
{
	GdkWindow      *tmp_window;
	GdkEventExpose  event;

	tmp_window = widget->window;
	widget->window = pixmap;

	event.type = GDK_EXPOSE;
	event.window = widget->window;
	event.send_event = FALSE;
	event.area = widget->allocation;
	event.region = NULL;
	event.count = 0;

	gtk_widget_send_expose (widget, (GdkEvent *) &event);

	widget->window = tmp_window;
}

static GdkPixbuf *
screenshot_from_widget (GtkWidget *widget)
{
	GdkPixmap *pixmap;
	GdkPixbuf *pixbuf;

	pixmap = gdk_pixmap_new (widget->window,
				 widget->allocation.width,
				 widget->allocation.height,
				 -1);
	fake_expose_event (widget, pixmap);

	pixbuf = gdk_pixbuf_get_from_drawable (NULL, pixmap, NULL,
					       0, 0, 0, 0,
					       widget->allocation.width,
					       widget->allocation.height);
	g_object_unref (pixmap);

	return pixbuf;
}

static gboolean
screenshot_cb (gpointer user_data)
{
	GtkWidget *widget = GTK_WIDGET (user_data);
	GdkPixbuf *pixbuf;
	GdkPixbuf *scaled;

	pixbuf = screenshot_from_widget (widget);
	scaled = gdk_pixbuf_scale_simple (pixbuf,
					  thumbnail_width,
					  thumbnail_height,
					  GDK_INTERP_HYPER);
	g_object_unref (pixbuf);

	gdk_pixbuf_save (scaled, thumbnail_file, "png", NULL, NULL);
	g_object_unref (scaled);

	gtk_main_quit ();

	return FALSE;
}

static void
net_stop_cb (GtkMozEmbed *embed)
{
	g_idle_add_full (G_PRIORITY_LOW, screenshot_cb, embed, NULL);
}

int
main (int argc, char **argv)
{
	GtkWidget  *win;
	GtkWidget  *embed;
	char       *profile_path;
        const char *outfile;
	int         size = 128;
	char        buf[7+PATH_MAX] = "file://";
	const char *infile;

	gtk_init (&argc, &argv);

	if (argc < 3)
	{
		g_printerr ("usage: galeon-html-thumbnailer <infile> <outfile> [size]\n");
		return 1;
	}

	/* GtkMozEmbed needs URLs, so if we're given a plain filename get its
	 * absolute path and make up a file URL.  URLs will fail the test below
	 * and we can use them as is.
	 */
	if (g_file_test (argv[1], G_FILE_TEST_EXISTS))
	{
		infile = realpath (argv[1], buf + 7);
	}
	else
	{

		infile = argv[1];
	}
	outfile = argv[2];

	if (argc > 3)
	{
		char *tail;
		size = strtol (argv[3], &tail, 10);
		if (tail && *tail)
		{
			g_warning ("Invalid size `%s'.  Using default.", argv[3]);
			size = 128;
		}
	}

	thumbnail_height = size;
	thumbnail_width  = (int)(size / aspect_ratio);
	thumbnail_file   = outfile;


	/* setting profile is optional, basically, but it gives us the right
	 * fonts (like it matters with thumbnails) and proxy settings
	 */
	profile_path = g_build_filename (g_get_home_dir (),
					 ".galeon", "mozilla",
					 NULL);
	gtk_moz_embed_set_profile_path (profile_path, "galeon");
	g_free (profile_path);


	win = gtk_window_new (GTK_WINDOW_TOPLEVEL);
	g_signal_connect (win, "destroy", G_CALLBACK (gtk_main_quit), 0);

	embed = gtk_moz_embed_new ();
	gtk_widget_set_app_paintable (embed, TRUE);
	gtk_widget_set_double_buffered (embed, FALSE);

	gtk_widget_set_size_request (embed, (int)(1024 / aspect_ratio), 1024);
	gtk_container_add (GTK_CONTAINER (win), embed);
	gtk_widget_show_all (win);
	gdk_window_withdraw (win->window);

	g_signal_connect (embed, "net-stop", G_CALLBACK (net_stop_cb), 0);

	gtk_moz_embed_load_url (GTK_MOZ_EMBED (embed), infile);

	gtk_main ();

	return 0;
}
