/*
 * This file is part of roccat-tools.
 *
 * roccat-tools 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.
 *
 * roccat-tools 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 roccat-tools. If not, see <http://www.gnu.org/licenses/>.
 */

#include "roccat/roccat.h"
#include "roccat_macro_editor_dialog_menu_bar.h"
#include "roccat_about_dialog.h"
#include "roccat_warning_dialog.h"

static GtkFileFilter *arvo_file_filter_new(void) {
	GtkFileFilter *filter;
	filter = gtk_file_filter_new();
	gtk_file_filter_set_name(filter, "Arvo macro files");
	gtk_file_filter_add_pattern(filter, "*.ini");
	return filter;
}

static GtkFileFilter *kone_file_filter_new(void) {
	GtkFileFilter *filter;
	filter = gtk_file_filter_new();
	gtk_file_filter_set_name(filter, "Kone macro files");
	gtk_file_filter_add_pattern(filter, "*.ini");
	return filter;
}

static GtkFileFilter *valo_file_filter_new(void) {
	GtkFileFilter *filter;
	filter = gtk_file_filter_new();
	gtk_file_filter_set_name(filter, "Valo macro files");
	gtk_file_filter_add_pattern(filter, "*.dat");
	return filter;
}

static GtkFileFilter *roccat_file_filter_new(void) {
	GtkFileFilter *filter;
	filter = gtk_file_filter_new();
	gtk_file_filter_set_name(filter, "Roccat macro files");
	gtk_file_filter_add_pattern(filter, "*.dat");
	return filter;
}

static GtkFileFilter *all_file_filter_new(void) {
	GtkFileFilter *filter;
	filter = gtk_file_filter_new();
	gtk_file_filter_set_name(filter, "All files");
	gtk_file_filter_add_pattern(filter, "*");
	return filter;
}

static void show_import_cb(GtkMenuItem *item, gpointer user_data) {
	RoccatMacroEditorDialog *parent = ROCCAT_MACRO_EDITOR_DIALOG(user_data);
	RoccatKeyFile *config;
	GtkWidget *dialog;
	GError *error = NULL;
	gchar *filename, *path;
	GtkFileFilter *arvo_filter;
	GtkFileFilter *kone_filter;
	GtkFileFilter *valo_filter;
	GtkFileFilter *roccat_filter;
	GtkFileFilter *all_filter;
	GtkFileFilter *filter;
	RoccatMacros *roccat_macros;

	config = roccat_configuration_load();

	dialog = gtk_file_chooser_dialog_new("Import Roccat macros",
			GTK_WINDOW(parent),
			GTK_FILE_CHOOSER_ACTION_OPEN,
			GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
			GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT,
			NULL
	);

	roccat_filter = roccat_file_filter_new();
	gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(dialog), roccat_filter);
	arvo_filter = arvo_file_filter_new();
	gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(dialog), arvo_filter);
	kone_filter = kone_file_filter_new();
	gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(dialog), kone_filter);
	valo_filter = valo_file_filter_new();
	gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(dialog), valo_filter);
	all_filter = all_file_filter_new();
	gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(dialog), all_filter);

	path = roccat_configuration_get_macro_save_path(config);
	gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(dialog), path);
	g_free(path);

	if (gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
		filter = gtk_file_chooser_get_filter(GTK_FILE_CHOOSER(dialog));
		filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog));

		path = g_path_get_dirname(filename);
		roccat_configuration_set_macro_save_path(config, path);
		g_free(path);
		roccat_configuration_save(config, &error);

		if (filter == arvo_filter)
			roccat_macros = arvo_original_macros_import(filename, &error);
		else if (filter == kone_filter)
			roccat_macros = kone_original_macros_import(filename, &error);
		else if (filter == valo_filter)
			roccat_macros = valo_original_macros_import(filename, &error);
		else
			roccat_macros = roccat_original_macros_import(filename, &error);

		if (error) {
			roccat_warning_dialog(GTK_WINDOW(parent), "Error importing macros", error->message);
			g_clear_error(&error);
		} else {
			roccat_macro_editor_dialog_add_macros(parent, roccat_macros);
			roccat_macros_free(roccat_macros);
		}
	}
	gtk_widget_destroy(dialog);
	roccat_configuration_free(config);
}

