#include <stdio.h>
#include <Foundation/NSAutoreleasePool.h>
#include <Foundation/NSException.h>
#include <Foundation/NSNotification.h>
#include <GToolKit/GToolKit.h>

//#define DEBUG

@interface Foo : NSObject <GTKApplicationDelegate>
- (void) newWindow:sender;
- (void) dumpInfo:sender;
- (void) printNotification:(NSNotification *) event;
#ifdef DEBUG
- (BOOL) print:sender event:(GdkEvent *) event;
#endif
@end

@implementation Foo

- (void) newWindow:sender
{
    GTKWindow *window = [GTKWindow windowWithType:GTK_WINDOW_TOPLEVEL];
    GTKBox *box = [GTKVBox vBoxWithHomogeneous:YES spacing:0];
    GTKButton *new = [GTKButton buttonWithLabel:@"Create New Window"];
    GTKButton *dump = [GTKButton buttonWithLabel:@"Dump Information"];

    [new connectSignal:@"clicked" withTarget:self sel:@selector(newWindow:)];
    [dump connectSignal:@"clicked" withTarget:self sel:@selector(dumpInfo:)];
#ifdef DEBUG
    [window connectSignal:@"event" withTarget:self sel:@selector(print:event:)];
#endif
    [box packStartDefaults:new];
    [box packStartDefaults:dump];
    [window add:box];
    [window show];
}

- (void) dumpInfo:sender
{
    fprintf(stderr, "isRunning:\t%d\n", [GTKApp isRunning]);
    fprintf(stderr, "isActive:\t%d\n", [GTKApp isActive]);
    fprintf(stderr, "mainWindow:\t%p\n", [GTKApp mainWindow]);
    fprintf(stderr, "windows:\t%s\n", [[[GTKApp windows] description] cString]);
}

- (void) printNotification:(NSNotification *) event
{
    fprintf(stderr, "%s (object=%p)\n", [[event name] cString], [event object]);
}

#ifdef DEBUG
- (BOOL) print:sender event:(GdkEvent *) event
{
    static const char *event_names[] =
    {
	"GDK_DELETE",
	"GDK_DESTROY",
	"GDK_EXPOSE",
	"GDK_MOTION_NOTIFY",
	"GDK_BUTTON_PRESS",
	"GDK_2BUTTON_PRESS",
	"GDK_3BUTTON_PRESS",
	"GDK_BUTTON_RELEASE",
	"GDK_KEY_PRESS",
	"GDK_KEY_RELEASE",
	"GDK_ENTER_NOTIFY",
	"GDK_LEAVE_NOTIFY",
	"GDK_FOCUS_CHANGE",
	"GDK_CONFIGURE",
	"GDK_MAP",
	"GDK_UNMAP",
	"GDK_PROPERTY_NOTIFY",
	"GDK_SELECTION_CLEAR",
	"GDK_SELECTION_REQUEST",
	"GDK_SELECTION_NOTIFY",
	"GDK_PROXIMITY_IN",
	"GDK_PROXIMITY_OUT",
	"GDK_DRAG_BEGIN",
	"GDK_DRAG_REQUEST",
	"GDK_DROP_ENTER",
	"GDK_DROP_LEAVE",
	"GDK_DROP_DATA_AVAIL",
	"GDK_CLIENT_EVENT",
	"GDK_VISIBILITY_NOTIFY",
	"GDK_NO_EXPOSE",
    };

    fprintf(stderr, "%s event = %s\n", [[sender description] cString], 
	    event_names[event->any.type]);
    return NO;
}
#endif

- (void) applicationDidBecomeActive:(NSNotification *) event
{
    [self printNotification:event];
}

- (void) applicationDidFinishLaunching:(NSNotification *) event
{
    [self printNotification:event];
}

- (void) applicationDidResignActive:(NSNotification *) event
{
    [self printNotification:event];
}

- (BOOL) applicationShouldTerminate:(GTKApplication *) sender
{
    fprintf(stderr, "[foo applicationShouldTerminate]\n");
    return YES;
}

- (BOOL) applicationShouldTerminateAfterLastWindowClosed:(GTKApplication *) sender
{
    fprintf(stderr, "[foo applicationShouldTerminateAfterLastWindowClosed]\n");
    return YES;
}

- (void) applicationWillFinishLaunching:(NSNotification *) event
{
    [self printNotification:event];
}

- (void) applicationWillTerminate:(NSNotification *) event
{
    [self printNotification:event];
}
@end

int main (int argc, char *argv[])
{
    NSAutoreleasePool *pool = [NSAutoreleasePool new];
    Foo *foo = [[Foo new] autorelease];
#ifdef LIB_FOUNDATION_LIBRARY
    extern char **environ;
    [NSProcessInfo initializeWithArguments:argv count:argc environment:environ];
#endif

#ifdef DEBUG
    [[NSNotificationCenter defaultCenter] addObserver:foo
	selector:@selector(printNotification:) name:nil object:nil];
#endif

    [[GTKApplication alloc] initWithArgc:&argc argv:&argv];
    [GTKApp setDelegate:foo];

    [foo newWindow:nil];
    [GTKApp reportException:[NSException exceptionWithName:@"WindowsException"
	reason:@"Just Testing..." userInfo:nil]];

    [[GTKApplication sharedApplication] run];
    [pool release];
    return 0;
}
