/*
 * GQmpeg
 * (C)1998, 1999 John Ellis
 *
 * Author: John Ellis
 *
 * This software is released under the GNU General Public License.
 * Please read the included file COPYING for more information.
 * This software comes with no warranty of any kind, use at you own risk!
 */

#include "gqmpeg.h"
#include "utildlg.h"

enum {
	DIALOG_SAVE,
	DIALOG_LOAD,
	DIALOG_APPEND,
	DIALOG_IMPORT
};

static void playlist_confirm_cancel(GtkWidget *widget, gpointer data);
static void playlist_confirm_ok(GtkWidget *widget, gpointer data);
static gint playlist_save_confirmed(gchar *path, gint overwrite);
static void playlist_save_pressed(GtkWidget *widget, gpointer data);
static void playlist_load_pressed(GtkWidget *widget, gpointer data);
static void playlist_append_pressed(GtkWidget *widget, gpointer data);
static void playlist_import_pressed(GtkWidget *widget, gpointer data);
static void playlist_save_confirmed_by_enter(gchar *path, gpointer data);
static void playlist_load_confirmed_by_enter(gchar *path, gpointer data);
static void playlist_append_confirmed_by_enter(gchar *path, gpointer data);
static void playlist_import_confirmed_by_enter(gchar *path, gpointer data);
static void playlist_completion_sync_list(gchar *path, gpointer data);
static void playlist_save_or_load_dialog(gchar *path, gint type);

static void playlist_dialog_load_file_pressed(GtkWidget *widget, gpointer data);
static void playlist_dialog_load_file_confirmed_by_enter(gchar *path, gpointer data);
static void playlist_dialog_load_file_completion_sync(gchar *path, gpointer data);

/*
 *-----------------------------------------------------------------------------
 * playlist save and load dialogs (private)
 *-----------------------------------------------------------------------------
 */

static void playlist_confirm_cancel(GtkWidget *widget, gpointer data)
{
	g_free(data);
}

static void playlist_confirm_ok(GtkWidget *widget, gpointer data)
{
	gchar *path = data;
	playlist_save_confirmed(path, TRUE);
	g_free(path);
}

static gint playlist_save_confirmed(gchar *path, gint overwrite)
{
	if (isdir(path))
		{
		gchar *buf;
		buf = g_strconcat("specified path is a directory, playlists are files\n", path, NULL);
		warning_dialog("Invalid filename", buf);
		g_free(buf);
		return TRUE;
		}

	if (!overwrite && isfile(path))
		{
		ConfirmDialog *cd;
		gchar *buf;

		buf = g_strconcat("Overwrite playlist file:\n", path, NULL);
		cd = confirm_dialog_new("Overwrite File", buf, playlist_confirm_cancel, g_strdup(path));
		g_free(buf);
		confirm_dialog_add(cd, "Overwrite", playlist_confirm_ok);

		return FALSE;
		}

	if (!playlist_save(path))
		{
		gchar *buf = g_strconcat("Failed to save the playlist:\n", path, NULL);
		warning_dialog("Save Failed", buf);
		g_free(buf);
		}

	return FALSE;
}

static void playlist_save_pressed(GtkWidget *widget, gpointer data)
{
	FileDialog *fd = data;
	gchar *buf = gtk_entry_get_text(GTK_ENTRY(fd->entry));

	if (strlen(buf) > 7 && strncasecmp(buf + (strlen(buf) - 7), ".gqmpeg", 7) == 0)
		{
		fd->dest_path = g_strdup(buf);
		}
	else
		{
		fd->dest_path = g_strconcat(buf, ".gqmpeg", NULL);
		}

	if (playlist_save_confirmed(fd->dest_path, FALSE))
		{
		g_free(fd->dest_path);
		fd->dest_path = NULL;
		}
	else
		{
		generic_dialog_close(NULL, fd);
		}
}

static void real_playlist_button_pressed(GtkWidget *widget, gpointer data, gint append, gint import)
{
	FileDialog *fd = data;
	fd->dest_path = g_strdup(gtk_entry_get_text(GTK_ENTRY(fd->entry)));

	if (isdir(fd->dest_path))
		{
		destination_widget_sync_to_entry(fd->entry);
		g_free(fd->dest_path);
		fd->dest_path = NULL;
		return;
		}

	playlist_load_from_file(fd->dest_path, append, import);

	generic_dialog_close(NULL, fd);
}

