/*
 * Copyright (C) Birb Developers
 *
 * Birb is the legal property of its developers, whose names are too numerous
 * to list here. Please refer to the AUTHORS file distributed with this source
 * distribution
 *
 * This library is free software; you can redistribute it and/or modify it
 * under the terms of the GNU Lesser General Public License as published by the
 * Free Software Foundation; either version 2.1 of the License, or (at your
 * option) any later version.
 *
 * This library 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 Lesser General Public License
 * for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with this library; if not, see <https://www.gnu.org/licenses/>.
 */

#include "birbactionmenu.h"

struct _BirbActionMenu {
	GObject parent;

	GMenu *menu;
	GHashTable *action_groups;
};

/******************************************************************************
 * GObject Implementation
 *****************************************************************************/
G_DEFINE_FINAL_TYPE(BirbActionMenu, birb_action_menu, G_TYPE_OBJECT)

static void
birb_action_menu_finalize(GObject *obj) {
	BirbActionMenu *menu = BIRB_ACTION_MENU(obj);

	g_clear_object(&menu->menu);
	g_clear_pointer(&menu->action_groups, g_hash_table_unref);

	G_OBJECT_CLASS(birb_action_menu_parent_class)->finalize(obj);
}

static void
birb_action_menu_init(BirbActionMenu *menu) {
	menu->menu = g_menu_new();
	menu->action_groups = g_hash_table_new_full(g_str_hash, g_str_equal,
	                                            g_free, g_object_unref);
}

static void
birb_action_menu_class_init(BirbActionMenuClass *klass) {
	GObjectClass *obj_class = G_OBJECT_CLASS(klass);

	obj_class->finalize = birb_action_menu_finalize;
}

/******************************************************************************
 * Public API
 *****************************************************************************/
BirbActionMenu *
birb_action_menu_new(void) {
	return g_object_new(BIRB_TYPE_ACTION_MENU, NULL);
}

GMenu *
birb_action_menu_get_menu(BirbActionMenu *menu) {
	g_return_val_if_fail(BIRB_IS_ACTION_MENU(menu), NULL);

	return menu->menu;
}

gboolean
birb_action_menu_add_action_group(BirbActionMenu *menu, const char *prefix,
                                  GActionGroup *group)
{
	g_return_val_if_fail(BIRB_IS_ACTION_MENU(menu), FALSE);
	g_return_val_if_fail(prefix != NULL, FALSE);
	g_return_val_if_fail(G_IS_ACTION_GROUP(group), FALSE);

	if(g_hash_table_contains(menu->action_groups, prefix)) {
		return FALSE;
	}

	g_hash_table_insert(menu->action_groups, g_strdup(prefix),
	                    g_object_ref(group));

	return TRUE;
}

void
birb_action_menu_foreach_action_group(BirbActionMenu *menu,
                                      BirbActionMenuForeachActionGroupFunc func,
                                      gpointer user_data)
{
	GHashTableIter iter;
	gpointer key = NULL;
	gpointer value = NULL;

	g_return_if_fail(BIRB_IS_ACTION_MENU(menu));
	g_return_if_fail(func != NULL);

	g_hash_table_iter_init(&iter, menu->action_groups);
	while(g_hash_table_iter_next(&iter, &key, &value)) {
		func(key, value, user_data);
	}
}