static void show_export_cb(GtkMenuItem *item, gpointer user_data) {
	RoccatMacroEditorDialog *parent = ROCCAT_MACRO_EDITOR_DIALOG(user_data);
	RoccatKeyFile *config;
	GtkWidget *dialog;
	GError *error = NULL;
	gchar *filename, *path;
	GtkFileFilter *arvo_filter;
	GtkFileFilter *kone_filter;
	GtkFileFilter *valo_filter;
	GtkFileFilter *roccat_filter;
	GtkFileFilter *all_filter;
	GtkFileFilter *filter;
	RoccatMacros *roccat_macros;

	config = roccat_configuration_load();

	dialog = gtk_file_chooser_dialog_new("Export Roccat macros",
			GTK_WINDOW(parent),
			GTK_FILE_CHOOSER_ACTION_SAVE,
			GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
			GTK_STOCK_SAVE, GTK_RESPONSE_ACCEPT,
			NULL
	);

	roccat_filter = roccat_file_filter_new();
	gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(dialog), roccat_filter);
	arvo_filter = arvo_file_filter_new();
	gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(dialog), arvo_filter);
	kone_filter = kone_file_filter_new();
	gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(dialog), kone_filter);
	valo_filter = valo_file_filter_new();
	gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(dialog), valo_filter);
	all_filter = all_file_filter_new();
	gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(dialog), all_filter);

	path = roccat_configuration_get_macro_save_path(config);
	gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(dialog), path);
	g_free(path);

	if (gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
		filter = gtk_file_chooser_get_filter(GTK_FILE_CHOOSER(dialog));
		filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog));

		path = g_path_get_dirname(filename);
		roccat_configuration_set_macro_save_path(config, path);
		g_free(path);
		roccat_configuration_save(config, &error);

		roccat_macros = roccat_macro_editor_dialog_get_macros(parent);

		if (filter == arvo_filter)
			arvo_original_macros_export(filename, roccat_macros, &error);
		else if (filter == kone_filter)
			kone_original_macros_export(filename, roccat_macros, &error);
		else if (filter == valo_filter)
			valo_original_macros_export(filename, roccat_macros, &error);
		else
			roccat_original_macros_export(filename, roccat_macros, &error);

		roccat_macros_free(roccat_macros);

		if (error) {
			roccat_warning_dialog(GTK_WINDOW(parent), "Error exporting macros", error->message);
			g_clear_error(&error);
		}
	}
	gtk_widget_destroy(dialog);
	roccat_configuration_free(config);
}

static void show_quit_cb(GtkMenuItem *item, gpointer user_data) {
	gtk_dialog_response(GTK_DIALOG(user_data), GTK_RESPONSE_REJECT);
}

static void show_about_cb(GtkMenuItem *item, gpointer user_data) {
	roccat_about_dialog(GTK_WINDOW(user_data), "Roccat macro editor", "Application to edit roccat macros");
}

GtkWidget *roccat_macro_editor_dialog_menu_bar_new(RoccatMacroEditorDialog *dialog) {
	GtkWidget *menu_bar;
	GtkWidget *menu_item;
	GtkWidget *menu;

	menu_bar = gtk_menu_bar_new();

	menu_item = gtk_menu_item_new_with_label("File");
	menu = gtk_menu_new();
	gtk_menu_item_set_submenu(GTK_MENU_ITEM(menu_item), menu);
	gtk_menu_shell_append(GTK_MENU_SHELL(menu_bar), menu_item);

	menu_item = gtk_image_menu_item_new_with_label("Import");
	gtk_menu_shell_append(GTK_MENU_SHELL(menu), menu_item);
	g_signal_connect(G_OBJECT(menu_item), "activate", G_CALLBACK(show_import_cb), dialog);

	menu_item = gtk_image_menu_item_new_with_label("Export");
	gtk_menu_shell_append(GTK_MENU_SHELL(menu), menu_item);
	g_signal_connect(G_OBJECT(menu_item), "activate", G_CALLBACK(show_export_cb), dialog);

	menu_item = gtk_image_menu_item_new_from_stock(GTK_STOCK_QUIT, NULL);
	gtk_menu_shell_append(GTK_MENU_SHELL(menu), menu_item);
	g_signal_connect(G_OBJECT(menu_item), "activate", G_CALLBACK(show_quit_cb), dialog);

	menu_item = gtk_menu_item_new_with_label("Help");
	menu = gtk_menu_new();
	gtk_menu_item_set_submenu(GTK_MENU_ITEM(menu_item), menu);
	gtk_menu_shell_append(GTK_MENU_SHELL(menu_bar), menu_item);

	menu_item = gtk_image_menu_item_new_from_stock(GTK_STOCK_ABOUT, NULL);
	gtk_menu_shell_append(GTK_MENU_SHELL(menu), menu_item);
	g_signal_connect(G_OBJECT(menu_item), "activate", G_CALLBACK(show_about_cb), dialog);

	return menu_bar;
}
