/* Module for creating a shaped window with text (for desktop icons)
 *
 * Copyright (C) 1998 the Free Software Foundation
 *
 * Author: Federico Mena <federico@nuclecu.unam.mx>
 */

#include <gnome.h>
#include <string.h>
#include "gdesktop.h"
#include "gcache.h"
#include <gdk/gdkx.h>

/* The spacing between the cute little icon and the text */
#define SPACING 2

int want_transparent_icons = 1;
int want_transparent_text = 0;


static void
set_window_text (GtkWidget *window, GdkImlibImage *im, char *text)
{
	GdkPixmap *pixmap;
	GdkPixmap *im_pixmap;
	GdkBitmap *mask;
	GdkBitmap *im_mask;
	GnomeIconTextInfo *ti;
	GdkColor color;
	GdkGC *p_gc, *m_gc;
	int width, height;

	ti = gnome_icon_layout_text (window->style->font, text, " /.-_", SNAP_X, FALSE);

	width = MAX (ti->width, im->rgb_width);
	height = im->rgb_height + SPACING + ti->height;

	/* Create pixmap, mask, and gc's */

	pixmap = gdk_pixmap_new (window->window, width, height, gdk_imlib_get_visual ()->depth);
	mask = gdk_pixmap_new (window->window, width, height, 1);

	p_gc = gdk_gc_new (pixmap);
	m_gc = gdk_gc_new (mask);

	/* Fill mask with transparent */

	color.pixel = 0;
	gdk_gc_set_foreground (m_gc, &color);
	gdk_draw_rectangle (mask,
			    m_gc,
			    TRUE,
			    0, 0,
			    width, height);

	/* Icon */

	im_pixmap = gdk_imlib_move_image (im);
	im_mask = gdk_imlib_move_mask (im);

	if (!want_transparent_icons || im_mask == NULL) {
		/* black background */

		gdk_color_black (gdk_imlib_get_colormap (), &color);
		gdk_gc_set_foreground (p_gc, &color);
		gdk_draw_rectangle (pixmap,
				    p_gc,
				    TRUE,
				    (width - im->rgb_width) / 2,
				    0,
				    im->rgb_width,
				    im->rgb_height);

		/* opaque mask */

		color.pixel = 1;
		gdk_gc_set_foreground (m_gc, &color);
		gdk_draw_rectangle (mask,
				    m_gc,
				    TRUE,
				    (width - im->rgb_width) / 2,
				    0,
				    im->rgb_width,
				    im->rgb_height);
	} else if (im_mask)
		gdk_draw_pixmap (mask,
				 m_gc,
				 im_mask,
				 0, 0,
				 (width - im->rgb_width) / 2,
				 0,
				 im->rgb_width,
				 im->rgb_height);

	if (im_mask) {
		gdk_gc_set_clip_mask (p_gc, im_mask);
		gdk_gc_set_clip_origin (p_gc, (width - im->rgb_width) / 2, 0);
	}

	gdk_draw_pixmap (pixmap,
			 p_gc,
			 im_pixmap,
			 0, 0,
			 (width - im->rgb_width) / 2,
			 0,
			 im->rgb_width,
			 im->rgb_height);

	if (im_mask) {
		gdk_gc_set_clip_mask (p_gc, NULL);
		gdk_imlib_free_bitmap (im_mask);
	}

	gdk_imlib_free_pixmap (im_pixmap);
	
	/* Text */

	if (!want_transparent_text) {
		/* black background */

		gdk_color_black (gdk_imlib_get_colormap (), &color);
		gdk_gc_set_foreground (p_gc, &color);
		gdk_draw_rectangle (pixmap,
				    p_gc,
				    TRUE,
				    (width - ti->width) / 2,
				    im->rgb_height + SPACING,
				    ti->width,
				    ti->height);

		/* opaque mask */

		color.pixel = 1;
		gdk_gc_set_foreground (m_gc, &color);
		gdk_draw_rectangle (mask,
				    m_gc,
				    TRUE,
				    (width - ti->width) / 2,
				    im->rgb_height + SPACING,
				    ti->width,
				    ti->height);
	} else {
		color.pixel = 1;
		gdk_gc_set_foreground (m_gc, &color);
		gnome_icon_paint_text (ti, mask, m_gc,
				       (width - ti->width) / 2,
				       im->rgb_height + SPACING,
				       GTK_JUSTIFY_CENTER);
	}
	
	gdk_color_white (gdk_imlib_get_colormap (), &color);
	gdk_gc_set_foreground (p_gc, &color);
	gnome_icon_paint_text (ti, pixmap, p_gc,
			       (width - ti->width) / 2,
			       im->rgb_height + SPACING,
			       GTK_JUSTIFY_CENTER);

	/* Set contents of window */

	gtk_widget_set_usize (window, width, height);
	gdk_window_set_back_pixmap (window->window, pixmap, FALSE);
	gdk_window_shape_combine_mask (window->window, mask, 0, 0);

	gdk_gc_destroy (p_gc);
	gdk_gc_destroy (m_gc);

	gdk_pixmap_unref (pixmap);
	gdk_pixmap_unref (mask);

	gnome_icon_text_info_free (ti);
}