static void playlist_load_pressed(GtkWidget *widget, gpointer data)
{
	real_playlist_button_pressed(widget, data, FALSE, TRUE);
}

static void playlist_append_pressed(GtkWidget *widget, gpointer data)
{
	real_playlist_button_pressed(widget, data, TRUE, TRUE);
}

static void playlist_import_pressed(GtkWidget *widget, gpointer data)
{
	real_playlist_button_pressed(widget, data, TRUE, FALSE);
}

static void playlist_save_confirmed_by_enter(gchar *path, gpointer data)
{
	FileDialog *fd = data;
	playlist_save_pressed(NULL, fd);
}

static void playlist_load_confirmed_by_enter(gchar *path, gpointer data)
{
	FileDialog *fd = data;
	playlist_load_pressed(NULL, fd);
}

static void playlist_append_confirmed_by_enter(gchar *path, gpointer data)
{
	FileDialog *fd = data;
	playlist_append_pressed(NULL, fd);
}

static void playlist_import_confirmed_by_enter(gchar *path, gpointer data)
{
	FileDialog *fd = data;
	playlist_import_pressed(NULL, fd);
}

static void playlist_completion_sync_list(gchar *path, gpointer data)
{
	FileDialog *fd = data;
	destination_widget_sync_to_entry(fd->entry);
}

static void playlist_save_or_load_dialog(gchar *path, gint type)
{
	FileDialog *fd;
	GtkWidget *list;
	GtkWidget *tabcomp;
	gchar *title;
	gchar *text;
	gchar *btntext;
	void *btnfunc;

	if (!path) return;

	if (type == DIALOG_SAVE)
		{
		title = "Save Playlist";
		text = "Save playlist as:";
		btntext = "Save";
		btnfunc = playlist_save_pressed;
		}
	else if (type == DIALOG_LOAD)
		{
		title = "Load Playlist";
		text = "Load playlist from:";
		btntext = "Load";
		btnfunc = playlist_load_pressed;
		}
	else if (type == DIALOG_APPEND)
		{
		title = "Append Playlist";
		text = "Append playlist from:";
		btntext = "Append";
		btnfunc = playlist_append_pressed;
		}
	else
		{
		title = "Import Playlist";
		text = "Import playlist from:";
		btntext = "Import";
		btnfunc = playlist_import_pressed;
		}

	fd = generic_dialog_new(title, text, btntext, "Cancel",
		btnfunc, generic_dialog_close);

	fd->source_path = g_strdup(path);

	if (type == DIALOG_SAVE)
		{
		tabcomp = tab_completion_new(&fd->entry, fd->dialog, fd->source_path, playlist_save_confirmed_by_enter, fd);
		}
	else if (type == DIALOG_LOAD)
		{
		tabcomp = tab_completion_new(&fd->entry, fd->dialog, fd->source_path, playlist_load_confirmed_by_enter, fd);
		}
	else if (type == DIALOG_APPEND)
		{
		tabcomp = tab_completion_new(&fd->entry, fd->dialog, fd->source_path, playlist_append_confirmed_by_enter, fd);
		}
	else
		{
		tabcomp = tab_completion_new(&fd->entry, fd->dialog, fd->source_path, playlist_import_confirmed_by_enter, fd);
		}

	gtk_box_pack_start(GTK_BOX(fd->vbox), tabcomp, FALSE,FALSE,0);
	gtk_widget_show(tabcomp);

	gtk_widget_grab_focus(fd->entry);
	gtk_entry_select_region(GTK_ENTRY(fd->entry), 0, strlen(fd->source_path));

	if (type != DIALOG_IMPORT)
		{
		list = destination_widget_new_with_files(fd->source_path, ".gqmpeg", fd->entry);
		}
	else
		{
		list = destination_widget_new_with_files(fd->source_path, "*", fd->entry);
		}
	gtk_box_pack_start(GTK_BOX(fd->vbox), list, TRUE, TRUE, 0);
	gtk_widget_show(list);

	tab_completion_add_tab_func(fd->entry, playlist_completion_sync_list, fd);
}

/*
 *-----------------------------------------------------------------------------
 * playlist save and load dialogs (public)
 *-----------------------------------------------------------------------------
 */

