#import "TalkController.h"
#import "NetTalkThinker.h"
#import <appkit/appkit.h>

@implementation TalkController

+ newFromNib
{
	NXRunLocalizedAlertPanel(NULL, "Alert", "TALKPROTO", "OK", NULL, NULL);
	return nil;
}

- init
{
	[super init];
	clientTable = [[HashTable alloc] initKeyDesc:"*" valueDesc:"@" capacity:0];
	codeSet = NO;
	topic = NULL;
	return self;
}

- free
{
	if (topic)
		free(topic);
	[clientTable empty];
	[clientTable free];
	return [super free];
}

- setup
{
	return self;
}

- (char *)keyFor:(const char *)aClientUName :(const char *)aCode
{
	char   *key;
//#define DEBUGMALLOC
#ifdef DEBUGMALLOC
	fprintf(stderr, "keyFor:%s :%s ", aClientUName, aCode);
#endif	
	key = malloc(strlen(aClientUName)+strlen(aCode)+2);
#ifdef DEBUGMALLOC
	fprintf(stderr, "successful.\n");
#endif	
	sprintf(key, "%s:%s", aClientUName, aCode);  
	return key;
}


- (BOOL)clientIsDying:sender
{
	return NO;
}


- (View *)addClientViewWith:(View *)aDocument
		from:(const char *)aClientUName
		forCode:(const char *)aCode
{
	return nil;
}


- (const char *)connectionCode
{	
	if (!codeSet)
	{
		codeSet = YES;
		sprintf(connectionCode, "NTK%ux", (unsigned int)self);
	}
	return connectionCode;
}


- setConnectionCode:(const char*)aCode
{
	NXBeep();
	NXBeep();
	codeSet = YES;
	strcpy(connectionCode, aCode);
	return self;
}

- (const char *)connectionName
{
	return connectionUName;
}

- setConnectionName:(const char*)name
{
	NXBeep();
	NXBeep();
	strcpy(connectionUName, name);
	return self;
}

- markClientUNameInvited:(const char *)aClientUName
		forCode:(const char *)aCode
{
	char *key = [self keyFor:aClientUName :aCode];
	[clientTable insertKey:key value:self];
	return self;
}

- (BOOL)hasClientUName:(const char *)aClientUName
		andCode:(const char *)aCode
{
	char *key = [self keyFor:aClientUName :aCode];
	id value = [clientTable valueForKey:key];
	free(key);
	return (value != nil);
}

- viewForClientUName:(const char *)aClientUName
		andCode:(const char *)aCode
{
	char *key = [self keyFor:aClientUName :aCode];
	id value = [clientTable valueForKey:key];
	free(key);
	return value;
}

- removeClientUName:(const char *)aClientUName
		forCode:(const char *)aCode
{
	char *key = [self keyFor:aClientUName :aCode];
	[clientTable removeKey:key];
	free(key);
	return self;
}


- (const char *)topic
{
	return topic;
}

- setTopic:(const char*)aTopic
{
	if (topic)
		free(topic);
	topic = NULL;
	if (aTopic)
	{
		topic = malloc(strlen(aTopic)+1);
		strcpy(topic, aTopic);
	}
	[[document window] setTitle:topic];
	return self;
}

- (View *)document
{
	return document;
}

- close:sender
{
	if ([[document window] isDocEdited])
	{
		switch (NXRunLocalizedAlertPanel(NULL
			, "Close"
			, "ReallyCloseConnections"
			, "Close", "Don't close", 0))
		{
		case NX_ALERTDEFAULT:
			[[document window] setDocEdited:NO];
			break;
		default:
			return nil;
		}
	}
	[[[NXApp delegate] client]
		sendDisconnectTo:connectionUName forCode:connectionCode];
	[[document window] close];

	return self;
}

- (BOOL)windowIsStayAbove
{
	id    window = [document window];
	int   number = [window windowNum];
	int   level;
	
	PScurrentwindowlevel(number, &level);
	return (level == NX_FLOATINGLEVEL);
}

- toggleStayAbove:sender
{
	id    window = [document window];
	int   number = [window windowNum];
	int   level;
	
	PScurrentwindowlevel(number, &level);
	if (level == NX_FLOATINGLEVEL)
	{
		PSsetwindowlevel(NX_NORMALLEVEL, number);
	}
	else
	{
		PSsetwindowlevel(NX_FLOATINGLEVEL, number);
	}
	return self;
}


@end


@implementation TalkController(WindowDelegate)

- windowWillClose:sender
{
	if (![self close:sender])
		return nil;
	[sender setDelegate:nil];
	return [self free];
}

@end
