/*
 *  Copyright (C) 2000 Marco Pesenti Gritti
 *
 *  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.
 */

/*

  - Panel applet TODOs:
M   - bookmarks resync
    - dont quit on exit
    - restarting properly
    - tidy up compositing
M   - enable DnD
    - shift click
    - pasting
    - shift pasting

*/

#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#ifdef ENABLE_APPLET

/* Galeon includes */
#include "galeon.h"
#include "embed.h"
#include "misc.h"

/* GNOME includes */
#include <applet-widget.h>
#include <gdk-pixbuf/gdk-pixbuf.h>

/* local function prototypes */
static GtkWidget *panel_applet_make_controls (AppletWidget *applet);
static void panel_applet_do_draw_cb (AppletWidget *applet);
static void panel_applet_change_pixel_size_cb (AppletWidget *applet, int size);
static gint panel_applet_button_press_cb (GtkWidget *button, 
					  GdkEventButton *event,
					  gpointer data);
static void panel_applet_bookmark_activate_cb (AppletWidget *applet, 
					       BookmarkItem *bi);
static void panel_applet_build_bookmarks_menu (AppletWidget *applet, 
					       BookmarkItem *bi, 
					       const gchar *path);

/* module local variables */
static GdkPixbuf *logo_pixbuf = NULL;
static GdkPixbuf *scaled_pixbuf = NULL;
static GtkWidget *pixmap_widget = NULL;

/**
 * panel_main: build the panel applet and run it
 */
void
panel_main (void)
{
	GtkWidget *controls;
	GtkWidget *applet;
	GList *l;
	
	/* make a new applet */
	applet = applet_widget_new (PACKAGE);

	/* make the controls */
	controls = panel_applet_make_controls (APPLET_WIDGET (applet));

	/* add bookmarks to the panel applet context menu */
	for (l = bookmarks_root->list; l != NULL; l = g_list_next (l))
	{
		BookmarkItem *bi = (BookmarkItem *)(l->data);
		panel_applet_build_bookmarks_menu 
			(APPLET_WIDGET (applet), bi, "");
	}

	/* put the controls into the applet */
	applet_widget_add (APPLET_WIDGET (applet), GTK_WIDGET (controls));

	/* show everything */
	gtk_widget_show_all (GTK_WIDGET (applet));

	/* run the applet main loop */
	applet_widget_gtk_main ();
}

/**
 * panel_applet_make_controls: make the applet controls
 */
static GtkWidget *
panel_applet_make_controls (AppletWidget *applet)
{
	GtkWidget *event_box;
	GdkPixmap *pixmap;
	GdkBitmap *mask;
	gint size;

	/* load the unscaled logo */
	logo_pixbuf = gdk_pixbuf_new_from_file (SHARE_DIR "/galeon.png");
	g_assert (logo_pixbuf != NULL);

	/* get the target size */
	size = applet_widget_get_panel_pixel_size (APPLET_WIDGET (applet));

	/* scale to this size */
	scaled_pixbuf = gdk_pixbuf_scale_simple (logo_pixbuf, size, size,
						 GDK_INTERP_HYPER);

	/* render into a pixmap */
	gdk_pixbuf_render_pixmap_and_mask (scaled_pixbuf, &pixmap, &mask, 100);

	/* make a widget out of this */
	pixmap_widget = gtk_pixmap_new (pixmap, mask);
	
	/* make an eventbox and put the widget inside it */
	event_box = gtk_event_box_new ();
	gtk_container_add (GTK_CONTAINER (event_box), 
			   GTK_WIDGET (pixmap_widget));

	/* capture button press events */
	gtk_signal_connect (GTK_OBJECT (event_box), "button_press_event",
			    (GtkSignalFunc)panel_applet_button_press_cb, NULL);

	/* capture draw signals */
	applet_widget_send_draw (APPLET_WIDGET (applet), TRUE);
	gtk_signal_connect (GTK_OBJECT (applet), "do_draw", 
			    panel_applet_do_draw_cb, NULL);

	/* capture resize signal */
	gtk_signal_connect (GTK_OBJECT (applet), "change_pixel_size",
			    panel_applet_change_pixel_size_cb, NULL);

	/* return completed controls */
	return (GTK_WIDGET (event_box));
}

/**
 * panel_applet_do_draw_cb: called when the background changes and therefore
 * the applet needs to be redrawn.
 */
