/*
 *  $Id: module-tool.c 28779 2025-11-04 17:00:29Z yeti-dn $
 *  Copyright (C) 2003-2006 David Necas (Yeti), Petr Klapetek.
 *  E-mail: yeti@gwyddion.net, klapetek@gwyddion.net.
 *
 *  This program 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.
 *
 *  This program 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 this program; if not, write to the Free Software
 *  Foundation, Inc., 51 Franklin Street, Fifth Floor,
 *  Boston, MA 02110-1301, USA.
 */

#include "config.h"
#include <string.h>
#include "libgwyddion/macros.h"
#include "libgwyddion/utils.h"
#include "libgwyapp/module-tool.h"
#include "libgwyapp/module-internal.h"

static GHashTable *tool_funcs = NULL;

/**
 * gwy_tool_func_register:
 * @type: Layer type in GObject type system.  That is the return value of
 *        gwy_tool_foo_get_type().
 *
 * Registeres a tool function (tool type).
 *
 * Returns: Normally %TRUE; %FALSE on failure.
 **/
gboolean
gwy_tool_func_register(GType type)
{
    const gchar *name;
    gpointer klass;

    g_return_val_if_fail(type, FALSE);
    klass = g_type_class_ref(type);
    name = g_type_name(type);
    gwy_debug("tool type = %s", name);

    if (!tool_funcs) {
        gwy_debug("Initializing...");
        tool_funcs = g_hash_table_new_full(g_str_hash, g_str_equal,
                                           NULL, NULL);
    }

    if (g_hash_table_lookup(tool_funcs, name)) {
        g_warning("Duplicate type %s, keeping only first", name);
        g_type_class_unref(klass);
        return FALSE;
    }
    g_hash_table_insert(tool_funcs, (gpointer)name, GUINT_TO_POINTER(type));
    if (!_gwy_module_add_registered_function(GWY_MODULE_PREFIX_TOOL, name)) {
        g_hash_table_remove(tool_funcs, name);
        g_type_class_unref(klass);
        return FALSE;
    }

    return TRUE;
}

/**
 * gwy_tool_func_foreach:
 * @function: (scope call):
 *            Function to run for each tool, passed by name.
 * @user_data: Data to pass to @function.
 *
 * Calls a function for each tool function.
 **/
void
gwy_tool_func_foreach(GwyNameFunc function,
                      gpointer user_data)
{
    foreach_func(tool_funcs, function, user_data);
}

gboolean
_gwy_tool_func_remove(const gchar *name)
{
    GType type;

    gwy_debug("%s", name);
    type = GPOINTER_TO_UINT(g_hash_table_lookup(tool_funcs, name));
    if (!type) {
        g_warning("Cannot remove function %s", name);
        return FALSE;
    }

    g_type_class_unref(g_type_class_peek(type));
    g_hash_table_remove(tool_funcs, name);
    return TRUE;
}

/**
 * SECTION: module-tool
 * @title: Tool modules
 * @short_description: Interactive tool modules
 *
 * Tool modules implement interactive tools that work directly on data
 * windows.
 **/

/**
 * GwyToolFuncInfo:
 * @name: An unique tool function name.
 * @stock_id: Icon stock id or button label (FIXME: more to be said).
 * @tooltip: Tooltip for this tool.
 * @use: The tool use function itself.
 *
 * Information about one tool use function.
 **/

/* vim: set cin et ts=4 sw=4 cino=>1s,e0,n0,f0,{0,}0,^0,\:1s,=0,g1s,h0,t0,+1s,c3,(0,u0 : */