static void
lower_icon_window(GtkWidget *widget, GdkEventExpose *event)
{
	gdk_window_lower(widget->window);
}

GtkWidget *
create_transparent_text_window (char *file, char *text, int extra_events)
{
	GtkWidget *window;
	GdkImlibImage *im;
	GdkCursor *cursor;

	if (!g_file_exists (file))
		return NULL;

	im = image_cache_load_image (file);
	if (!im)
		return NULL;

	gtk_widget_push_visual (gdk_imlib_get_visual ());
	gtk_widget_push_colormap (gdk_imlib_get_colormap ());
	
	window = gtk_window_new (GTK_WINDOW_POPUP);
	gtk_widget_set_events (window, gtk_widget_get_events (window) | extra_events);

	gtk_widget_pop_colormap ();
	gtk_widget_pop_visual ();

	gtk_widget_realize (window);
	
	gdk_imlib_render (im, im->rgb_width, im->rgb_height);

	set_window_text (window, im, text);

	cursor = gdk_cursor_new (GDK_TOP_LEFT_ARROW);
	gdk_window_set_cursor (window->window, cursor);
	gdk_cursor_destroy (cursor);

#if 0
	/* Do not enable this code */
	/* We do this so the desktop icons appear to really be part of the
	   desktop */

        /* This is wrong.  If you have two icons, one on top of the other,
	 * guess what is the result.
	 */
	gtk_signal_connect(window, "expose_event", GTK_SIGNAL_FUNC(lower_icon_window), NULL);
#endif
	return window;
}

GtkWidget *
make_transparent_window (char *file)
{
	GdkImlibImage *im;
	GtkWidget *window;
	XSetWindowAttributes xwa;
	
	if (!g_file_exists (file))
		return NULL;

	im = image_cache_load_image (file);
	if (!im)
		return NULL;
	
	gtk_widget_push_visual (gdk_imlib_get_visual ());
	gtk_widget_push_colormap (gdk_imlib_get_colormap ());

	window = gtk_window_new (GTK_WINDOW_POPUP);
	gtk_widget_pop_colormap ();
	gtk_widget_pop_visual ();

	gtk_widget_realize (window);

	xwa.save_under = True;
	XChangeWindowAttributes (GDK_WINDOW_XDISPLAY (window->window),
				 GDK_WINDOW_XWINDOW (window->window),
				 CWSaveUnder, &xwa);

	gtk_widget_set_usize (window, im->rgb_width, im->rgb_height);

	
	/* All of the following 3 lines should not be required, only
	 * gdk_imlib_apply_image, but is is buggy.
	 */
	gdk_imlib_render (im, im->rgb_width, im->rgb_height);
	gdk_window_set_back_pixmap (window->window, gdk_imlib_move_image (im), FALSE);
	gdk_window_shape_combine_mask (window->window, gdk_imlib_move_mask (im), 0, 0);
	
	return window;
}