static void
panel_applet_do_draw_cb (AppletWidget *applet)
{
	gint width, height, rowstride;
	GdkPixbuf *background_pixbuf;
	guchar *src, *dst;
	GdkPixmap *pixmap;
	GdkBitmap *mask;
	guchar *rgb;
	gint x, y;

	/* get the background image */
	applet_widget_get_rgb_bg (APPLET_WIDGET (applet), &rgb,
				  &width, &height, &rowstride);

	/* composite the logo with the pixbuf */
	src = gdk_pixbuf_get_pixels (scaled_pixbuf);
	dst = rgb;
	for (y = 0; y < height; y++)
	{
		for (x = 0; x < width; x++)
		{
			gint a, b;

			a = src[3];
			b = 256 - a;

			dst[0] = ((a * src[0]) + (b * dst[0])) >> 8;
			dst[1] = ((a * src[1]) + (b * dst[1])) >> 8;
			dst[2] = ((a * src[2]) + (b * dst[2])) >> 8;
			
			src += 4;
			dst += 3;
		}
		dst += rowstride - (width * 3);
	}

	/* make a pixbuf from it */
	background_pixbuf = gdk_pixbuf_new_from_data (rgb, GDK_COLORSPACE_RGB, 
						      FALSE, 8, width, height, 
						      rowstride, NULL, NULL);

	/* render into a pixmap */
	gdk_pixbuf_render_pixmap_and_mask (background_pixbuf, &pixmap, 
					   &mask, 100);

	/* set as the pixmap */
	gtk_pixmap_set (GTK_PIXMAP (pixmap_widget), pixmap, mask);
	
	/* lose the background pixbuf */
	gdk_pixbuf_unref (background_pixbuf);
}

/**
 * panel_applet_change_pixel_size_cb: called when the panel size changes
 */
static void
panel_applet_change_pixel_size_cb (AppletWidget *applet, int size)
{
	/* get rid of old scaled pixbuf */
	gdk_pixbuf_unref (scaled_pixbuf);

	/* now rescale to this size */
	scaled_pixbuf = gdk_pixbuf_scale_simple (logo_pixbuf, size, size,
						 GDK_INTERP_HYPER);

	/* force the widget to this size */
	gtk_widget_set_usize (GTK_WIDGET (applet), size, size);
}

/**
 * panel_applet_button_press_cb: called when the applet is clicked with
 * the left button. For now, just create a new browser window.
 */
static gint
panel_applet_button_press_cb (GtkWidget *button, GdkEventButton *event,
			      gpointer data)
{
	if (event->button == 1)
	{
		embed_create_default (NULL, TRUE);
		return TRUE;
	}

	return FALSE;
}

/**
 * panel_applet_bookmark_activate_cb: called when the user selects a bookmark
 * from the applet menu.
 */
static void
panel_applet_bookmark_activate_cb (AppletWidget *applet, BookmarkItem *bi)
{
	embed_create_from_url (NULL, bi->url, TRUE, TRUE);
}

/**
 * panel_applet_build_bookmarks_menu: recursively add bookmarks to the
 * panel applet menu.
 */
static void
panel_applet_build_bookmarks_menu (AppletWidget *applet, BookmarkItem *bi,
				   const gchar *path)
{
	gchar *name;
	GList *l;
	gchar *loc_str;

	/* build the menu path name */
	name = g_strdup_printf ("%s/%ld", path, bi->id);

	/* get the bookmark type */
	switch (bi->type)
	{
	case BM_SITE:
		/* a site is an entry with a callback */
		loc_str = mozilla_utf8_to_locale (bi->name);
		applet_widget_register_callback	
			(applet, name, loc_str, (AppletCallbackFunc)
			 panel_applet_bookmark_activate_cb, bi);
		g_free (loc_str);
		break;

	case BM_FOLDER:
	case BM_AUTOBOOKMARKS:
		/* check if this is an alias (FIXME: a better way?) */
		if (bi->alias_of != NULL)
		{
			return;
		}
		/* a folder builds recursively */
		loc_str = mozilla_utf8_to_locale (bi->name);
		applet_widget_register_callback_dir (applet, name, loc_str);
		for (l = bi->list; l != NULL; l = g_list_next (l))
		{
			BookmarkItem *bi = (BookmarkItem *)(l->data);
			panel_applet_build_bookmarks_menu (applet, bi, name);
		}
		g_free (loc_str);
		break;

	case BM_SEPARATOR:
		/* hmmm */
		break;		
	}

	/* done */
	g_free (name);
}

#endif /* ENABLE_APPLET */
