/*
 * Copyright (c) 2004 Jean-Yves Lefort
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. Neither the name of Jean-Yves Lefort nor the names of its contributors
 *    may be used to endorse or promote products derived from this software
 *    without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
 * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
 * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 */

#include "config.h"
#include <glib/gi18n.h>
#include <gtk/gtk.h>
#include "sgtk-blinking-image.h"
#include "sgtk-hig.h"
#include "sgtk-util.h"
#include "st-browser-tab-label.h"
#include "st-stock.h"

/*** cpp *********************************************************************/

#define BOX_SPACING			(SGTK_HIG_UNIT / 2)

/*** type definitions ********************************************************/

enum {
  PROP_0,
  PROP_TAB
};

struct _STBrowserTabLabelPrivate
{
  GtkWidget	*image;
  GtkWidget	*menu;
  GtkWidget	*stop_item;
};

/*** variable declarations ***************************************************/

static GObjectClass *parent_class = NULL;

/*** function declarations ***************************************************/

static void st_browser_tab_label_class_init (STBrowserTabLabelClass *class);
static void st_browser_tab_label_init (STBrowserTabLabel *tab_label);
static void st_browser_tab_label_finalize (GObject *object);

static GObject *st_browser_tab_label_constructor (GType type,
						  unsigned int n_construct_properties,
						  GObjectConstructParam *construct_params);
static void st_browser_tab_label_set_property (GObject *object,
					       unsigned int prop_id,
					       const GValue *value,
					       GParamSpec *pspec);

static void st_browser_tab_label_notify_running_h (GObject *object,
						   GParamSpec *pspec,
						   gpointer user_data);
static void st_browser_tab_label_update_sensitivity (STBrowserTabLabel *tab_label);

/*** implementation **********************************************************/

GType
st_browser_tab_label_get_type (void)
{
  static GType browser_tab_label_type = 0;
  
  if (! browser_tab_label_type)
    {
      static const GTypeInfo browser_tab_label_info = {
	sizeof(STBrowserTabLabelClass),
	NULL,
	NULL,
	(GClassInitFunc) st_browser_tab_label_class_init,
	NULL,
	NULL,
	sizeof(STBrowserTabLabel),
	0,
	(GInstanceInitFunc) st_browser_tab_label_init,
      };
      
      browser_tab_label_type = g_type_register_static(GTK_TYPE_HBOX,
						      "STBrowserTabLabel",
						      &browser_tab_label_info,
						      0);
    }

  return browser_tab_label_type;
}

static void
st_browser_tab_label_class_init (STBrowserTabLabelClass *class)
{
  GObjectClass *object_class = G_OBJECT_CLASS(class);

  parent_class = g_type_class_peek_parent(class);

  g_type_class_add_private(class, sizeof(STBrowserTabLabelPrivate));

  object_class->finalize = st_browser_tab_label_finalize;
  object_class->constructor = st_browser_tab_label_constructor;
  object_class->set_property = st_browser_tab_label_set_property;

  g_object_class_install_property(object_class,
				  PROP_TAB,
				  g_param_spec_object("tab",
						      NULL,
						      NULL,
						      ST_TYPE_BROWSER_TAB,
						      G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY));
}

static void
st_browser_tab_label_init (STBrowserTabLabel *tab_label)
{
  tab_label->priv = G_TYPE_INSTANCE_GET_PRIVATE(tab_label, ST_TYPE_BROWSER_TAB_LABEL, STBrowserTabLabelPrivate);
}

static void
st_browser_tab_label_finalize (GObject *object)
{
  STBrowserTabLabel *tab_label = ST_BROWSER_TAB_LABEL(object);

  gtk_widget_destroy(tab_label->priv->menu);
  
  parent_class->finalize(object);
}

