/* $Id$
 *
 * Copyright 2002-2004 Jasper Huijsmans (jasper@xfce.org)
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library 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
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public
 * License along with this library; if not, write to the
 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 * Boston, MA 02111-1307, USA.
 */

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

#include <math.h>

#include <gdk/gdk.h>
#include <gtk/gtkbutton.h>
#include <gtk/gtkhbox.h>
#include <gtk/gtklabel.h>

#include "xfce_scaled_image.h"
#include "xfce_menubutton.h"

#define DEBUGGING 0

/* XXX: this is used by gtkbutton. hope they won't change it soon ... */
#define CHILD_SPACING 1

/* Forward declarations */

static void xfce_menubutton_class_init (XfceMenubuttonClass * class);
static void xfce_menubutton_init (XfceMenubutton * menubutton);
static void xfce_menubutton_finalize (GObject * object);

static void xfce_menubutton_size_allocate (GtkWidget * widget,
					   GtkAllocation * allocation);

static void hbox_style_set (GtkWidget * widget, GtkStyle * old);

/* Local data */

static GtkWidgetClass *parent_class = NULL;

GtkType
xfce_menubutton_get_type (void)
{
    static GtkType menubutton_type = 0;

    if (!menubutton_type)
    {
	static const GTypeInfo menubutton_info = {
	    sizeof (XfceMenubuttonClass),
	    NULL,		/* base_init */
	    NULL,		/* base_finalize */
	    (GClassInitFunc) xfce_menubutton_class_init,
	    NULL,		/* class_finalize */
	    NULL,		/* class_data */
	    sizeof (XfceMenubutton),
	    0,			/* n_preallocs */
	    (GInstanceInitFunc) xfce_menubutton_init,
	    NULL		/* value_table */
	};

	menubutton_type =
	    g_type_register_static (GTK_TYPE_BUTTON, "XfceMenubutton",
				    &menubutton_info, 0);
    }

    return menubutton_type;
}

static void
xfce_menubutton_class_init (XfceMenubuttonClass * class)
{
    GObjectClass *gobject_class = G_OBJECT_CLASS (class);
    GtkObjectClass *object_class;
    GtkWidgetClass *widget_class;

    object_class = (GtkObjectClass *) class;
    widget_class = (GtkWidgetClass *) class;
    gobject_class = G_OBJECT_CLASS (class);

    parent_class = gtk_type_class (gtk_button_get_type ());

    widget_class->size_allocate = xfce_menubutton_size_allocate;

    gobject_class->finalize = xfce_menubutton_finalize;
}

static void
xfce_menubutton_init (XfceMenubutton * menubutton)
{
    menubutton->hbox = gtk_hbox_new (FALSE, 10);
    gtk_widget_show (menubutton->hbox);
    gtk_container_add (GTK_CONTAINER (menubutton), menubutton->hbox);

    menubutton->image = xfce_scaled_image_new ();
    gtk_widget_show (menubutton->image);
    gtk_box_pack_start (GTK_BOX (menubutton->hbox), menubutton->image, FALSE,
			TRUE, 0);

    menubutton->pb = NULL;
    menubutton->icon_size = -1;

    menubutton->label = gtk_label_new (NULL);
    gtk_misc_set_alignment (GTK_MISC (menubutton->label), 0, 0.5);
    gtk_widget_show (menubutton->label);
    gtk_box_pack_start (GTK_BOX (menubutton->hbox), menubutton->label, TRUE,
			TRUE, 0);

    g_signal_connect (menubutton->hbox, "style-set",
		      G_CALLBACK (hbox_style_set), NULL);
}

GtkWidget *
xfce_menubutton_new (const char *text)
{
    GtkWidget *button;

    button = GTK_WIDGET (g_object_new (xfce_menubutton_get_type (), NULL));

    xfce_menubutton_set_text (XFCE_MENUBUTTON (button), text);

    return button;
}

GtkWidget *
xfce_menubutton_new_with_pixbuf (const char *text, GdkPixbuf * pixbuf)
{
    GtkWidget *button;

    button = xfce_menubutton_new (text);
    xfce_menubutton_set_pixbuf (XFCE_MENUBUTTON (button), pixbuf);

    return button;
}

