/*
 *  Copyright (C) 2004 Mathias Andre <mathias@openbrookes.org>
 *
 *  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 of the License, 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.
 *
 */

#include <glib.h>
#include <gtk/gtk.h>
#include <glade/glade.h>
#include <libgnomeui/libgnomeui.h>

#include "../nb_global.h"
#include "../nb_attachment.h"
#include "../nb_attachment_list.h"
#include "nb_ui_interface.h"
#include "nb_ui_interface_callbacks.h"
#include "nb_ui_attachment_view.h"

#define _(text) gettext(text)

void
nb_ui_attachment_view_create (void)
{
	extern GladeXML * xml;
	GtkWidget * iconlist = glade_xml_get_widget (xml, "iconlist");

	AttachmentDrag * drag = g_malloc (sizeof (AttachmentDrag));
	drag->pressed_button = -1;

	g_object_set_data ( G_OBJECT (iconlist), "drag", drag);

	g_signal_connect ( G_OBJECT (iconlist), "button-press-event", G_CALLBACK (nb_ui_attachment_view_cb_button_pressed), iconlist);
	g_signal_connect ( G_OBJECT (iconlist), "button-release-event", G_CALLBACK (nb_ui_attachment_view_cb_button_released), iconlist);
	g_signal_connect ( G_OBJECT (iconlist), "motion-notify-event", G_CALLBACK (nb_ui_attachment_view_cb_motion), iconlist);
	g_signal_connect ( G_OBJECT (iconlist), "drag-data-get", G_CALLBACK (nb_ui_attachment_view_cb_drag_data_get), iconlist);
}

void	
nb_ui_attachment_view_show (void)
{
	extern GladeXML * xml;
	extern Global * g;
	GtkWidget * scrolled_window_attach = glade_xml_get_widget (xml, "scrolled_window_attach");
	GtkWidget * button_show_attach = glade_xml_get_widget (xml, "button_show_attach");

	if ( g->show_icon_list )
		gtk_widget_show (scrolled_window_attach);
	gtk_widget_show (button_show_attach);
}

void
nb_ui_attachment_view_hide (void)
{
	extern GladeXML * xml;
	GtkWidget * scrolled_window_attach = glade_xml_get_widget (xml, "scrolled_window_attach");
	GtkWidget * button_show_attach = glade_xml_get_widget (xml, "button_show_attach");

	gtk_widget_hide (scrolled_window_attach);
	gtk_widget_hide (button_show_attach);
}

void
nb_ui_attachment_view_icon_list_show_hide (void)
{
	extern GladeXML * xml;
	extern Global * g;
	GtkWidget * scrolled_window_attach = glade_xml_get_widget (xml, "scrolled_window_attach");

	if ( g->show_icon_list )
		g->show_icon_list = FALSE;
	else
		g->show_icon_list = TRUE;

	if ( GTK_WIDGET_VISIBLE (scrolled_window_attach) )
		gtk_widget_hide (scrolled_window_attach);
	else
		gtk_widget_show (scrolled_window_attach);
}

void
nb_ui_attachment_view_select_files (void)
{
	extern Global * g;
	extern GladeXML * xml;
	GtkWidget * dialog, * mainwindow;

	mainwindow = glade_xml_get_widget (xml, "mainwindow");

	dialog = gtk_file_chooser_dialog_new ((gchar *) _("Select files to attach."), GTK_WINDOW (mainwindow),
					      GTK_FILE_CHOOSER_ACTION_OPEN,
					      GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
					      GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT,
					      NULL);

	gtk_file_chooser_set_select_multiple ( GTK_FILE_CHOOSER (dialog), TRUE);

	if ( gtk_dialog_run ( GTK_DIALOG (dialog)) == GTK_RESPONSE_ACCEPT )
	{
		GSList * selection;

		selection = gtk_file_chooser_get_uris (GTK_FILE_CHOOSER (dialog));
		if ( selection->data != NULL)
			nb_global_add_attachments (g, selection);

		g_slist_free (selection);
	}

	gtk_widget_destroy (dialog);

}

void
nb_ui_attachment_view_update (AttachmentList * attachments)
{
	extern GladeXML * xml;
	GtkWidget * iconlist;
	GtkIconTheme * theme;
	GtkIconInfo * icon_info;
	Attachment * a;
	gchar * icon_filename;
	gint i, idx, nb_attach = nb_attachment_list_get_nb (attachments);

	if ( nb_attach < 1 )
	{
		nb_ui_attachment_view_hide ();
		return ;
	}

	iconlist = glade_xml_get_widget (xml, "iconlist");

	gnome_icon_list_clear ( GNOME_ICON_LIST (iconlist));

	nb_ui_attachment_view_show ();

	theme = gtk_icon_theme_get_default ();

	for ( i = 0 ; i < nb_attach ; i++ )
	{
		a = g_ptr_array_index (attachments, i);

		/* add the attachment to the iconview */
		icon_filename = gnome_icon_lookup ( theme,
				NULL, a->uri,
				NULL, NULL,
				a->mime_type, GNOME_ICON_LOOKUP_FLAGS_SHOW_SMALL_IMAGES_AS_THEMSELVES, NULL);

		icon_info = gtk_icon_theme_lookup_icon (theme, icon_filename, 48, 0);

		if ( icon_info )
		{
			idx = gnome_icon_list_append (GNOME_ICON_LIST (iconlist), 
						      gtk_icon_info_get_filename (icon_info), 
						      g_path_get_basename (a->uri));


			gnome_icon_list_set_icon_data (GNOME_ICON_LIST (iconlist), idx, a);

			gtk_icon_info_free (icon_info);
		}
	}
}