void playlist_dialog_save_as(gchar *path)
{
	if (playlist_get_count() < 1)
		{
		warning_dialog("Playlist empty", "The current playlist is empty, save aborted.");
		return;
		}
	playlist_save_or_load_dialog(path, DIALOG_SAVE);
}

void playlist_dialog_load(gchar *path)
{
	playlist_save_or_load_dialog(path, DIALOG_LOAD);
}

void playlist_dialog_append(gchar *path)
{
	playlist_save_or_load_dialog(path, DIALOG_APPEND);
}

void playlist_dialog_import(gchar *path)
{
	playlist_save_or_load_dialog(path, DIALOG_IMPORT);
}

/*
 *-----------------------------------------------------------------------------
 * playlist add custom (non file-types, or urls, etc.)
 *-----------------------------------------------------------------------------
 */

static void playlist_dialog_custom_add_cb(GtkWidget *widget, gpointer data)
{
	FileDialog *fd = data;
	gchar *path;
	if (fd->type == -1) return;

	path = typelist_get_path_from_widget(fd->type, fd->entry);

	if (!path) return;

	if (fd->type)
		{
		playlist_add(path);
		}
	else
		{
		current_song_set_and_play(-1, path);
		}
	g_free(path);

	generic_dialog_close(NULL, fd);
}

static void playlist_dialog_custom_close_cb(GtkWidget *widget, gpointer data)
{
	FileDialog *fd = data;
	generic_dialog_close(NULL, fd);
}

static void playlist_dialog_menu_cb(GtkWidget *widget, gpointer data)
{
	FileDialog *fd = data;
	gint c = GPOINTER_TO_INT(gtk_object_get_user_data(GTK_OBJECT(widget)));
	if (fd->type == c) return;

	gtk_widget_destroy(fd->entry);
	fd->entry = typelist_get_entry_widget_by_id(c, current_path);
	if (!fd->entry)
		{
		fd->entry = gtk_label_new("no entry defined");
		fd->type = -1;
		}
	gtk_box_pack_start (GTK_BOX(fd->vbox), fd->entry, FALSE, FALSE,0);
	gtk_widget_show(fd->entry);
	fd->type = c;
}

void playlist_dialog_add_custom_type(gint to_playlist)
{
	FileDialog *fd;
	GtkWidget *optionmenu;
	GtkWidget *menu;
	GtkWidget *item;
	GList *list;
	GList *work;
	gint c = 0;
	gchar *title;

	if (to_playlist)
		{
		title = "GQmpeg - add custom song type";
		}
	else
		{
		title = "GQmpeg - open custom song type";
		}

	fd = generic_dialog_new(title, NULL, "Ok", "Cancel",
                playlist_dialog_custom_add_cb,
                playlist_dialog_custom_close_cb);

	fd->type = to_playlist;

	optionmenu = gtk_option_menu_new();
	gtk_box_pack_start (GTK_BOX(fd->vbox), optionmenu, FALSE, FALSE,0);
	gtk_widget_show (optionmenu);

	menu = gtk_menu_new();

	list = typelist_get_description_list();
	work = list;

	while(work)
		{
		item = gtk_menu_item_new_with_label (work->data);
		gtk_signal_connect (GTK_OBJECT (item), "activate",
			(GtkSignalFunc) playlist_dialog_menu_cb, fd);
		gtk_object_set_user_data(GTK_OBJECT(item), GINT_TO_POINTER(c));
		c++;
		gtk_menu_append (GTK_MENU (menu), item);
		gtk_widget_show (item);
		work = work->next;
		}

	gtk_option_menu_set_menu(GTK_OPTION_MENU(optionmenu), menu);

	if (list)
		{
		fd->entry = typelist_get_entry_widget_by_id(0, current_path);
		if (!fd->entry)
			{
			fd->entry = gtk_label_new("no entry defined");
			fd->type = -1;
			}
		gtk_box_pack_start (GTK_BOX(fd->vbox), fd->entry, FALSE, FALSE,0);
		gtk_widget_show(fd->entry);
		fd->type = 0;
		}
	else
		{
		GtkWidget *label = gtk_label_new("No types enabled");
		gtk_box_pack_start (GTK_BOX(fd->vbox), label, FALSE, FALSE,0);
		gtk_widget_show(label);
		fd->entry = NULL;
		fd->type = -1;
		}

	g_list_free(list);
}