GtkWidget *
xfce_menubutton_new_with_stock_icon (const char *text, const char *stock)
{
    GtkWidget *button;

    button = xfce_menubutton_new (text);
    xfce_menubutton_set_stock_icon (XFCE_MENUBUTTON (button), stock);

    return button;
}

void
xfce_menubutton_set_text (XfceMenubutton * menubutton, const char *text)
{
    g_return_if_fail (menubutton != NULL);
    g_return_if_fail (XFCE_IS_MENUBUTTON (menubutton));

    gtk_label_set_text (GTK_LABEL (menubutton->label), text);
}

void
xfce_menubutton_set_pixbuf (XfceMenubutton * menubutton, GdkPixbuf * pixbuf)
{
    g_return_if_fail (menubutton != NULL);
    g_return_if_fail (XFCE_IS_MENUBUTTON (menubutton));

    xfce_scaled_image_set_from_pixbuf (XFCE_SCALED_IMAGE (menubutton->image),
	    			       pixbuf);
}

void
xfce_menubutton_set_stock_icon (XfceMenubutton * menubutton,
				const char *stock)
{
    GdkPixbuf *pb;
    
    g_return_if_fail (menubutton != NULL);
    g_return_if_fail (XFCE_IS_MENUBUTTON (menubutton));

    pb = gtk_widget_render_icon (GTK_WIDGET (menubutton), stock,
	    			 GTK_ICON_SIZE_MENU, "xfce_menubutton");

    xfce_scaled_image_set_from_pixbuf (XFCE_SCALED_IMAGE (menubutton->image), 
	    			       pb);
    g_object_unref (pb);
}

static void
xfce_menubutton_finalize (GObject * object)
{
    G_OBJECT_CLASS (parent_class)->finalize (object);
}

static void
xfce_menubutton_size_allocate (GtkWidget * widget, GtkAllocation * allocation)
{
    XfceMenubutton *menubutton;
    gint ythick, borderwidth;
    GtkBorder *tmp_border = NULL;

    g_return_if_fail (widget != NULL);
    g_return_if_fail (XFCE_IS_MENUBUTTON (widget));
    g_return_if_fail (allocation != NULL);

    menubutton = XFCE_MENUBUTTON (widget);

    borderwidth = gtk_container_get_border_width (GTK_CONTAINER (widget));

    ythick = 2 * (CHILD_SPACING + borderwidth + widget->style->ythickness +
		  menubutton->hbox->style->ythickness +
		  menubutton->image->style->ythickness);

    gtk_widget_style_get (widget, "default_border", &tmp_border, NULL);

    if (tmp_border)
    {
	if (GTK_WIDGET_CAN_DEFAULT (widget))
	    ythick += tmp_border->top + tmp_border->bottom;

	g_free (tmp_border);
    }

    if (menubutton->icon_size != allocation->height - ythick)
    {
	menubutton->icon_size = allocation->height - ythick;

	widget->allocation = *allocation;

	gtk_widget_set_size_request (menubutton->image, menubutton->icon_size,
				     menubutton->icon_size);
    }

    parent_class->size_allocate (widget, allocation);

#if DEBUGGING
    g_print (" ** xfce_menubutton.c: requested size: %d\n",
	     menubutton->icon_size);
    
    g_print (" ** xfce_menubutton.c: allocated size: %d x %d\n",
	     menubutton->image->allocation.width,
	     menubutton->image->allocation.height);
#endif
}

static void
real_style_set (GtkWidget * widget, GtkStyle * old)
{
    GtkRcStyle *style;

    style = gtk_widget_get_modifier_style (widget);
    style->xthickness = style->ythickness = 0;
    gtk_widget_modify_style (widget, style);
}

static void
hbox_style_set (GtkWidget * widget, GtkStyle * old)
{
    static int recursive = 0;

    if (recursive > 0)
	return;

    recursive++;
    real_style_set (widget, old);
    recursive--;
}
