/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */

/*
 *  Copyright (C) 2004  Hidetaka Iwai
 *
 *  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.
 */

#ifdef HAVE_CONFIG_H
#include "config.h"
#endif

#include <string.h>
#include <glib/gi18n.h>

#include "kazehakase.h"
#include "kz-popup-tablist.h"
#include "kz-window.h"
#include "kz-thumbnails-view.h"
#include "egg-pixbuf-thumbnail.h"
#include "kz-bookmark.h"
#include "kz-embed.h"
#include "glib-utils.h"
#include "utils.h"
#include "kz-marshalers.h"

typedef struct _KzPopupTablistPriv KzPopupTablistPriv;
struct _KzPopupTablistPriv
{
	KzWindow  *kz;
	GtkWidget *popup_frame;
	GtkWidget *view;

	gboolean now_shown;
};

#define KZ_POPUP_TABLIST_GET_PRIVATE(object) (G_TYPE_INSTANCE_GET_PRIVATE ((object), KZ_TYPE_POPUP_TABLIST, KzPopupTablistPriv))

enum {
	PROP_0,
	PROP_KZ_WINDOW
};

enum {
	SELECTED_SIGNAL,
	LAST_SIGNAL
};

static void        dispose                (GObject *object);

static void        set_property           (GObject *object,
                                           guint prop_id,
                                           const GValue *value,
                                           GParamSpec *pspec);
static void        get_property           (GObject *object,
                                           guint prop_id,
                                           GValue *value,
                                           GParamSpec *pspec);

static void        cb_thumbnail_activate                   (KzThumbnailsView *view, 
							    KzBookmark *bookmark,
							    gint index,
							    KzPopupTablist *popup);

static gint kz_popup_tablist_signals[LAST_SIGNAL] = {0};

G_DEFINE_TYPE(KzPopupTablist, kz_popup_tablist, GTK_TYPE_WINDOW)

static void
kz_popup_tablist_class_init (KzPopupTablistClass *klass)
{
	GObjectClass *object_class;

	kz_popup_tablist_parent_class = g_type_class_peek_parent (klass);
	object_class = (GObjectClass *) klass;

	object_class->dispose      = dispose;
	object_class->set_property = set_property;
	object_class->get_property = get_property;
	
	g_object_class_install_property
		(object_class,
		 PROP_KZ_WINDOW,
		 g_param_spec_object ("kz-window",
				      _("KzWindow"),
				      _("The parent kazehakase window"),
				      KZ_TYPE_WINDOW,
				      G_PARAM_READWRITE |
				      G_PARAM_CONSTRUCT_ONLY));

	klass->selected = NULL;
	kz_popup_tablist_signals[SELECTED_SIGNAL]
		= g_signal_new ("selected",
				G_TYPE_FROM_CLASS (klass),
				G_SIGNAL_RUN_LAST | G_SIGNAL_DETAILED,
				G_STRUCT_OFFSET (KzPopupTablistClass, selected),
				NULL, NULL,
				_kz_marshal_VOID__OBJECT_INT,
				G_TYPE_NONE, 2,
				KZ_TYPE_BOOKMARK, G_TYPE_INT);


	g_type_class_add_private (klass, sizeof(KzPopupTablistPriv));
}

static void
kz_popup_tablist_init (KzPopupTablist *popup)
{
	KzPopupTablistPriv *priv = KZ_POPUP_TABLIST_GET_PRIVATE (popup);
	GtkWidget *frame;

	priv->kz           = NULL;

	frame = gtk_frame_new(NULL);
	gtk_frame_set_shadow_type(GTK_FRAME(frame), GTK_SHADOW_ETCHED_IN);
	gtk_widget_show(frame);
	priv->popup_frame = frame;
	gtk_container_add(GTK_CONTAINER(popup), frame);

	priv->view = NULL;
	priv->now_shown = FALSE;
}

static void
dispose (GObject *object)
{
	KzPopupTablist *popup = KZ_POPUP_TABLIST (object);
	KzPopupTablistPriv *priv = KZ_POPUP_TABLIST_GET_PRIVATE (popup);

	if (priv->kz)
	{
		g_object_unref(priv->kz);
		priv->kz = NULL;
	}

	if (G_OBJECT_CLASS (kz_popup_tablist_parent_class)->dispose)
		G_OBJECT_CLASS (kz_popup_tablist_parent_class)->dispose(object);
}


static void
set_property (GObject *object,
              guint prop_id,
              const GValue *value,
              GParamSpec *pspec)
{
	KzPopupTablistPriv *priv = KZ_POPUP_TABLIST_GET_PRIVATE(object);
  
	switch (prop_id)
	{
	case PROP_KZ_WINDOW:
		priv->kz = g_object_ref(g_value_get_object(value));
		break;
	default:
		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
		break;
	}
}


static void
get_property (GObject *object,
              guint prop_id,
              GValue *value,
              GParamSpec *pspec)
{
	KzPopupTablistPriv *priv = KZ_POPUP_TABLIST_GET_PRIVATE(object);

	switch (prop_id)
	{
	case PROP_KZ_WINDOW:
		g_value_set_object(value, priv->kz);
		break;
	default:
		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
		break;
	}
}


GtkWidget *
kz_popup_tablist_new (KzWindow *kz)
{
	return g_object_new (KZ_TYPE_POPUP_TABLIST, 
			     "type", GTK_WINDOW_POPUP,
			     "kz-window", kz,
			     NULL);
}

void
kz_popup_tablist_show(KzPopupTablist *popup, KzBookmark* tabs)
{
	KzPopupTablistPriv *priv = KZ_POPUP_TABLIST_GET_PRIVATE (popup);
	GtkWidget *view;
	GList *list;
	gint length, width;

	if(priv->now_shown)
		return;
	view = kz_thumbnails_view_new();

	kz_thumbnails_view_set_mode(KZ_THUMBNAILS_VIEW(view), KZ_THUMBNAILS_VIEW_PLANE);
	gtk_widget_show(view);

	if(priv->view)
	{
		gtk_container_remove(GTK_CONTAINER(priv->popup_frame),
				     priv->view);
	}
	priv->view = view;

	gtk_container_add(GTK_CONTAINER(priv->popup_frame), view);
	kz_thumbnails_view_set_folder(KZ_THUMBNAILS_VIEW(view),
				      tabs);

	g_signal_connect(view,
			 "activate",
			 G_CALLBACK(cb_thumbnail_activate),
			 popup);

	priv->now_shown = TRUE;
	gtk_window_set_position (GTK_WINDOW (popup), GTK_WIN_POS_CENTER);
	
	list = kz_bookmark_get_children(tabs);
	length = g_list_length(list);
	g_list_free(list);

	gtk_window_get_size(GTK_WINDOW(priv->kz), &width, NULL);
	width = MIN(length * (EGG_PIXBUF_THUMB_NORMAL + 4), width);
	gtk_window_set_default_size(GTK_WINDOW(popup),
				    width, -1);
	gtk_widget_show(GTK_WIDGET(popup));
}

void
kz_popup_tablist_hide(KzPopupTablist *popup)
{
	KzPopupTablistPriv *priv = KZ_POPUP_TABLIST_GET_PRIVATE (popup);
	gtk_widget_hide(GTK_WIDGET(popup));
	priv->now_shown = FALSE;
}

static void
cb_thumbnail_activate (KzThumbnailsView *view, 
		       KzBookmark *tab, 
		       gint index,
		       KzPopupTablist *popup)
{
	g_signal_emit(popup,
		      kz_popup_tablist_signals[SELECTED_SIGNAL], 0, tab, index);
}