/*
 *-----------------------------------------------------------------------------
 * playlist edit custom (non file-types, or urls, etc.)
 *-----------------------------------------------------------------------------
 */

static void playlist_dialog_custom_edit_ok_cb(GtkWidget *widget, gpointer data)
{
	FileDialog *fd = data;
	gchar *path;
	gint row;
	SongData *sd;

	if (fd->type == -1) return;

	sd = gtk_object_get_user_data(GTK_OBJECT(fd->dialog));
	path = typelist_get_path_from_widget(fd->type, fd->entry);

	if (!path) return;

	row = playlist_get_index_by_data(sd);
	if (row >= 0)
		{
		playlist_update(row, path);
		}
		
	g_free(path);

	generic_dialog_close(NULL, fd);
}

static void playlist_dialog_custom_edit_close_cb(GtkWidget *widget, gpointer data)
{
	FileDialog *fd = data;
	generic_dialog_close(NULL, fd);
}

void playlist_dialog_edit_custom_type(SongData *sd)
{
	FileDialog *fd;

	if (!sd->custom) return;

	fd = generic_dialog_new("GQmpeg - edit custom song type", NULL, "Change", "Cancel",
                playlist_dialog_custom_edit_ok_cb,
                playlist_dialog_custom_edit_close_cb);

	gtk_object_set_user_data(GTK_OBJECT(fd->dialog), sd);

	fd->entry = typelist_get_edit_widget_by_id(sd->custom_type, sd);
	if (!fd->entry)
		{
		fd->entry = gtk_label_new("no entry defined");
		fd->type = -1;
		}
	gtk_box_pack_start (GTK_BOX(fd->vbox), fd->entry, FALSE, FALSE,0);
	gtk_widget_show(fd->entry);
	fd->type = sd->custom_type;
}

/*
 *-----------------------------------------------------------------------------
 * load a file
 *-----------------------------------------------------------------------------
 */

static void playlist_dialog_load_file_pressed(GtkWidget *widget, gpointer data)
{
	FileDialog *fd = data;
	fd->dest_path = g_strdup(gtk_entry_get_text(GTK_ENTRY(fd->entry)));

	if (isdir(fd->dest_path))
		{
		destination_widget_sync_to_entry(fd->entry);
		g_free(fd->dest_path);
		fd->dest_path = NULL;
		return;
		}

	if (fd->type)
		{
		playlist_add(fd->dest_path);
		}
	else
		{
		current_song_set_and_play(-1, fd->dest_path);
		}

	generic_dialog_close(NULL, fd);
}

static void playlist_dialog_load_file_confirmed_by_enter(gchar *path, gpointer data)
{
	playlist_dialog_load_file_pressed(NULL, data);
}

static void playlist_dialog_load_file_completion_sync(gchar *path, gpointer data)
{
	FileDialog *fd = data;
	destination_widget_sync_to_entry(fd->entry);
}

void playlist_dialog_load_file(gchar *path, gint to_playlist)
{
	FileDialog *fd;
	GtkWidget *list;
	GtkWidget *tabcomp;
	gchar *text;
	gchar *filter;

	if (!path) return;

	if (to_playlist)
		{
		text = "Add to playlist:";
		}
	else
		{
		text = "Open file:";
		}
	fd = generic_dialog_new("GQmpeg - open", text, "Ok", "Cancel",
		playlist_dialog_load_file_pressed , generic_dialog_close);
	fd->type = to_playlist;

	fd->source_path = g_strdup(path);

	tabcomp = tab_completion_new(&fd->entry, fd->dialog, fd->source_path, playlist_dialog_load_file_confirmed_by_enter, fd);
	gtk_box_pack_start(GTK_BOX(fd->vbox), tabcomp, FALSE, FALSE,0);
	gtk_widget_show(tabcomp);
	
	gtk_widget_grab_focus(fd->entry);
	gtk_entry_select_region(GTK_ENTRY(fd->entry), 0, strlen(fd->source_path));

	filter = filter_get_text_list();
	list = destination_widget_new_with_files(fd->source_path, filter, fd->entry);
	g_free(filter);
	gtk_box_pack_start(GTK_BOX(fd->vbox), list, TRUE, TRUE, 0);
	gtk_widget_show(list);

	tab_completion_add_tab_func(fd->entry, playlist_dialog_load_file_completion_sync, fd);
}

