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

#define SAVUCONFIG_LIGHT_FRAME_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), SAVUCONFIG_LIGHT_FRAME_TYPE, SavuconfigLightFrameClass))
#define IS_SAVUCONFIG_LIGHT_FRAME_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), SAVUCONFIG_LIGHT_FRAME_TYPE))
#define SAVUCONFIG_LIGHT_FRAME_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE((obj), SAVUCONFIG_LIGHT_FRAME_TYPE, SavuconfigLightFramePrivate))

typedef struct _SavuconfigLightFrameClass SavuconfigLightFrameClass;
typedef struct _SavuconfigLightFramePrivate SavuconfigLightFramePrivate;

struct _SavuconfigLightFrame {
	GtkFrame parent;
	SavuconfigLightFramePrivate *priv;
};

struct _SavuconfigLightFrameClass {
	GtkFrameClass parent_class;
};

struct _SavuconfigLightFramePrivate {
	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(SavuconfigLightFrame, savuconfig_light_frame, GTK_TYPE_FRAME);

static GdkColor const colors[SAVU_SINGLE_COLOR_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(guint red, guint green, guint blue, GdkColor *color) {
	color->pixel = 0;
	color->red = red * 257;
	color->green = green * 257;
	color->blue = 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 savuconfig_light_frame_set_from_rmp(SavuconfigLightFrame *frame, SavuRmp *rmp) {
	SavuconfigLightFramePrivate *priv = frame->priv;
	GdkColor color;
	guint color_index;
	guint color_flow;

	gtk_toggle_button_set_active(priv->breathing, savu_rmp_get_breath_on(rmp));
	gtk_toggle_button_set_active(priv->light, savu_rmp_get_light_switch(rmp));

	light_info_to_color(
			savu_rmp_get_color_red(rmp),
			savu_rmp_get_color_green(rmp),
			savu_rmp_get_color_blue(rmp),
			&color);
	gtk_color_button_set_color(priv->custom_color, &color);

	color_index = savu_rmp_get_color_database(rmp);
	if (color_index < SAVU_GENERAL_COLOR_INDEX_CUSTOM)
		roccat_color_palette_button_set_index(priv->single_color, color_index);

	color_flow = savu_rmp_get_color_flow(rmp);
	if (color_flow)
		gtk_toggle_button_set_active(priv->color_flow_radio, TRUE);
	else if (color_index == SAVU_GENERAL_COLOR_INDEX_CUSTOM)
		gtk_toggle_button_set_active(priv->custom_color_radio, TRUE);
	else
		gtk_toggle_button_set_active(priv->single_color_radio, TRUE);
}

void savuconfig_light_frame_update_rmp(SavuconfigLightFrame *frame, SavuRmp *rmp) {
	SavuconfigLightFramePrivate *priv = frame->priv;
	GdkColor color;
	gboolean on;

	gtk_color_button_get_color(priv->custom_color, &color);

	savu_rmp_set_color_red(rmp, color.red / 257);
	savu_rmp_set_color_green(rmp, color.green / 257);
	savu_rmp_set_color_blue(rmp, color.blue / 257);

	if (gtk_toggle_button_get_active(priv->custom_color_radio))
		savu_rmp_set_color_database(rmp, SAVU_GENERAL_COLOR_INDEX_CUSTOM);
	else
		savu_rmp_set_color_database(rmp, roccat_color_palette_button_get_index(priv->single_color));

	on = gtk_toggle_button_get_active(priv->light);
	savu_rmp_set_light_switch(rmp, on ? 1 : 0);

	on = gtk_toggle_button_get_active(priv->breathing);
	savu_rmp_set_breath_on(rmp, on ? 1 : 0);

	on = gtk_toggle_button_get_active(priv->color_flow_radio);
	savu_rmp_set_color_flow(rmp, on ? 1 : 0);
}

GtkWidget *savuconfig_light_frame_new(void) {
	SavuconfigLightFrame *frame;

	frame = SAVUCONFIG_LIGHT_FRAME(g_object_new(SAVUCONFIG_LIGHT_FRAME_TYPE,
			NULL));

	return GTK_WIDGET(frame);
}

static void savuconfig_light_frame_init(SavuconfigLightFrame *frame) {
	SavuconfigLightFramePrivate *priv = SAVUCONFIG_LIGHT_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, SAVU_SINGLE_COLOR_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), "Light");
}

static void savuconfig_light_frame_class_init(SavuconfigLightFrameClass *klass) {
	g_type_class_add_private(klass, sizeof(SavuconfigLightFramePrivate));
}
