/*
 * 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_macros.h"
#include "roccat_macro_keystrokes.h"
#include "g_roccat_helper.h"
#include <errno.h>

/*!
 * \brief Return path of macro file
 * \retval Path that has to be freed with g_free()
 */
static gchar *roccat_macros_path(void) {
	gchar *dir = roccat_configuration_dir();
	gchar *path = g_build_path("/", dir, "roccat_macros.ini", NULL);
	g_free(dir);
	return path;
}

RoccatMacros *roccat_macros_new(void) {
	RoccatMacros *roccat_macros;
	roccat_macros = g_malloc(sizeof(RoccatMacros));
	roccat_macros->key_file = g_key_file_new();
	return roccat_macros;
}

RoccatMacros *roccat_macros_load(void) {
	gchar *path;
	RoccatMacros *roccat_macros;

	roccat_macros = roccat_macros_new();
	path = roccat_macros_path();

	/* file might not exist yet */
	g_key_file_load_from_file(roccat_macros->key_file, path, G_KEY_FILE_KEEP_COMMENTS, NULL);

	g_free(path);
	return roccat_macros;
}

gboolean roccat_macros_save(RoccatMacros *roccat_macros, GError **error) {
	gchar *dir, *path, *data;
	gsize length;
	gboolean retval;

	dir = roccat_configuration_dir();
	if (!roccat_create_dir_if_needed(dir, error))
		return FALSE;
	g_free(dir);

	path = roccat_macros_path();
	data = g_key_file_to_data(roccat_macros->key_file, &length, error);

	retval = g_file_set_contents(path, data, length, error);

	g_free(data);
	g_free(path);

	return retval;
}

void roccat_macros_free(RoccatMacros *roccat_macros) {
	if (roccat_macros) {
		g_key_file_free(roccat_macros->key_file);
		g_free(roccat_macros);
	}
}

RoccatMacro *roccat_macros_get(RoccatMacros *roccat_macros, gchar const *macro_set_name, gchar const *macro_name, GError **error) {
	RoccatMacroKeystrokes *roccat_macro_keystrokes;
	RoccatMacro *result;

	roccat_macro_keystrokes = roccat_key_file_get_roccat_macro_keystrokes(roccat_macros->key_file, macro_set_name, macro_name, error);
	if (!roccat_macro_keystrokes)
		return NULL;

	result = roccat_macro_new(macro_set_name, macro_name, roccat_macro_keystrokes);
	g_free(roccat_macro_keystrokes);
	return result;
}

void roccat_macros_set(RoccatMacros *roccat_macros, RoccatMacro const *macro) {
	roccat_key_file_set_binary(roccat_macros->key_file, macro->macro_set, macro->macro, &macro->keystrokes, sizeof(RoccatMacroKeystrokes));
}

gchar **roccat_macros_get_macro_sets(RoccatMacros *roccat_macros, gsize *length) {
	return g_key_file_get_groups(roccat_macros->key_file, length);
}

gchar **roccat_macros_get_macros(RoccatMacros *roccat_macros, gchar const *macro_set_name, gsize *length, GError **error) {
	return g_key_file_get_keys(roccat_macros->key_file, macro_set_name, length, error);
}
