#include <stdio.h>
#include <string.h>
#include <Foundation/NSAutoreleasePool.h>
#include <Foundation/NSObjCRuntime.h>

static void item_forward_signal (gpointer data, guint action, GtkWidget *widget)
{
    NSAutoreleasePool *pool = [NSAutoreleasePool new];
    id target = gtk_object_get_data((GtkObject *) widget, "_menu_target");

#ifdef DEBUG
    fprintf(stderr, "(item_forward_signal init) gtk = %p, action [%p %s]\n",
	    widget, target, NSSelector_to_String(data));
#endif
    [target performSelector:data withObject:GTK_GET_OBJECT(widget)];
    [pool release];
#ifdef DEBUG
    fprintf(stderr, "(item_forward_signal exit) gtk = %p\n", widget);
#endif
}

 /* This must be kept in sync with gtk_item_factory_parse_path()! */
static void item_parse_path (char *path, const char *str)
{
    while (*str == '_' ? *str++ : (*path++ = *str++));
}

/*
 * This is the preferred method to create item factoy entries. Note that
 * it expects a vector of type GTKItemFactoryEntry (defined in
 * GToolKit/GTKItemFactory.h) instead of the original GtkItemFactoryEntry.
 * @see -deleteEntries:count:
 */
- (void) createItems:(GTKItemFactoryEntry *) entries count:(guint) count forTarget:target
{
    for (; count--; ++entries)
    {
	char *path = g_new(char, strlen(entries->item.path) + 1);
	GtkWidget *item_widget;

	if (entries->item.callback == NULL && entries->selector)
	    entries->item.callback =
		(GtkItemFactoryCallback) item_forward_signal;

	gtk_item_factory_create_item(gtk, &entries->item,
				     (gpointer) entries->selector, 1);

	item_parse_path(path, entries->item.path);
	item_widget = gtk_item_factory_get_widget(gtk, path);
	gtk_object_set_data((GtkObject *) item_widget, "_menu_target", target);
	g_free(path);
    }
}

/*
 * This is the preferred method to delete item factoy entries. Note that it
 * expects a vector of type GTKItemFactoryEntry (defined in
 * GToolKit/GTKItemFactory.h) instead of the original GtkItemFactoryEntry.
 * @see -createItems:count:forTarget:
 */
- (void) deleteEntries:(GTKItemFactoryEntry *) entries count:(guint) count
{
    for (; count--; ++entries)
	gtk_item_factory_delete_entry(gtk, &entries->item);
}

#define gtk	((GtkItemFactory *) gtk)
- (GTKAccelGroup *) accelGroup
{
    return Gtk_to_Object(gtk->accel_group, "GTKAccelGroup");
}
#undef gtk
%
%struct _GTKItemFactoryEntry
%{
%    GtkItemFactoryEntry item;		// menu item
%    SEL selector;			// menu selector
%};
