/*
 *  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.
 */
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif

/* Galeon includes */
#include "eel-gconf-extensions.h"
#include "gul-download.h"
#include "gul-string.h"
#include "prefs-strings.h"
#include "Gtm.h"

#include <string.h>

/* GNOME includes */
#include <glib.h>
#include <glib/gi18n.h>
#include <libgnome/gnome-exec.h>
#include <libgnomevfs/gnome-vfs-utils.h>
#include <bonobo-activation/bonobo-activation-activate.h>
#include <gtk/gtkfilesel.h>

static gboolean gul_download_gtm_add_url (const gchar *url, gchar *dir, 
					gboolean disable_proxy,
					gboolean disable_auto_dl);
static void gul_download_save_url_with_dir (const gchar *url, 
					    const gchar *directory);
static void gul_download_save_url_without_dir (const gchar *url);
static void gul_download_save_url_with_command_line (const gchar *url, 
						     const gchar *command,
						     const gchar *directory);
static void gul_download_save_url_with_gtm (const gchar *url, 
					  const gchar *directory);

/**
 * save_url
 */
void
gul_download_external_save_url (const gchar *url)
{
	gchar *command;

	command = eel_gconf_get_string (CONF_DOWNLOADING_EXTERNAL_COMMAND);
	
	if (eel_gconf_get_boolean (CONF_DOWNLOADING_ASK_DIR) &&
	    command && (!strcmp(command, "GTM through CORBA") ||
	    		strstr (command,"%f")))
	{
		gchar *dirName, *utf8DirName, *prefDir = NULL;
		gsize bytesRead, bytesWritten;
		gint retVal;
		GtkWidget *fileSel = gtk_file_selection_new(_("Choose destination folder"));

		/* Dirname must end in a '/' for the file selection to treat
		 * it as a directory. When we have a UI to set the value, we
		 * will ensure this at the time the pref is stored.
		 */
		prefDir = eel_gconf_get_string(CONF_DOWNLOADING_DIR);
		if (!prefDir)
		{
			prefDir = g_strdup (g_get_home_dir());
		}
		utf8DirName = g_strconcat(prefDir, "/", NULL);
		g_free(prefDir);

		/* On-disk filenames are locale encoded so we must convert
		 * from utf8 to ensure the the correct name is passed.
		 * If the conversion fails, we're in trouble, so we'll abort
		 * to avoid messing with the filesystem.
		 */
		dirName = g_filename_from_utf8(utf8DirName, -1,
					       &bytesRead, &bytesWritten, NULL);
		g_free(utf8DirName);
		if(!dirName)
		{
			g_warning("Save-to dirname failed to convert from "
				  "UTF8 to Locale. Save aborted.");
			gtk_widget_hide(fileSel);
			gtk_widget_destroy(fileSel);
			return;
		}

		gtk_file_selection_set_filename(GTK_FILE_SELECTION(fileSel),
						dirName);
		gtk_widget_set_sensitive(GTK_FILE_SELECTION(fileSel)
					 ->file_list, FALSE);

		retVal = gtk_dialog_run(GTK_DIALOG(fileSel));

		if(retVal == GTK_RESPONSE_OK)
		{
			/* File selection returns a locale filename
			 * which is what we need.
			 */
			gul_download_save_url_with_dir(url,
				gtk_file_selection_get_filename(GTK_FILE_SELECTION(fileSel)));
		}
		gtk_widget_hide(fileSel);
		gtk_widget_destroy(fileSel);
		g_free(dirName);
	}
	else
	{
		gul_download_save_url_without_dir (url);
	}
	g_free (command);
}

static void
gul_download_save_url_with_dir (const gchar *url, const char *directory)
{
	Downloader downloader;
	gchar *command;

	/* which downloader? */
	downloader = eel_gconf_get_boolean (CONF_DOWNLOADING_EXTERNAL_DOWNLOADER);
	if (downloader == DOWNLOADER_EXTERNAL)
	{
		/* get command */
		command = eel_gconf_get_string 
			(CONF_DOWNLOADING_EXTERNAL_COMMAND);

		/* check available */
		if (strcmp(command, "GTM through CORBA") == 0)
		{
			gul_download_save_url_with_gtm (url, directory);
		}
		else if (command != NULL)
		{
			/* check valid */
			if (strlen (command) > 0)
			{
				gul_download_save_url_with_command_line 
					(url, command, directory);
				return;
			}

			/* free allocated string */
			g_free (command);
		}
	}
}

