//
//  AppController.m
//  DO
//
//  Created by Dr. H. Nikolaus Schaller on 23.10.06.
//  Copyright 2006 __MyCompanyName__. All rights reserved.
//

#import "AppController.h"

@interface Responder : NSObject <Respond>
@end

@implementation Responder

- (oneway void) passMessage:(NSString *) str;
{ // we received a message
	[[[[NSApp delegate] valueForKey:@"server"] textStorage] appendAttributedString:[[[NSAttributedString alloc] initWithString:str] autorelease]];	// show what we have received on server side
	abort();
}

- (bycopy NSString *) pleaseRespond;
{
	NSString *str=[NSString stringWithFormat:@"This is %@ at %@\n", [[NSHost currentHost] name], [NSDate date]];
	NSLog(@"connections=%@", [NSConnection allConnections]);
	abort();
	return str;
}

@end

@implementation AppController

- (BOOL) applicationShouldTerminateAfterLastWindowClosed:(NSApplication *)theApplication
{
	return YES;
}

- (void) awakeFromNib;
{
	[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(connection:) name:NSConnectionDidInitializeNotification object:nil];
}

- (void) connection:(NSNotification *) notif;
{
	NSLog(@"new connection: %@", notif);
}

- (IBAction) registerAsServer:(id) sender;
{
	if([[sender title] length] > 0)
		{
		NSSocketPort *port = [[[NSSocketPort alloc] init] autorelease];	// assign free IP port number
		NSConnection *connection = [[NSConnection connectionWithReceivePort:port sendPort:nil] retain];
		NSLog(@"registerAsServer connection = %@", connection);
		if(![[NSSocketPortNameServer sharedInstance] registerPort:port name:[sender title]])	// register with zeroconf
			{
			[[result textStorage] appendAttributedString:[[[NSAttributedString alloc] initWithString:@"Not published\n"] autorelease]];
			NSLog(@"SocketPort not published through ZeroConf %@", port);
			}
		else
			{
			NSLog(@"SocketPort published %@", port);
			[connection setRootObject:[[Responder alloc] init]];
			NSLog(@"Responder object set as Root");
			}
		}
}

- (IBAction) registerAsMSGPortServer:(id) sender;
{
	if([[sender title] length] > 0)
		{
		NSMessagePort *port = [[[NSMessagePort alloc] init] autorelease];	// create new message port
		NSConnection *connection = [[NSConnection connectionWithReceivePort:port sendPort:nil] retain];	// uses same port to send and receive
		NSLog(@"registerAsMSGPortServer connection = %@", connection);
		if(![[NSMessagePortNameServer sharedInstance] registerPort:port name:[sender title]])	// register as named message port
			{
			[[result textStorage] appendAttributedString:[[[NSAttributedString alloc] initWithString:@"Not published\n"] autorelease]];
			NSLog(@"Message port not published %@", port);
			}
		else
			{
			NSLog(@"MessagePort published %@", port);
			[connection setRootObject:[[Responder alloc] init]];
			NSLog(@"Responder object set as Root");
#if 0
			{
				NSConnection *c2=[NSConnection connectionWithReceivePort:nil sendPort:port];	// should allocate a fresh receive port
				NSLog(@"a=%@ root=%@", c2, [c2 rootObject]);
				c2=[NSConnection connectionWithReceivePort:port sendPort:[[[NSMessagePort alloc] init] autorelease]];	// should be a subconnection
				NSLog(@"b=%@ root=%@", c2, [c2 rootObject]);
				[connection setRootObject:self];
				NSLog(@"c1 root=%@", [connection rootObject]);
				NSLog(@"c2 root=%@", [c2 rootObject]);	// ok, sharing is done only when creating the connection!
				c2=[NSConnection connectionWithReceivePort:port sendPort:nil];
				NSLog(@"c=%@ root=%@", c2, [c2 rootObject]);	// returns a new reference to connection
			}
#endif
			}
		}
}

- (BOOL) connect:(NSPort *) port title:(NSString *) title;
{
	NSConnection *connection;
	NSLog(@"connectToServer port = %@", port);
	connection = [NSConnection connectionWithReceivePort:nil sendPort:port];
	NSLog(@"connectToServer connection = %@", connection);
	if(!connection)
		{
		[[result textStorage] appendAttributedString:[[[NSAttributedString alloc] initWithString:[NSString stringWithFormat:@"could not connect to %@\n", title]] autorelease]];
		NSLog(@"Failed to connect");
		return NO;
		}
	NSLog(@"Connected. Getting root proxy.");
	//		rootProxy=[[connection rootProxy] retain];
	rootProxy=[connection rootProxy];
	NSLog(@"Retaining %@", rootProxy);
	[rootProxy retain];
	NSLog(@"Setting root proxy Protocol.");
	[rootProxy setProtocolForProxy:@protocol(Respond)];
	NSLog(@"connectToServer rootProxy = %@", rootProxy);
#if 1
	NSLog(@"get again");
	[connection rootProxy];
#endif
	return YES;
}

- (IBAction) connectToServer:(id) sender;
{
	NSLog(@"connectToServer %@", sender);
	if([[sender title] length] > 0)
		{
		NSPort *port = [[NSSocketPortNameServer sharedInstance] portForName:[sender title] host:@"*"];
		if(![self connect:port title:[sender title]])
			[sender selectItemAtIndex:0];
		}
}

- (IBAction) connectToMSGServer:(id) sender;
{
	NSLog(@"connectToMSGServer %@", sender);
	if([[sender title] length] > 0)
		{
		NSPort *port = [[NSMessagePortNameServer sharedInstance] portForName:[sender title] host:@""];
		if(![self connect:port title:[sender title]])
			[sender selectItemAtIndex:0];
		}
}

- (IBAction) sendMessage:(id) sender;
{
	if(!rootProxy)
		{
		[[result textStorage] appendAttributedString:[[[NSAttributedString alloc] initWithString:@"Not connected\n"] autorelease]];
		return;
		}
	[rootProxy passMessage:[NSString stringWithFormat:@"%@\n", [message stringValue]]];
	[message setStringValue:@""];
}

- (IBAction) getResponse:(id) sender;
{
	if(!rootProxy)
		{
		[[result textStorage] appendAttributedString:[[[NSAttributedString alloc] initWithString:@"Not connected\n"] autorelease]];
		return;
		}
	[[result textStorage] appendAttributedString:[[[NSAttributedString alloc] initWithString:[rootProxy pleaseRespond]] autorelease]];
}

@end
