/*
 * 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 "iskufxconfig_color_frame.h"
#include "roccat/iskufx.h"
#include "roccat_color_palette_button.h"

#define ISKUFXCONFIG_COLOR_FRAME_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), ISKUFXCONFIG_COLOR_FRAME_TYPE, IskufxconfigColorFrameClass))
#define IS_ISKUFXCONFIG_COLOR_FRAME_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), ISKUFXCONFIG_COLOR_FRAME_TYPE))
#define ISKUFXCONFIG_COLOR_FRAME_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE((obj), ISKUFXCONFIG_COLOR_FRAME_TYPE, IskufxconfigColorFramePrivate))

typedef struct _IskufxconfigColorFrameClass IskufxconfigColorFrameClass;
typedef struct _IskufxconfigColorFramePrivate IskufxconfigColorFramePrivate;

struct _IskufxconfigColorFrame {
	GtkFrame parent;
	IskufxconfigColorFramePrivate *priv;
};

struct _IskufxconfigColorFrameClass {
	GtkFrameClass parent_class;
};

struct _IskufxconfigColorFramePrivate {
	GtkToggleButton *breathing;
	GtkToggleButton *light;

	GtkToggleButton *single_color_radio;
	GtkToggleButton *custom_color_radio;
	GtkToggleButton *color_flow_radio;

	RoccatColorPaletteButton *single_color;
	GtkColorButton *custom_color;
};

G_DEFINE_TYPE(IskufxconfigColorFrame, iskufxconfig_color_frame, GTK_TYPE_FRAME);

static GdkColor const colors[ISKUFX_RKP_LIGHT_INFO_COLORS_NUM] = {
	{0,  50 * 257, 165 * 257, 254 * 257},
	{0,   0 * 257, 113 * 257, 254 * 257},
	{0,  37 * 257,   0 * 257, 253 * 257},
	{0,  92 * 257,  24 * 257, 231 * 257},
	{0, 129 * 257,  24 * 257, 230 * 257},
	{0, 196 * 257,  24 * 257, 230 * 257},
	{0, 255 * 257,   5 * 257, 128 * 257},
	{0, 255 * 257,  18 * 257,   0 * 257},
	{0, 253 * 257, 123 * 257,   1 * 257},
	{0, 254 * 257, 242 * 257,   0 * 257},
	{0, 197 * 257, 245 * 257,   9 * 257},
	{0,  40 * 257, 254 * 257,   0 * 257},
	{0,  24 * 257, 167 * 257,  43 * 257},
	{0,  19 * 257, 235 * 257, 150 * 257},
	{0,  13 * 257, 237 * 257, 227 * 257},
	{0,   1 * 257, 197 * 257, 255 * 257},
};

static void light_info_to_color(IskufxRkpLightInfo const *light_info, GdkColor *color) {
	color->pixel = 0;
	color->red = light_info->red * 257;
	color->green = light_info->green * 257;
	color->blue = light_info->blue * 257;
}

static void activate_radio_cb(GtkButton *color_button, gpointer user_data) {
	GtkToggleButton *button = GTK_TOGGLE_BUTTON(user_data);
	gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button), TRUE);
}

void iskufxconfig_color_frame_set_from_rkp(IskufxconfigColorFrame *frame, IskuRkp *rkp) {
	IskufxconfigColorFramePrivate *priv = frame->priv;
	IskufxRkpLightInfo *light_info;
	GdkColor color;
	guint type;

	gtk_toggle_button_set_active(priv->breathing, iskufx_rkp_get_light_breath_switch(rkp));
	gtk_toggle_button_set_active(priv->light, iskufx_rkp_get_light_switch(rkp));

	type = iskufx_rkp_get_light_color_type(rkp);
	switch (type) {
	case ISKUFX_LIGHT_COLOR_TYPE_SINGLE:
		gtk_toggle_button_set_active(priv->single_color_radio, TRUE);
		break;
	case ISKUFX_LIGHT_COLOR_TYPE_CUSTOM:
		gtk_toggle_button_set_active(priv->custom_color_radio, TRUE);
		break;
	case ISKUFX_LIGHT_COLOR_TYPE_FLOW:
		gtk_toggle_button_set_active(priv->color_flow_radio, TRUE);
		break;
	}

	light_info = iskufx_rkp_get_rkp_light_info(rkp);

	if (light_info->index)
		roccat_color_palette_button_set_index(priv->single_color, light_info->index);

	light_info_to_color(light_info, &color);
	gtk_color_button_set_color(priv->custom_color, &color);

	g_free(light_info);
}

void iskufxconfig_color_frame_update_rkp(IskufxconfigColorFrame *frame, IskuRkp *rkp) {
	IskufxconfigColorFramePrivate *priv = frame->priv;
	IskufxRkpLightInfo light_info;
	IskufxRkpLightInfo const *standard_light_info;
	GdkColor color;
	gboolean on;
	guint index;

	on = gtk_toggle_button_get_active(priv->light);
	iskufx_rkp_set_light_switch(rkp, on ? ISKUFX_LIGHT_STATE_ON : ISKUFX_LIGHT_STATE_OFF);

	on = gtk_toggle_button_get_active(priv->breathing);
	iskufx_rkp_set_light_breath_switch(rkp, on ? ISKUFX_LIGHT_BREATHING_ON : ISKUFX_LIGHT_BREATHING_OFF);

	if (gtk_toggle_button_get_active(priv->single_color_radio)) {
		index = roccat_color_palette_button_get_index(priv->single_color);
		standard_light_info = iskufx_rkp_light_info_get_standard(index);
		light_info = *standard_light_info;
		iskufx_rkp_set_rkp_light_info(rkp, &light_info);
	} else {
		gtk_color_button_get_color(priv->custom_color, &color);
		light_info.index = 0;
		light_info.state = ISKUFX_RKP_LIGHT_INFO_STATE_ON;
		light_info.red = color.red / 257;
		light_info.green = color.green / 257;
		light_info.blue = color.blue / 257;
		iskufx_rkp_set_rkp_light_info(rkp, &light_info);
	}

	if (gtk_toggle_button_get_active(priv->single_color_radio))
		iskufx_rkp_set_light_color_type(rkp, ISKUFX_LIGHT_COLOR_TYPE_SINGLE);
	else if (gtk_toggle_button_get_active(priv->custom_color_radio))
		iskufx_rkp_set_light_color_type(rkp, ISKUFX_LIGHT_COLOR_TYPE_CUSTOM);
	else if (gtk_toggle_button_get_active(priv->color_flow_radio))
		iskufx_rkp_set_light_color_type(rkp, ISKUFX_LIGHT_COLOR_TYPE_FLOW);
}

GtkWidget *iskufxconfig_color_frame_new(void) {
	IskufxconfigColorFrame *frame;

	frame = ISKUFXCONFIG_COLOR_FRAME(g_object_new(ISKUFXCONFIG_COLOR_FRAME_TYPE,
			NULL));

	return GTK_WIDGET(frame);
}

static void iskufxconfig_color_frame_init(IskufxconfigColorFrame *frame) {
	IskufxconfigColorFramePrivate *priv = ISKUFXCONFIG_COLOR_FRAME_GET_PRIVATE(frame);
	GtkTable *table;

	frame->priv = priv;

	table = GTK_TABLE(gtk_table_new(6, 2, FALSE));
	priv->light = GTK_TOGGLE_BUTTON(gtk_check_button_new_with_label("Fully lightened"));
	priv->breathing = GTK_TOGGLE_BUTTON(gtk_check_button_new_with_label("Breathing"));
	priv->single_color_radio = GTK_TOGGLE_BUTTON(gtk_radio_button_new_with_label(NULL, "Single color"));
	priv->custom_color_radio = GTK_TOGGLE_BUTTON(gtk_radio_button_new_with_label_from_widget(GTK_RADIO_BUTTON(priv->single_color_radio), "Custom color"));
	priv->color_flow_radio = GTK_TOGGLE_BUTTON(gtk_radio_button_new_with_label_from_widget(GTK_RADIO_BUTTON(priv->custom_color_radio), "Color flow"));
	priv->single_color = ROCCAT_COLOR_PALETTE_BUTTON(roccat_color_palette_button_new(colors, ISKUFX_RKP_LIGHT_INFO_COLORS_NUM));
	priv->custom_color = GTK_COLOR_BUTTON(gtk_color_button_new());

	g_signal_connect(G_OBJECT(priv->single_color), "clicked", G_CALLBACK(activate_radio_cb), priv->single_color_radio);
	g_signal_connect(G_OBJECT(priv->custom_color), "clicked", G_CALLBACK(activate_radio_cb), priv->custom_color_radio);

	gtk_table_attach(table, GTK_WIDGET(priv->light), 0, 2, 0, 1, GTK_FILL, GTK_EXPAND, 0, 0);
	gtk_table_attach(table, GTK_WIDGET(priv->breathing), 0, 2, 1, 2, GTK_FILL, GTK_EXPAND, 0, 0);
	gtk_table_attach(table, gtk_hseparator_new(), 0, 2, 2, 3, GTK_EXPAND, GTK_EXPAND, 0, 0);
	gtk_table_attach(table, GTK_WIDGET(priv->single_color_radio), 0, 1, 3, 4, GTK_FILL, GTK_EXPAND, 0, 0);
	gtk_table_attach(table, GTK_WIDGET(priv->custom_color_radio), 0, 1, 4, 5, GTK_FILL, GTK_EXPAND, 0, 0);
	gtk_table_attach(table, GTK_WIDGET(priv->color_flow_radio), 0, 1, 5, 6, GTK_FILL, GTK_EXPAND, 0, 0);
	gtk_table_attach(table, GTK_WIDGET(priv->single_color), 1, 2, 3, 4, GTK_EXPAND, GTK_EXPAND, 0, 0);
	gtk_table_attach(table, GTK_WIDGET(priv->custom_color), 1, 2, 4, 5, GTK_EXPAND, GTK_EXPAND, 0, 0);
	gtk_container_add(GTK_CONTAINER(frame), GTK_WIDGET(table));

	gtk_frame_set_label(GTK_FRAME(frame), "Color");
}

static void iskufxconfig_color_frame_class_init(IskufxconfigColorFrameClass *klass) {
	g_type_class_add_private(klass, sizeof(IskufxconfigColorFramePrivate));
}
