#import "DictionaryViewerController.h"

@implementation DictionaryViewerController
CPhidgetDictionaryHandle dict;
CPhidgetDictionaryListenerHandle listener = NULL;
	
int
event_handler(CPhidgetDictionaryHandle dict, void *context, const char *key, const char *val, CPhidgetDictionary_keyChangeReason reason)
{
	KeyInfo *temp = [KeyInfo alloc];
	[temp setKey:[NSString stringWithCString:key]];
	[temp setVal:[NSString stringWithCString:val]];
	[(id)context gotAKey:temp:reason];
	return 0;
}

int gotConnect(CPhidgetDictionaryHandle dict, void *context) {
	[(id)context serverConnected];
	return 0;
}

int gotDisconnect(CPhidgetDictionaryHandle dict, void *context) {
	[(id)context serverDisconnected];
	return 0;
}

int gotError(CPhidgetDictionaryHandle phid, void *context, int errcode, const char *error) {
	NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
	NSRunAlertPanel(@"Received an Asynchronous Error", [NSString stringWithFormat:@"Code: %d\n%s", errcode, error], nil, nil, nil);
	[pool release];
	CPhidgetDictionary_close(dict);
	return 0;
}

- (IBAction)guiAddKey:(id)sender
{
	NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
	CPhidgetDictionary_addKey(dict, [[keyField stringValue] UTF8String], [[valueField stringValue] UTF8String], TRUE);
	[pool release];
}

- (IBAction)DelKey:(id)sender
{
	NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
	CPhidgetDictionary_removeKey(dict, [[keyField stringValue] UTF8String]);
	[pool release];
}

- (IBAction)chooseOpenType:(id)sender
{
	if([[sender titleOfSelectedItem] isEqualToString:@"Address, Port"])
	{
		[addressText setStringValue:@"Address:"];
		[addressField setStringValue:@"localhost"];
		[portText setHidden:FALSE];
		[portField setHidden:FALSE];
	}
	else if([[sender titleOfSelectedItem] isEqualToString:@"Server ID"])
	{
		[addressText setStringValue:@"ServerID:"];
		[addressField setStringValue:@""];
		[portText setHidden:TRUE];
		[portField setHidden:TRUE];
	}
}

- (void)gotAKey:(KeyInfo *)keyInfo:(CPhidgetDictionary_keyChangeReason)reason
{
	NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
	if(reason == PHIDGET_DICTIONARY_ENTRY_REMOVING)
		[keys removeObject: keyInfo];
	else
	{
		[keys removeObject: keyInfo];
		[keys addObject: keyInfo];
	}
	
	[keys sortUsingSelector:@selector(compareKey:)];
	
	[keyInfo retain];
    [treeView reloadData];
	[pool release];
}

- (IBAction)connect:(id)sender
{
	if([[connectButton title] isEqualToString:@"Connect"])
	{	
		[statusText setStringValue:@"Trying to Connect..."];
		if([[openTypeComboBox titleOfSelectedItem] isEqualToString:@"Address, Port"])
			CPhidgetDictionary_openRemoteIP(dict, [[addressField stringValue] UTF8String], [portField intValue], NULL);
		if([[openTypeComboBox titleOfSelectedItem] isEqualToString:@"Server ID"])
		{
			if(![[addressField stringValue] UTF8String][0])
				CPhidgetDictionary_openRemote(dict, NULL, NULL);
			else
				CPhidgetDictionary_openRemote(dict, [[addressField stringValue] UTF8String], NULL);
		}
		[connectButton setTitle:@"Disconnect"];
	}
	else if([[connectButton title] isEqualToString:@"Disconnect"])
	{
		[connectButton setTitle:@"Connect"];
		[self serverDisconnected];
		CPhidgetDictionary_close(dict);
	}
}

- (void)serverConnected
{
	CPhidgetDictionary_set_OnKeyChange_Handler(dict, &listener, ".*", event_handler, self);
	[statusText setStringValue:@"Connected"];
	[valueField setEnabled:TRUE];
	[keyField setEnabled:TRUE];
	[addButton setEnabled:TRUE];
	[deleteButton setEnabled:TRUE];
}

- (void)serverDisconnected
{
	if(listener)
	{
		CPhidgetDictionary_remove_OnKeyChange_Handler(listener);
		listener = NULL;
	}
	if([[connectButton title] isEqualToString:@"Connect"])
		[statusText setStringValue:@"Not Connected"];
	else if([[connectButton title] isEqualToString:@"Disconnect"])
		[statusText setStringValue:@"Trying to Connect..."];
	[keys removeAllObjects];
    [treeView reloadData];
	[valueField setEnabled:FALSE];
	[keyField setEnabled:FALSE];
	[addButton setEnabled:FALSE];
	[deleteButton setEnabled:FALSE];
}

/*
 * This gets run when the GUI gets displayed
 */
- (void)awakeFromNib
{
	[mainWindow setDelegate:self];
	// Create the storage our table will use.
    keys = [[NSMutableArray alloc] init];
    // Be the data source... 
    [treeView setDataSource:self];
	
	CPhidgetDictionary_create(&dict);
	
	CPhidgetDictionary_set_OnServerConnect_Handler(dict, gotConnect, self);
	CPhidgetDictionary_set_OnServerDisconnect_Handler(dict, gotDisconnect, self);
	CPhidgetDictionary_set_OnError_Handler(dict, gotError, self);
}

- (void)windowWillClose:(NSNotification *)aNotification {
	CPhidgetDictionary_close(dict);
	CPhidgetDictionary_delete(dict);
	dict = 0;
	[NSApp terminate:self];
}

// ---------------------------------------------------------
//  Data source methods
// ---------------------------------------------------------

- (int)numberOfRowsInTableView:(NSTableView *)tv {
    return [keys count];
}

- (id)tableView:(NSTableView *)tv objectValueForTableColumn:(NSTableColumn *)tc row:(int)row {
	NSParameterAssert(row >= 0 && row < [keys count]);
    if ([[tc identifier] isEqualToString:@"Key"]) {
        return [[keys objectAtIndex:row] getKey];
    } else if ([[tc identifier] isEqualToString:@"Value"]) {
        return [[keys objectAtIndex:row] getVal];
    } else {
        return NULL;
    }
}

- (void)tableView:(NSTableView *)tv
    setObjectValue:objectValue
    forTableColumn:(NSTableColumn *)tc
    row:(int)row
{
	char buf[1024];
    KeyInfo *keyInfo = [keys objectAtIndex:row];
	sprintf(buf, "%s",([[keyInfo getKey] UTF8String]));
	printf("set: %s -> %s\n",buf,[objectValue UTF8String]);
	
	CPhidgetDictionary_addKey(dict, buf, [objectValue UTF8String], TRUE);
	
	return;
	
	NSParameterAssert(row >= 0 && row < [keys count]);
    if ([[tc identifier] isEqualToString:@"Key"]) {
        [[keys objectAtIndex:row] setKey: objectValue];
    } else {
        [[keys objectAtIndex:row] setVal: objectValue];
    }
}


@end
