//
//  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

- (byref NSString *) passMessage:(bycopy NSString *) str;
{ // we received a message
	NSString *ret;
	NSLog(@"Responder received %@", str);
#if 0
		{
			NSConnection *c=[[NSConnection allConnections] objectAtIndex:0];
			NSLog(@"Responder connections %@", [NSConnection allConnections]);
			NSLog(@"Responder localObjects = %@", NSStringFromClass([[c localObjects] class]));
				{
					int i;
					for(i=0; i<[[c localObjects] count]; i++)
							{
								id obj=[[c localObjects] objectAtIndex:i];
								NSLog(@"[%d] %p %@", i, obj, NSStringFromClass([obj class]));
							}
				}
			NSLog(@"Responder remoteObjects = %@", NSStringFromClass([[c remoteObjects] class]));	// => NSArray - we can't send -description to all objects!
				{
					int i;
					for(i=0; i<[[c remoteObjects] count]; i++)
							{
								id obj=[[c remoteObjects] objectAtIndex:i];
								NSLog(@"[%d] %p %@", i, obj, NSStringFromClass([obj class]));
							}
				}
		}
#endif
	[[NSApp delegate] setString:str];
	ret=[NSString stringWithFormat:@"--- %@ ---", str];	// return a modified string
	NSLog(@"Responder returning %@", ret);
	return ret;
}

- (NSString *) arg0;
{
	return @"arg0";
}

- (NSString *) arg1:(NSString *) str1;
{
	return [NSString stringWithFormat:@"%@", str1];
}

- (NSString *) arg1:(NSString *) str1 arg2:(NSString *) str2;
{
	return [NSString stringWithFormat:@"%@ %@", str1, str2];
}

- (NSString *) arg1:(NSString *) str1 arg2:(NSString *) str2 arg3:(NSString *) str3;
{
	return [NSString stringWithFormat:@"%@ %@ %@", str1, str2, str3];
}

- (NSString *) arg1:(NSString *) str1 arg2:(NSString *) str2 arg3:(NSString *) str3 arg4:(NSString *) str4;
{
	return [NSString stringWithFormat:@"%@ %@ %@ %@", str1, str2, str3, str4];
}

- (NSString *) arg1:(NSString *) str1 arg2:(NSString *) str2 arg3:(NSString *) str3 arg4:(NSString *) str4 arg5:(NSString *) str5;
{
	return [NSString stringWithFormat:@"%@ %@ %@ %@ %@", str1, str2, str3, str4, str5];
}

@end

@interface Tester : NSObject <Respond>
@end

@implementation Tester

#if 0

- (NSString *) arg0;
{
	return @"arg0";
}

- (NSString *) arg1:(NSString *) str1;
{
	return [NSString stringWithFormat:@"%@", str1];
}

- (NSString *) arg1:(NSString *) str1 arg2:(NSString *) str2;
{
	return [NSString stringWithFormat:@"%@ %@", str1, str2];
}

- (NSString *) arg1:(NSString *) str1 arg2:(NSString *) str2 arg3:(NSString *) str3;
{
	return [NSString stringWithFormat:@"%@ %@ %@", str1, str2, str3];
}

- (NSString *) arg1:(NSString *) str1 arg2:(NSString *) str2 arg3:(NSString *) str3 arg4:(NSString *) str4;
{
	return [NSString stringWithFormat:@"%@ %@ %@ %@", str1, str2, str3, str4];
}

- (NSString *) arg1:(NSString *) str1 arg2:(NSString *) str2 arg3:(NSString *) str3 arg4:(NSString *) str4 arg5:(NSString *) str5;
{
	return [NSString stringWithFormat:@"%@ %@ %@ %@ %@", str1, str2, str3, str4, str5];
}

#endif

- (NSMethodSignature *) methodSignatureForSelector:(SEL) sel;
{
	NSMethodSignature *ms=[super methodSignatureForSelector:sel];
	if(!ms)
		ms=[NSMethodSignature signatureWithObjCTypes:"@0@+8:+12"];
	return ms;
}

- (void) forwardInvocation:(NSInvocation*)anInvocation
{ // handle unimplemented methods
	NSString *ret=@"result";
	[anInvocation _log:@"calling"];
	[anInvocation setReturnValue:&ret];
}

@end

@implementation AppController

- (void) setString:(NSString *) str;
{
	[result setStringValue:str];
}

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

