/*
 * 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/konepure.h"

KonepureProfileSettings *konepure_rmp_to_profile_settings(KoneplusRmp *rmp) {
	KonepureProfileSettings *settings;
	guint i;
	KoneplusRmpLightInfo *rmp_light_info;

	settings = g_malloc0(sizeof(KonepureProfileSettings));
	settings->command = KONEPLUS_COMMAND_PROFILE_SETTINGS;
	settings->size = sizeof(KonepureProfileSettings);

	settings->xy_sync = koneplus_rmp_get_xy_synchronous(rmp);
	if (settings->xy_sync == KONEPLUS_PROFILE_SETTINGS_XY_SYNC_SYNC) {
		settings->sensitivity_x = koneplus_rmp_get_sensitivity(rmp);
		settings->sensitivity_y = settings->sensitivity_x;
	} else {
		settings->sensitivity_x = koneplus_rmp_get_sensitivity_x(rmp);
		settings->sensitivity_y = koneplus_rmp_get_sensitivity_y(rmp);
	}

	for (i = 0; i < KONEPLUS_PROFILE_SETTING_CPI_LEVELS_NUM; ++i) {
		settings->cpi_levels_x[i] = konextd_rmp_cpi_to_bin(koneplus_rmp_get_cpi_level_x(rmp, i));
		settings->cpi_levels_y[i] = konextd_rmp_cpi_to_bin(koneplus_rmp_get_cpi_level_y(rmp, i));
	}
	settings->cpi_levels_enabled = koneplus_rmp_get_cpi_all(rmp);
	settings->cpi_startup_level = koneplus_rmp_get_cpi_x(rmp);

	settings->polling_rate = koneplus_rmp_get_polling_rate(rmp);

	settings->color_flow_effect = koneplus_rmp_get_light_color_flow(rmp);
	settings->light_effect_type = koneplus_rmp_get_light_effect_type(rmp);
	settings->light_effect_speed = koneplus_rmp_get_light_effect_speed(rmp);
	settings->light_effect_mode = koneplus_rmp_get_light_effect_mode(rmp);

	rmp_light_info = koneplus_rmp_get_rmp_light_info(rmp, 0);
	koneplus_rmp_light_info_to_light_info(rmp_light_info, &settings->light);
	roccat_set_bit(&settings->light_enabled, 0, rmp_light_info->state == KONEPLUS_RMP_LIGHT_INFO_STATE_ON);
	g_free(rmp_light_info);

	return settings;
}

void konepure_rmp_update_with_profile_settings(KoneplusRmp *rmp, KonepureProfileSettings const *profile_settings) {
	KoneplusRmpLightInfo rmp_light_info;
	guint i;

	koneplus_rmp_set_xy_synchronous(rmp, profile_settings->xy_sync);
	if (profile_settings->xy_sync == KONEPLUS_PROFILE_SETTINGS_XY_SYNC_SYNC) {
		koneplus_rmp_set_sensitivity(rmp, profile_settings->sensitivity_x);
	} else {
		koneplus_rmp_set_sensitivity_x(rmp, profile_settings->sensitivity_x);
		koneplus_rmp_set_sensitivity_y(rmp, profile_settings->sensitivity_y);
	}

	for (i = 0; i < KONEPLUS_PROFILE_SETTING_CPI_LEVELS_NUM; ++i) {
		koneplus_rmp_set_cpi_level_x(rmp, i, konextd_bin_cpi_to_rmp(profile_settings->cpi_levels_x[i]));
		koneplus_rmp_set_cpi_level_y(rmp, i, konextd_bin_cpi_to_rmp(profile_settings->cpi_levels_y[i]));
	}
	koneplus_rmp_set_cpi_all(rmp, profile_settings->cpi_levels_enabled);
	koneplus_rmp_set_cpi_x(rmp, profile_settings->cpi_startup_level);
	koneplus_rmp_set_cpi_y(rmp, profile_settings->cpi_startup_level);

	koneplus_light_info_to_rmp_light_info(&profile_settings->light, &rmp_light_info);
	koneplus_rmp_set_rmp_light_info(rmp, 0, &rmp_light_info);

	koneplus_rmp_set_light_effect_type(rmp, profile_settings->light_effect_type);
	koneplus_rmp_set_light_effect_speed(rmp, profile_settings->light_effect_speed);
	koneplus_rmp_set_light_color_flow(rmp, profile_settings->color_flow_effect);
	koneplus_rmp_set_light_effect_mode(rmp, profile_settings->light_effect_mode);

	koneplus_rmp_set_polling_rate(rmp, profile_settings->polling_rate);
}

static void konepure_rmp_update_with_profile_button(KoneplusRmp *rmp,
		KoneplusProfileButton const *profile_button,
		guint rmp_index) {
	KoneplusRmpMacroKeyInfo *macro_key_info;

	switch (profile_button->type) {
	case KONEPLUS_PROFILE_BUTTON_TYPE_SHORTCUT:
		macro_key_info = koneplus_rmp_macro_key_info_new_shortcut(profile_button->key, profile_button->modifier);
		break;
	default:
		macro_key_info = koneplus_rmp_macro_key_info_new();
		macro_key_info->type = profile_button->type;
	}

	koneplus_rmp_set_macro_key_info(rmp, rmp_index, macro_key_info);
}

void konepure_rmp_update_with_profile_buttons(KoneplusRmp *rmp, KonepureProfileButtons const *profile_buttons) {
	konepure_rmp_update_with_profile_button(rmp, &profile_buttons->buttons[KONEPURE_PROFILE_BUTTONS_BUTTON_INDEX_LEFT], KONEPLUS_PROFILE_BUTTONS_BUTTON_INDEX_LEFT);
	konepure_rmp_update_with_profile_button(rmp, &profile_buttons->buttons[KONEPURE_PROFILE_BUTTONS_BUTTON_INDEX_RIGHT], KONEPLUS_PROFILE_BUTTONS_BUTTON_INDEX_RIGHT);
	konepure_rmp_update_with_profile_button(rmp, &profile_buttons->buttons[KONEPURE_PROFILE_BUTTONS_BUTTON_INDEX_MIDDLE], KONEPLUS_PROFILE_BUTTONS_BUTTON_INDEX_MIDDLE);
	konepure_rmp_update_with_profile_button(rmp, &profile_buttons->buttons[KONEPURE_PROFILE_BUTTONS_BUTTON_INDEX_FORWARD], KONEPLUS_PROFILE_BUTTONS_BUTTON_INDEX_FORWARD);
	konepure_rmp_update_with_profile_button(rmp, &profile_buttons->buttons[KONEPURE_PROFILE_BUTTONS_BUTTON_INDEX_BACKWARD], KONEPLUS_PROFILE_BUTTONS_BUTTON_INDEX_BACKWARD);
	konepure_rmp_update_with_profile_button(rmp, &profile_buttons->buttons[KONEPURE_PROFILE_BUTTONS_BUTTON_INDEX_WHEEL_UP], KONEPLUS_PROFILE_BUTTONS_BUTTON_INDEX_WHEEL_UP);
	konepure_rmp_update_with_profile_button(rmp, &profile_buttons->buttons[KONEPURE_PROFILE_BUTTONS_BUTTON_INDEX_WHEEL_DOWN], KONEPLUS_PROFILE_BUTTONS_BUTTON_INDEX_WHEEL_DOWN);
	konepure_rmp_update_with_profile_button(rmp, &profile_buttons->buttons[KONEPURE_PROFILE_BUTTONS_BUTTON_INDEX_PLUS], KONEPLUS_PROFILE_BUTTONS_BUTTON_INDEX_PLUS);
	konepure_rmp_update_with_profile_button(rmp, &profile_buttons->buttons[KONEPURE_PROFILE_BUTTONS_BUTTON_INDEX_MINUS], KONEPLUS_PROFILE_BUTTONS_BUTTON_INDEX_MINUS);
	konepure_rmp_update_with_profile_button(rmp, &profile_buttons->buttons[KONEPURE_PROFILE_BUTTONS_BUTTON_INDEX_SHIFT_LEFT], KONEPLUS_PROFILE_BUTTONS_BUTTON_INDEX_SHIFT_LEFT);
	konepure_rmp_update_with_profile_button(rmp, &profile_buttons->buttons[KONEPURE_PROFILE_BUTTONS_BUTTON_INDEX_SHIFT_RIGHT], KONEPLUS_PROFILE_BUTTONS_BUTTON_INDEX_SHIFT_RIGHT);
	konepure_rmp_update_with_profile_button(rmp, &profile_buttons->buttons[KONEPURE_PROFILE_BUTTONS_BUTTON_INDEX_SHIFT_MIDDLE], KONEPLUS_PROFILE_BUTTONS_BUTTON_INDEX_SHIFT_MIDDLE);
	konepure_rmp_update_with_profile_button(rmp, &profile_buttons->buttons[KONEPURE_PROFILE_BUTTONS_BUTTON_INDEX_SHIFT_FORWARD], KONEPLUS_PROFILE_BUTTONS_BUTTON_INDEX_SHIFT_FORWARD);
	konepure_rmp_update_with_profile_button(rmp, &profile_buttons->buttons[KONEPURE_PROFILE_BUTTONS_BUTTON_INDEX_SHIFT_BACKWARD], KONEPLUS_PROFILE_BUTTONS_BUTTON_INDEX_SHIFT_BACKWARD);
	konepure_rmp_update_with_profile_button(rmp, &profile_buttons->buttons[KONEPURE_PROFILE_BUTTONS_BUTTON_INDEX_SHIFT_WHEEL_UP], KONEPLUS_PROFILE_BUTTONS_BUTTON_INDEX_SHIFT_WHEEL_UP);
	konepure_rmp_update_with_profile_button(rmp, &profile_buttons->buttons[KONEPURE_PROFILE_BUTTONS_BUTTON_INDEX_SHIFT_WHEEL_DOWN], KONEPLUS_PROFILE_BUTTONS_BUTTON_INDEX_SHIFT_WHEEL_DOWN);
	konepure_rmp_update_with_profile_button(rmp, &profile_buttons->buttons[KONEPURE_PROFILE_BUTTONS_BUTTON_INDEX_SHIFT_PLUS], KONEPLUS_PROFILE_BUTTONS_BUTTON_INDEX_SHIFT_PLUS);
	konepure_rmp_update_with_profile_button(rmp, &profile_buttons->buttons[KONEPURE_PROFILE_BUTTONS_BUTTON_INDEX_SHIFT_MINUS], KONEPLUS_PROFILE_BUTTONS_BUTTON_INDEX_SHIFT_MINUS);
}

static void konepure_profile_buttons_set_button(KoneplusRmp *rmp, guint rmp_index,
		guint profile_index, KonepureProfileButtons *profile_buttons) {
	KoneplusRmpMacroKeyInfo *macro_key_info;
	KoneplusProfileButton *profile_button;

	macro_key_info = koneplus_rmp_get_macro_key_info(rmp, rmp_index);
	profile_button = &profile_buttons->buttons[profile_index];

	profile_button->type = macro_key_info->type;
	switch (profile_button->type) {
	case KONEPLUS_PROFILE_BUTTON_TYPE_SHORTCUT:
		profile_button->key = macro_key_info->keystrokes[0].key;
		profile_button->modifier = macro_key_info->keystrokes[0].action;
		break;
	default:
		profile_button->modifier = 0;
		profile_button->key = 0;
	}

	g_free(macro_key_info);
}

KonepureProfileButtons *konepure_rmp_to_profile_buttons(KoneplusRmp *rmp) {
	KonepureProfileButtons *buttons;

	buttons = g_malloc0(sizeof(KonepureProfileButtons));
	buttons->command = KONEPLUS_COMMAND_PROFILE_BUTTONS;
	buttons->size = sizeof(KonepureProfileButtons);

	konepure_profile_buttons_set_button(rmp, KONEPLUS_PROFILE_BUTTONS_BUTTON_INDEX_LEFT, KONEPURE_PROFILE_BUTTONS_BUTTON_INDEX_LEFT, buttons);
	konepure_profile_buttons_set_button(rmp, KONEPLUS_PROFILE_BUTTONS_BUTTON_INDEX_RIGHT, KONEPURE_PROFILE_BUTTONS_BUTTON_INDEX_RIGHT, buttons);
	konepure_profile_buttons_set_button(rmp, KONEPLUS_PROFILE_BUTTONS_BUTTON_INDEX_MIDDLE, KONEPURE_PROFILE_BUTTONS_BUTTON_INDEX_MIDDLE, buttons);
	konepure_profile_buttons_set_button(rmp, KONEPLUS_PROFILE_BUTTONS_BUTTON_INDEX_FORWARD, KONEPURE_PROFILE_BUTTONS_BUTTON_INDEX_FORWARD, buttons);
	konepure_profile_buttons_set_button(rmp, KONEPLUS_PROFILE_BUTTONS_BUTTON_INDEX_BACKWARD, KONEPURE_PROFILE_BUTTONS_BUTTON_INDEX_BACKWARD, buttons);
	konepure_profile_buttons_set_button(rmp, KONEPLUS_PROFILE_BUTTONS_BUTTON_INDEX_WHEEL_UP, KONEPURE_PROFILE_BUTTONS_BUTTON_INDEX_WHEEL_UP, buttons);
	konepure_profile_buttons_set_button(rmp, KONEPLUS_PROFILE_BUTTONS_BUTTON_INDEX_WHEEL_DOWN, KONEPURE_PROFILE_BUTTONS_BUTTON_INDEX_WHEEL_DOWN, buttons);
	konepure_profile_buttons_set_button(rmp, KONEPLUS_PROFILE_BUTTONS_BUTTON_INDEX_PLUS, KONEPURE_PROFILE_BUTTONS_BUTTON_INDEX_PLUS, buttons);
	konepure_profile_buttons_set_button(rmp, KONEPLUS_PROFILE_BUTTONS_BUTTON_INDEX_MINUS, KONEPURE_PROFILE_BUTTONS_BUTTON_INDEX_MINUS, buttons);
	konepure_profile_buttons_set_button(rmp, KONEPLUS_PROFILE_BUTTONS_BUTTON_INDEX_SHIFT_LEFT, KONEPURE_PROFILE_BUTTONS_BUTTON_INDEX_SHIFT_LEFT, buttons);
	konepure_profile_buttons_set_button(rmp, KONEPLUS_PROFILE_BUTTONS_BUTTON_INDEX_SHIFT_RIGHT, KONEPURE_PROFILE_BUTTONS_BUTTON_INDEX_SHIFT_RIGHT, buttons);
	konepure_profile_buttons_set_button(rmp, KONEPLUS_PROFILE_BUTTONS_BUTTON_INDEX_SHIFT_MIDDLE, KONEPURE_PROFILE_BUTTONS_BUTTON_INDEX_SHIFT_MIDDLE, buttons);
	konepure_profile_buttons_set_button(rmp, KONEPLUS_PROFILE_BUTTONS_BUTTON_INDEX_SHIFT_FORWARD, KONEPURE_PROFILE_BUTTONS_BUTTON_INDEX_SHIFT_FORWARD, buttons);
	konepure_profile_buttons_set_button(rmp, KONEPLUS_PROFILE_BUTTONS_BUTTON_INDEX_SHIFT_BACKWARD, KONEPURE_PROFILE_BUTTONS_BUTTON_INDEX_SHIFT_BACKWARD, buttons);
	konepure_profile_buttons_set_button(rmp, KONEPLUS_PROFILE_BUTTONS_BUTTON_INDEX_SHIFT_WHEEL_UP, KONEPURE_PROFILE_BUTTONS_BUTTON_INDEX_SHIFT_WHEEL_UP, buttons);
	konepure_profile_buttons_set_button(rmp, KONEPLUS_PROFILE_BUTTONS_BUTTON_INDEX_SHIFT_WHEEL_DOWN, KONEPURE_PROFILE_BUTTONS_BUTTON_INDEX_SHIFT_WHEEL_DOWN, buttons);
	konepure_profile_buttons_set_button(rmp, KONEPLUS_PROFILE_BUTTONS_BUTTON_INDEX_SHIFT_PLUS, KONEPURE_PROFILE_BUTTONS_BUTTON_INDEX_SHIFT_PLUS, buttons);
	konepure_profile_buttons_set_button(rmp, KONEPLUS_PROFILE_BUTTONS_BUTTON_INDEX_SHIFT_MINUS, KONEPURE_PROFILE_BUTTONS_BUTTON_INDEX_SHIFT_MINUS, buttons);

	return buttons;
}