static void
gul_download_save_url_without_dir (const gchar *url)
{
	Downloader downloader;
	gchar *command, *utf8Dir, *utf8ExpDir, *exp_dir;
	gsize bytesRead, bytesWritten;

	/* get directory to save to */
	utf8Dir = eel_gconf_get_string (CONF_DOWNLOADING_DIR);

	if (utf8Dir && strcmp(utf8Dir,"") == 0)
	{
		utf8ExpDir = g_strdup(utf8Dir);
		g_free(utf8Dir);
	}
	else if (utf8Dir)
	{
		utf8ExpDir = gnome_vfs_expand_initial_tilde(utf8Dir);
		g_free(utf8Dir);
	}
	else
	{
		utf8ExpDir = g_strdup(g_get_home_dir());
	}

	/* Dirname must be locale encoded as explained above */
	exp_dir = g_filename_from_utf8(utf8ExpDir, -1,
				       &bytesRead, &bytesWritten,
				       NULL);
	g_free(utf8ExpDir);
	if(!exp_dir)
	{
		g_warning("Save-to dirname failed to convert from "
			  "UTF8 to Locale. Save aborted.");
		return;
	}

	/* which downloader? */
	downloader = eel_gconf_get_boolean (CONF_DOWNLOADING_EXTERNAL_DOWNLOADER);
	if (downloader == DOWNLOADER_EXTERNAL)
	{
		/* get command */
		command = eel_gconf_get_string 
		  (CONF_DOWNLOADING_EXTERNAL_COMMAND);

		/* check available */
		if (strcmp(command, "GTM through CORBA") == 0)
		{
			gul_download_save_url_with_gtm (url, exp_dir);
		}
		else if (command != NULL)
		{
			/* check valid */
			if (strlen (command) > 0)
			{
				gul_download_save_url_with_command_line 
					(url, command, exp_dir);
				g_free (command);
				g_free (exp_dir);
				return;
			}

			/* free allocated string */
			g_free (command);
		}
	}

	g_free (exp_dir);
}

static void 
gul_download_save_url_with_command_line (const gchar *url, const gchar *command,
			       					 const gchar *directory)
{
	gint pid;

	int i;
	gchar **argv, *temp;

	if (eel_gconf_get_boolean(CONF_DOWNLOADING_EXTERNAL_TERMINAL))
	{
		temp = g_strconcat("gnome-terminal -t %t -e ",
				   command, NULL);
		command = temp;
	}

	/* expand %s and %f (must be done after splitting the
	 * command to accommodate spaces in urls and directory
	 * names) */
	argv = g_strsplit (command, " ", 100);
	for (i = 0; argv[i] != NULL; i++)
	{
		if (strstr (argv[i], "%s"))
		{
			temp = gul_string_strdup_replace (argv[i],
							  "%s", url);
			g_free (argv[i]);
			argv[i] = temp;
		}
		if (strstr (argv[i], "%f"))
		{
			temp = gul_string_strdup_replace (argv[i],
							  "%f",
							  directory);
			g_free (argv[i]);
			argv[i] = temp;
		}
		if (strstr(argv[i], "%t"))
		{
			temp = gul_string_strdup_replace(argv[i],
							 "%t",
							 _("Galeon Downloader"));
			g_free(argv[i]);
			argv[i] = temp;
		}
	}

	pid = gnome_execute_async (directory, i, argv);
	g_strfreev (argv);

	if (pid == -1)
	{
		gchar *text;	

		text = g_strdup_printf (_("Failed to execute download "
					  "command."));
		g_warning (text);
		g_free (text);
	}
}

/**
 * save_url_with_gtm
 */
static void
gul_download_save_url_with_gtm (const gchar *url, const gchar *directory)
{  
	gul_download_gtm_add_url (g_strdup(url), (char *)directory,
				  FALSE, FALSE);
}

/*
 * Calls the gtm CORBA interface function gtm_add_url() to place the
 * download in queue
 */
static gboolean 
gul_download_gtm_add_url (const gchar *url, gchar *dir, gboolean disable_proxy,
			gboolean disable_auto_dl)
{
	CORBA_Environment ev;
	extern CORBA_Environment corba_env;
	GTM_Download gtm_download_client;
	gboolean result;

	/* exception catching environment */
	CORBA_exception_init (&ev);

	result = FALSE;

	ev = corba_env;
	gtm_download_client =   
		bonobo_activation_activate_from_id ("OAFIID:GNOME_GTM", 
						    0, NULL, &ev);

	if (gtm_download_client != NULL)
	{
		result = GTM_Download_add_url ( gtm_download_client, url, dir,
						disable_proxy,
						disable_auto_dl, &ev);
		
		if (ev._major != CORBA_NO_EXCEPTION)
		{
			g_warning ("Exception thrown: %s\n", 
				   CORBA_exception_id (&ev));
			CORBA_exception_free (&ev);
		}
	}
	else
	{
		/* GtkWidget *dialog; */
		gchar *text;

		text = g_strdup_printf (_("Failed to communicate with GTM.\n\n"
					  "Please check it is installed "
					  "correctly. Download it from:\n"
					  "\thttp://gtm.sourceforge.net"));
		/* dialog = gnome_error_dialog (text); */
		/* gnome_dialog_run_and_close (GNOME_DIALOG (dialog)); */
		g_warning(text);
		g_free (text);
	}
  
	return result;
}
