/*
 *  Copyright (C) 2000 Marco Pesenti Gritti
 *
 *  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.
 */

/* Galeon includes */
#include "galeon.h"
#include "misc.h"
#include "file-operations.h"
#include "glade.h"

#include <gtk/gtkprogressbar.h>

/* GNOME includes */
#include <libgnomevfs/gnome-vfs.h>
#include <libgnomevfs/gnome-vfs-mime.h>

typedef struct
{
	GtkWidget *dialog;
	GtkWidget *progress;
	GtkWidget *label;
	char **messages;
	void (*callback) (gpointer data);
	gboolean cancelled;
	gpointer data;
} OperationInfo;

static void file_operations_create_dialog (OperationInfo *op_info);
static void file_operations_set_status (GtkWidget *status, char *message);
static void file_operations_set_progress (GtkWidget *progress, float perc);
static int file_operations_handle_ok (GnomeVFSXferProgressInfo *progress_info,
				      OperationInfo *info);
void xfer_cancel_clicked_cb (GtkButton *button, OperationInfo *info);

static int
file_operations_handle_ok (GnomeVFSXferProgressInfo *progress_info,
			   OperationInfo *info)
{
	char **messages = info->messages;
	float perc;

	switch (progress_info->phase) {
		
	case GNOME_VFS_XFER_PHASE_INITIAL:
		file_operations_create_dialog (info);
		file_operations_set_status (info->label, 
					    messages [FILE_OPERATION_MOVING]);
		break;
	case GNOME_VFS_XFER_PHASE_COPYING:
		perc = (float)progress_info->bytes_copied / 
			(float)progress_info->bytes_total;
		file_operations_set_progress (info->progress, perc);
		break;
	case GNOME_VFS_XFER_PHASE_COMPLETED:
		info->callback (info->data);
		gtk_widget_destroy (info->dialog);
		g_free (info);
		break;
	default:
		break;
	}
	
	return 1;
}

static int
update_transfer_cb (GnomeVFSAsyncHandle *handle,
		    GnomeVFSXferProgressInfo *progress_info,
		    gpointer data)
{
	OperationInfo *info = (OperationInfo*)data;

	switch (progress_info->status) {
	case GNOME_VFS_XFER_PROGRESS_STATUS_OK:
		if (info->cancelled) return 0;
		return file_operations_handle_ok (progress_info, info);
	case GNOME_VFS_XFER_PROGRESS_STATUS_VFSERROR:
		/* FIXME show a failure dialog if the message is not NULL */
		return 0;
	case GNOME_VFS_XFER_PROGRESS_STATUS_OVERWRITE:
		/* FIXME show an overwrite choice dialog if the message is not NULL */
		return 1;
	default:
		return 0;
	}
}

static int
sync_transfer_cb (GnomeVFSXferProgressInfo *progress_info, gpointer data)
{
	return 1;
}


void
file_operations_copy_move (const GList *source_uris,
			   const GList *target_uris,
			   gboolean move,
			   char **messages,
			   void (*completed_cb) (gpointer data),
			   gpointer data)
{
	GList *p = (GList *)source_uris;
	GList *t = (GList *)target_uris;
	GList *target_uri_list = NULL, *source_uri_list = NULL;
	GnomeVFSURI *source_uri = NULL, *target_uri = NULL;
	GnomeVFSAsyncHandle *handle;
	OperationInfo *op_info;

	op_info = g_new0 (OperationInfo, 1);

	op_info->messages = messages;
	op_info->callback = completed_cb;
	op_info->cancelled = FALSE;
	op_info->data = data;

	for (; p != NULL; p = p->next, t = t->next) {
		source_uri = gnome_vfs_uri_new ((const char *) p->data);
		target_uri = gnome_vfs_uri_new ((const char *) t->data);
		
		target_uri_list = g_list_prepend (target_uri_list, target_uri);
		source_uri_list = g_list_prepend (source_uri_list, source_uri);
	}
	
	gnome_vfs_async_xfer (&handle, source_uri_list, target_uri_list,
			      GNOME_VFS_XFER_DEFAULT, GNOME_VFS_XFER_ERROR_MODE_QUERY, 
			      GNOME_VFS_XFER_OVERWRITE_MODE_QUERY,
			      update_transfer_cb, op_info,
			      sync_transfer_cb, op_info);

       	gnome_vfs_uri_unref (source_uri);
	gnome_vfs_uri_unref (target_uri);
}

static void
file_operations_create_dialog (OperationInfo *op_info)
{
	GladeXML *gxml;

	gxml = glade_widget_new ("galeon.glade", "transfer_dialog", 
				 &(op_info->dialog), op_info);
	op_info->label = glade_xml_get_widget (gxml, "xfer_label");
	op_info->progress = glade_xml_get_widget (gxml, "xfer_progress");
	gtk_object_unref (GTK_OBJECT(gxml));

	gtk_widget_show (op_info->dialog);
}

static void
file_operations_set_status (GtkWidget *status, char *message)
{  
	gtk_label_set_text (GTK_LABEL(status), message);
}

static void
file_operations_set_progress (GtkWidget *progress, float perc)
{
	 gtk_progress_bar_update (GTK_PROGRESS_BAR(progress), perc);
}

void
xfer_cancel_clicked_cb (GtkButton *button, OperationInfo *info)
{
	info->cancelled = TRUE;
}