- (void) awakeFromNib;
{
#if __mySTEP__
	NSMessagePort *port = [[[NSMessagePort alloc] init] autorelease];	// assign free IP port number
#else
	NSSocketPort *port = [[[NSSocketPort alloc] init] autorelease];	// assign free IP port number
#endif
	NSConnection *connection = [[NSConnection connectionWithReceivePort:port sendPort:nil] retain];
	NSLog(@"AppController registerAsServer connection = %@", connection);
#if __mySTEP__
	if(![[NSMessagePortNameServer sharedInstance] registerPort:port name:@"timer"])	// register without zeroconf
#else
	if(![[NSSocketPortNameServer sharedInstance] registerPort:port name:@"timer"])	// register with zeroconf
#endif
		{
		NSLog(@"SocketPort not published through ZeroConf %@", port);
		}
	else
		{
		NSLog(@"SocketPort published %@", port);
		[connection setRootObject:[[Responder alloc] init]];
		NSLog(@"Responder object set as Root");
		}
	[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(connection:) name:NSConnectionDidInitializeNotification object:nil];
#if 1
		{
			NSString *a1=@"1";
			NSString *a2=@"2";
			NSString *a3=@"3";
			NSString *a4=@"4";
			NSString *a5=@"5";
			Tester *t=[[Tester alloc] init];	// create an object (init is not declared!)
			NSLog(@"a1=%p", a1);
			NSLog(@"a2=%p", a2);
			NSLog(@"a3=%p", a3);
			NSLog(@"a4=%p", a4);
			NSLog(@"a5=%p", a5);
			NSLog(@"%@", [t methodSignatureForSelector:@selector(arg0)]);
			[t arg0];
			NSLog(@"%@", [t methodSignatureForSelector:@selector(arg1:)]);
			[t arg1:a1];
			NSLog(@"%@", [t methodSignatureForSelector:@selector(arg1:arg2:)]);
			[t arg1:a1 arg2:a2];
			NSLog(@"%@", [t methodSignatureForSelector:@selector(arg1:arg2:arg3:)]);
			[t arg1:a1 arg2:a2 arg3:a3];
			NSLog(@"%@", [t methodSignatureForSelector:@selector(arg1:arg2:arg3:arg4:)]);
			[t arg1:a1 arg2:a2 arg3:a3 arg4:a4];
			NSLog(@"%@", [t methodSignatureForSelector:@selector(arg1:arg2:arg3:arg4:arg5:)]);
			[t arg1:a1 arg2:a2 arg3:a3 arg4:a4 arg5:a5];
		}
#endif
}

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

- (void) start:(id) sender
{ // start connection and timer
#if __mySTEP__
	NSPort *port = [[NSMessagePortNameServer sharedInstance] portForName:@"timer"];
#else
	NSPort *port = [[NSSocketPortNameServer sharedInstance] portForName:@"timer" host:@"*"];
#endif
	NSConnection *connection = [NSConnection connectionWithReceivePort:nil sendPort:port];
	if(!connection)
		{
		NSLog(@"Failed to connect");
		return;
		}
	NSLog(@"AppController connected. Getting root proxy.");
	rootProxy=[connection rootProxy];
	NSLog(@"AppController retaining %@", rootProxy);
	[rootProxy retain];
	NSLog(@"AppController setting root proxy Protocol.");
	[rootProxy setProtocolForProxy:@protocol(Respond)];
	NSLog(@"AppController connectToServer rootProxy = %@", rootProxy);
#if 1
	NSLog(@"  Responder signature passMessage: %@", [Responder instanceMethodSignatureForSelector:@selector(passMessage:)]);
	NSLog(@"  Responder signature arg1:arg2:arg3: %@", [Responder instanceMethodSignatureForSelector:@selector(arg1:arg2:arg3:)]);
	NSLog(@"  Responder signature arg1:arg2:arg3:arg4:arg5: %@", [Responder instanceMethodSignatureForSelector:@selector(arg1:arg2:arg3:arg4:arg5:)]);

	NSLog(@"  rootProxy signature passMessage: %@", [rootProxy methodSignatureForSelector:@selector(passMessage:)]);
	NSLog(@"  rootProxy signature arg1:arg2:arg3: %@", [rootProxy methodSignatureForSelector:@selector(arg1:arg2:arg3:)]);
	NSLog(@"  rootProxy signature arg1:arg2:arg3:arg4:arg5: %@", [rootProxy methodSignatureForSelector:@selector(arg1:arg2:arg3:arg4:arg5:)]);
#endif
#if 1
	NSLog(@"AppController get root proxy again");
	NSLog(@"  %@", [connection rootProxy]);
#endif
#if 1
	NSLog(@"AppController get root proxy a third time");
	NSLog(@"  %@", [connection rootProxy]);
#endif
	NSLog(@"AppController start timer");
	[NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(timeout:) userInfo:nil repeats:YES];
#if 1
	NSLog(@"AppController localObjects = %@", NSStringFromClass([[connection localObjects] class]));
		{
			int i;
			for(i=0; i<[[connection localObjects] count]; i++)
					{
						id obj=[[connection localObjects] objectAtIndex:i];
						NSLog(@"[%d] %p %@", i, obj, NSStringFromClass([obj class]));
					}
		}
	NSLog(@"AppController remoteObjects = %@", NSStringFromClass([[connection remoteObjects] class]));	// => NSArray - we can't send -description to all objects!
		{
			int i;
			for(i=0; i<[[connection remoteObjects] count]; i++)
					{
						id obj=[[connection remoteObjects] objectAtIndex:i];
						NSLog(@"[%d] %p %@", i, obj, NSStringFromClass([obj class]));
					}
		}
#endif
}

- (void) timeout:(NSTimer *) timer;
{
	NSString *r=[[NSDate date] description];
	NSLog(@"AppController timeout - passMessage: %@", r);
	r=[rootProxy passMessage:r];	// send current date as string
	NSLog(@"AppController passMessage result = %p", r);
	NSLog(@"  object %@", r);
	[result2 setStringValue:r];
}

@end