void
nb_ui_attachment_view_context_menu (GtkWidget * widget, GdkEventButton * event)
{
	extern GladeXML * xml;
	GtkWidget * menu, * menuitem;
	int icon;
	GtkWidget * iconlist = glade_xml_get_widget (xml, "iconlist");
	GList * selection;

	menu = gtk_menu_new ();

	menuitem = gtk_menu_item_new_with_label ((gchar *) _("Attach a file..."));
	g_signal_connect ( G_OBJECT (menuitem), "activate", G_CALLBACK (nb_ui_cb_on_attach_clicked), NULL);
	gtk_widget_show (menuitem);
	gtk_menu_shell_append ( GTK_MENU_SHELL (menu), menuitem);

	icon = gnome_icon_list_get_icon_at ( GNOME_ICON_LIST (iconlist), event->x, event->y);

	/* if the signal was emited over an icon allow the user to delete the selected attachments */
	if ( icon != -1 ) 
	{
		gnome_icon_list_select_icon ( GNOME_ICON_LIST (iconlist), icon);
		selection = gnome_icon_list_get_selection ( GNOME_ICON_LIST (iconlist));

		menuitem = gtk_image_menu_item_new_from_stock (GTK_STOCK_REMOVE, NULL);

		g_signal_connect (menuitem, "activate", G_CALLBACK (nb_ui_attachment_view_remove_attachments), selection);
		gtk_widget_show (menuitem);
		gtk_menu_shell_append ( GTK_MENU_SHELL (menu), menuitem);
	}

	gtk_menu_popup (GTK_MENU (menu), NULL, NULL, NULL, NULL, event->button, event->time);
}

/* callbacks */
void
nb_ui_attachment_view_remove_attachments (GtkMenuItem * menuitem, gpointer user_data)
{
	extern GladeXML * xml;
	extern Global * g;
	GtkWidget * iconlist = glade_xml_get_widget (xml, "iconlist");
	GList * selection = (GList *) user_data;
	GList * l = selection;

	do
	{
		nb_note_remove_attachment (g->current_note,
					  gnome_icon_list_get_icon_data ( GNOME_ICON_LIST (iconlist), (gint) l->data));

		l = g_list_next (l);
	}
	while ( l != NULL );

	nb_ui_attachment_view_update (g->current_note->attachments);

	 g->modified_note = EDITED;
}

gboolean
nb_ui_attachment_view_cb_button_pressed (GtkWidget * widget, GdkEventButton * event, gpointer user_data)
{
	GtkWidget * iconlist = (GtkWidget *) user_data;
	AttachmentDrag * drag = g_object_get_data ( G_OBJECT (iconlist), "drag");

	g_return_val_if_fail (event != NULL, FALSE);

	drag->pressed_button = event->button;
	drag->start_x = event->x;
	drag->start_y = event->y;

	return FALSE;
}

gboolean
nb_ui_attachment_view_cb_button_released (GtkWidget * widget, GdkEventButton * event, gpointer user_data)
{
	GtkWidget * iconlist = (GtkWidget *) user_data;
	AttachmentDrag * drag = g_object_get_data ( G_OBJECT (iconlist), "drag");

	drag->pressed_button = -1;

	return FALSE;
}

gboolean
nb_ui_attachment_view_cb_motion (GtkWidget * widget, GdkEventButton * event, gpointer user_data)
{
	GtkWidget * iconlist = (GtkWidget *) user_data;
	AttachmentDrag * drag = g_object_get_data ( G_OBJECT (iconlist), "drag");
	gint button, icon_index;

	if  ( drag->pressed_button == -1 ) 
		return FALSE;

	if ( !gtk_drag_check_threshold (iconlist, drag->start_x, drag->start_y, event->x, event->y) )
		return FALSE;

	icon_index = gnome_icon_list_get_icon_at ( GNOME_ICON_LIST (iconlist), drag->start_x, drag->start_y);

	if ( icon_index == -1 )
		return FALSE;

	button = drag->pressed_button;
	drag->pressed_button = -1;

	gtk_drag_begin (iconlist, gtk_target_list_new (drag_drop_target, 2), GDK_ACTION_COPY, button, (GdkEvent *) event);

	return TRUE;
}

void
nb_ui_attachment_view_cb_drag_data_get (GtkWidget * widget, GdkDragContext * drag_context, GtkSelectionData * data, guint info, guint time, gpointer user_data)
{
	GList * selection, * s;
	GtkWidget * iconlist = (GtkWidget *) user_data;
	AttachmentDrag * drag = g_object_get_data ( G_OBJECT (iconlist), "drag");
	Attachment * a;
	gint i;
	
	selection = gnome_icon_list_get_selection ( GNOME_ICON_LIST (iconlist));

	/* TODO: handle multiple files selection */
	for ( s = selection ; s != NULL ; s = s->next )
	{
		a = (Attachment *) gnome_icon_list_get_icon_data ( GNOME_ICON_LIST (iconlist), (gint) s->data);
		gtk_selection_data_set (data, data->target, 8, a->uri, strlen (a->uri));
	}
}

/* context menu callbacks */
gboolean
nb_ui_attachment_view_button_press (GtkWidget * widget, GdkEventButton * event)
{
	/* Ignore double-clicks and triple-clicks */
	if ( (event->button == 3) && (event->type == GDK_BUTTON_PRESS) )
	{
		nb_ui_attachment_view_context_menu (widget, event);
		return TRUE;
	}

	return FALSE;
}
