#import "ClientText.h"
#import "ServerText.h"
#import "TextDiff.h"
#import "RTFDChat.h"
#import <appkit/appkit.h>
#import <remote/NXProxy.h>
#import <remote/NXConnection.h>


@implementation ClientText

- initFrame:(const NXRect *)frameRect
		text:(const char *)theText alignment:(int)mode
{
	char   path[MAXPATHLEN];
	[[NXBundle bundleForClass:[RTFDChat class]]
		getPath:path forResource:"Empty.rtfd" ofType:NULL];
	
	[super initFrame:frameRect text:theText alignment:mode];
	[self openRTFDFrom:path];
	stayFirstResponder = NO;

	return self;
}

- awakeFromNib
{
	NXAtom	supportedTypes[11] = {NXFilenamePboardType,
								NXFileContentsPboardType, 
								NXSoundPboardType,
								NXPostScriptPboardType, 
								NXTIFFPboardType,
								NXColorPboardType,
								NXFontPboardType,
								NXRulerPboardType,
								NXRTFPboardType,
								NXAsciiPboardType,
								NULL};
	[self registerForDraggedTypes:supportedTypes count:10];

	return self;
}

- setStayFirstResponder:(BOOL)aFlag
{
	stayFirstResponder = aFlag;
	return self;
}

- resignFirstResponder
{
	if (stayFirstResponder)
		return nil;
	return [super resignFirstResponder];
}

- free
{
	[[serverText connectionForProxy] unregisterForInvalidationNotification:self];
	[serverText removeClientText:self];
	[NXConnection removeObject:self];
	return [super free];
}

- (oneway void)applyDifference:(bycopy TextDiff *)diff
{
	int     start, end;
	int     click;
	NXRect  oldRect;
	id      oldResponder;
	
	[window disableFlushWindow];
	oldResponder = [window firstResponder];
	if ([oldResponder respondsTo:@selector(setStayFirstResponder:)])
		[oldResponder setStayFirstResponder:YES];

/* save up the old selection */
	start = sp0.cp;
	end = spN.cp;
	click = clickCount;
	
	[superview getDocVisibleRect:&oldRect];

/* apply difference */
	[self setEditable:YES];
	[diff applyTo:self];
	[self setEditable:NO];
	[self setSel:spN.cp :spN.cp];

/* restore the old selection or scroll to visible */
	if (autoscroll)
		[self scrollSelToVisible];
	else
		[self scrollPoint:&oldRect.origin];
		
	[self setSel:start :end];
	clickCount = click;

/* we HAVE TO free diff, because it should be a copy... */
/* if we are in another task than the server, it is...  */
/* else it isn't, and the app will crash! */
	[diff free];

	if ([oldResponder respondsTo:@selector(setStayFirstResponder:)])
		[oldResponder setStayFirstResponder:NO];
	[[window reenableFlushWindow] flushWindow];
	return;
}

- (int)clickCount
{
	return clickCount;
}

- setClickCount:(int)count
{
	clickCount = count;
	return self;
}

- serverText
{
	return serverText;
}

- setServerText:aServer
{
	serverText = aServer;
	[[serverText connectionForProxy] registerForInvalidationNotification:self];
	return self;
}

- serverIsDead
{
	[[serverText connectionForProxy] unregisterForInvalidationNotification:self];
	serverText = nil;
	if ([[window delegate] clientIsDying:self])
	{
		[[[self superview] superview] free];
		return nil;
	}
	return self;
}

- (BOOL)doesAutoscroll;
{
	return autoscroll;
}

- setAutoscrollFrom:sender;
{
	autoscroll = [sender state];
	return self;
}


/********************************************/
/* NXSenderIsInvalid protocol               */
/********************************************/

- senderIsInvalid:sender
{
	return [self serverIsDead];
}

@end