static GObject *
st_browser_tab_label_constructor (GType type,
				  unsigned int n_construct_properties,
				  GObjectConstructParam *construct_params)
{
  GObject *object;
  STBrowserTabLabel *tab_label;
  GtkWidget *label;
  GtkWidget *event_box;
  GtkWidget *hbox;
  GdkPixbuf *pixbuf;
  GtkWidget *reload_item;
  GtkWidget *present_directory_preferences_item;
  GtkWidget *visit_directory_homepage_item;
  GtkWidget *separator_item;

  object = parent_class->constructor(type, n_construct_properties, construct_params);
  tab_label = ST_BROWSER_TAB_LABEL(object);

  /* event box */

  event_box = gtk_event_box_new();
  gtk_event_box_set_visible_window(GTK_EVENT_BOX(event_box), FALSE);
  hbox = gtk_hbox_new(FALSE, BOX_SPACING);

  gtk_container_add(GTK_CONTAINER(tab_label), event_box);
  gtk_container_add(GTK_CONTAINER(event_box), hbox);

  gtk_widget_show(event_box);
  gtk_widget_show(hbox);

  /* image */

  pixbuf = st_handler_get_pixbuf(tab_label->tab->handler);
  if (pixbuf)
    {
      GdkPixbuf *scaled;

      tab_label->priv->image = sgtk_blinking_image_new();

      scaled = sgtk_pixbuf_scale(pixbuf, GTK_ICON_SIZE_MENU);
      sgtk_blinking_image_set_from_pixbuf(SGTK_BLINKING_IMAGE(tab_label->priv->image), scaled);
      g_object_unref(scaled);

      gtk_box_pack_start(GTK_BOX(hbox), tab_label->priv->image, FALSE, FALSE, 0);
      gtk_widget_show(tab_label->priv->image);
    }

  /* label */

  label = gtk_label_new(st_handler_get_label(tab_label->tab->handler));

  gtk_box_pack_start(GTK_BOX(hbox), label, TRUE, TRUE, 0);
  gtk_widget_show(label);

  /* popup menu */

  tab_label->priv->menu = gtk_menu_new();

  tab_label->priv->stop_item = gtk_image_menu_item_new_from_stock(GTK_STOCK_STOP, NULL);
  reload_item = gtk_image_menu_item_new_from_stock(ST_STOCK_RELOAD, NULL);
  present_directory_preferences_item = gtk_image_menu_item_new_from_stock(ST_STOCK_DIRECTORY_PREFERENCES, NULL);
  visit_directory_homepage_item = gtk_image_menu_item_new_from_stock(ST_STOCK_VISIT_DIRECTORY_HOMEPAGE, NULL);

  g_signal_connect_swapped(tab_label->priv->stop_item, "activate", G_CALLBACK(st_browser_tab_stop), tab_label->tab);
  g_signal_connect_swapped(reload_item, "activate", G_CALLBACK(st_browser_tab_reload), tab_label->tab);
  g_signal_connect_swapped(present_directory_preferences_item, "activate", G_CALLBACK(st_browser_tab_present_preferences), tab_label->tab);
  g_signal_connect_swapped(visit_directory_homepage_item, "activate", G_CALLBACK(st_browser_tab_visit_homepage), tab_label->tab);

  gtk_widget_show(tab_label->priv->stop_item);
  gtk_widget_show(reload_item);
  gtk_widget_show(present_directory_preferences_item);
  gtk_widget_show(visit_directory_homepage_item);

  /* misc */

  gtk_widget_set_sensitive(reload_item, st_browser_tab_can_reload(tab_label->tab));
  gtk_widget_set_sensitive(present_directory_preferences_item, st_browser_tab_can_present_preferences(tab_label->tab));
  gtk_widget_set_sensitive(visit_directory_homepage_item, st_browser_tab_can_visit_homepage(tab_label->tab));

  gtk_menu_shell_append(GTK_MENU_SHELL(tab_label->priv->menu), tab_label->priv->stop_item);
  gtk_menu_shell_append(GTK_MENU_SHELL(tab_label->priv->menu), reload_item);

  separator_item = gtk_separator_menu_item_new();
  gtk_widget_show(separator_item);
  gtk_menu_shell_append(GTK_MENU_SHELL(tab_label->priv->menu), separator_item);

  gtk_menu_shell_append(GTK_MENU_SHELL(tab_label->priv->menu), present_directory_preferences_item);
  gtk_menu_shell_append(GTK_MENU_SHELL(tab_label->priv->menu), visit_directory_homepage_item);

  sgtk_widget_set_popup_menu(event_box, GTK_MENU(tab_label->priv->menu));

  st_browser_tab_label_update_sensitivity(tab_label);

  g_object_connect(tab_label->tab,
		   "signal::notify::running", st_browser_tab_label_notify_running_h, tab_label,
		   "swapped-signal::stream-task-added", st_browser_tab_label_update_sensitivity, tab_label,
		   "swapped-signal::stream-task-removed", st_browser_tab_label_update_sensitivity, tab_label,
		   NULL);

  return object;
}

static void
st_browser_tab_label_set_property (GObject *object,
				   unsigned int prop_id,
				   const GValue *value,
				   GParamSpec *pspec)
{
  STBrowserTabLabel *tab_label = ST_BROWSER_TAB_LABEL(object);

  switch (prop_id)
    {
    case PROP_TAB:
      tab_label->tab = g_value_get_object(value);
      break;

    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
      break;
    }
}

static void
st_browser_tab_label_notify_running_h (GObject *object,
				       GParamSpec *pspec,
				       gpointer user_data)
{
  STBrowserTab *tab = ST_BROWSER_TAB(object);
  STBrowserTabLabel *tab_label = user_data;

  if (tab_label->priv->image)
    sgtk_blinking_image_set_blinking(SGTK_BLINKING_IMAGE(tab_label->priv->image), tab->running);

  st_browser_tab_label_update_sensitivity(tab_label);
}

static void
st_browser_tab_label_update_sensitivity (STBrowserTabLabel *tab_label)
{
  g_return_if_fail(ST_IS_BROWSER_TAB_LABEL(tab_label));

  gtk_widget_set_sensitive(tab_label->priv->stop_item, st_browser_tab_can_stop(tab_label->tab));
}

GtkWidget *
st_browser_tab_label_new (STBrowserTab *tab)
{
  return g_object_new(ST_TYPE_BROWSER_TAB_LABEL,
		      "spacing", BOX_SPACING,
		      "tab", tab,
		      NULL);
}

void
st_browser_tab_label_set_icon_visible (STBrowserTabLabel *tab_label,
				       gboolean visible)
{
  g_return_if_fail(ST_IS_BROWSER_TAB_LABEL(tab_label));

  if (tab_label->priv->image)
    g_object_set(tab_label->priv->image,
		 "visible", visible,
		 NULL);
}
