#include "check_menu_radio_group.h"

static void check_menu_item_group_handler(GtkCheckMenuItem *item, CheckMenuItemGroupHandlerData *data) {
	bool cancel = false;

	if (data->handler) {
		cancel = data->handler(GTK_WIDGET(item), (gpointer) data->arg);
	}

	GValue value = G_VALUE_INIT;
	g_value_init(&value, G_TYPE_BOOLEAN);

	if (cancel) {
		g_value_set_boolean(&value, false);
		g_object_set_property(G_OBJECT(item), "active", &value);
	}
	else {
		for (unsigned i = 0; i < data->group->count; i++) {
			GtkCheckMenuItem *cur = GTK_CHECK_MENU_ITEM(data->group->items[i]);
			g_value_set_boolean(&value, cur == item);
			g_object_set_property(G_OBJECT(cur), "active", &value);
		}
	}
}

CheckMenuItemGroup *check_menu_item_group_new(char **names, char **args) {
	unsigned name_count = 0;

	if (names != NULL) {
		for (char **ptr = names; *ptr != NULL; ptr++, name_count++);
	}

	CheckMenuItemGroup *group = g_malloc0(sizeof(CheckMenuItemGroup));
	group->count    = name_count;
	group->items    = g_malloc0(sizeof(GtkWidget*) * name_count);
	group->handlers = g_malloc0(sizeof(CheckMenuItemGroupHandlerData*) * name_count);

	for (unsigned i = 0; i < name_count; i++) {
		group->items[i] = gtk_check_menu_item_new_with_label(names[i]);

		group->handlers[i] = g_malloc0(sizeof(CheckMenuItemGroupHandlerData));
		group->handlers[i]->group = group;
		group->handlers[i]->arg = args[i];
		g_signal_connect(group->items[i], "toggled", G_CALLBACK(check_menu_item_group_handler), group->handlers[i]);

		gtk_check_menu_item_set_draw_as_radio(GTK_CHECK_MENU_ITEM(group->items[i]), true);
	}

	return group;
}

void check_menu_item_group_activate(CheckMenuItemGroup *group, char *arg) {
	GValue value = G_VALUE_INIT;
	g_value_init(&value, G_TYPE_BOOLEAN);
	g_value_set_boolean(&value, false);

	for (unsigned i = 0; i < group->count; i++) {
		GtkCheckMenuItem *cur = GTK_CHECK_MENU_ITEM(group->items[i]);

		if (g_strcmp0(arg, group->handlers[i]->arg) == 0) {
			gtk_check_menu_item_set_active(cur, true);
		}
		else {
			g_object_set_property(G_OBJECT(cur), "active", &value);
		}
	}
}

void check_menu_item_group_connect_toggle_signal(CheckMenuItemGroup *group, bool (*handler)(GtkWidget *, gpointer)) {
	for (unsigned i = 0; i < group->count; i++) {
		group->handlers[i]->handler = handler;
	}
}

void check_menu_item_group_insert_into_menu_shell(CheckMenuItemGroup *group, GtkMenuShell *menu_shell, gint position) {
	for (unsigned i = 0; i < group->count; i++) {
		gtk_menu_shell_insert(menu_shell, group->items[i], position + i);
	}
}