/*	This file is part of the XText package (version 0.8)
	Mike Dixon, April 1992
	
	Copyright (c) 1992 Xerox Corporation.  All rights reserved.

	Use and copying of this software and preparation of derivative works based
	upon this software are permitted.  This software is made available AS IS,
	and Xerox Corporation makes no warranty about the software or its
	performance.
*/

#import "XText0.h"
#import "XTAction.h"
#import "ErrorStream.h"
#import <objc/objc.h>
#import <appkit/Window.h>
#import <appkit/publicWraps.h>

@implementation XText0

struct WindowGuts { @defs(Window); }; 

/*	everything except the setInitialAction/setErrorStream is copied straight
	out of Window's getFieldEditor:for: method
*/

+ newFieldEditorFor:win initialAction:action estream:errs
{
	id editor = nil;
	
	if ([win isKindOf: [Window class]]) {
		editor = ((struct WindowGuts *)win)->fieldEditor;
		if (editor == nil) {
			editor = [[self allocFromZone:[win zone]] init];
			[editor setCharFilter: &NXFieldFilter];
			[editor setSelectable: YES];
			[editor setFontPanelEnabled: NO];
			[editor setInitialAction:action];
			if (errs)
				[editor setErrorStream:errs];
			((struct WindowGuts *)win)->fieldEditor = editor;
		}
	}
	return editor;
}

- initFrame:(const NXRect *)frameRect text:(const char *)theText
	alignment:(int)mode
{
	[super initFrame:frameRect text:theText alignment:mode];
	nextAction = nil;
	initialAction = nil;
	errorStream = [ErrorStream default];
	return self;
}

/*	We want to make sure that unrecognized messages are reported nicely,
	since it's easy to generate them while your experimenting.
*/

- doesNotRecognize:(SEL)sel
{
	char msg[100];

	sprintf(msg, "No method for %.48s on this text object", sel_getName(sel));
	[errorStream report: msg];
	return self;
}

/*	Egregious paranoia: don't set the error stream to something that can't
	report errors...
*/

- setErrorStream:errs
{
	if ([errs respondsTo: @selector(report:)])
		errorStream = errs;
	else
		[errorStream report:"Invalid argument to setErrorStream:"];
	return self;
}

- errorStream
{
	return errorStream;
}

- setInitialAction:action
{
	initialAction = nextAction = action;
	return self;
}

- initialAction
{
	return initialAction;
}

- setNextAction:action
{
	nextAction = action;
	return self;
}

- keyDown:(NXEvent *)event
{
	id temp;

	temp = nextAction;
	nextAction = initialAction;
	if (temp) {
		temp = [temp applyTo:self event:event];
		if (vFlags.disableAutodisplay) {
			[self setAutodisplay:YES];
			[self display];
		}
		if (sp0.cp == spN.cp)
			[self setSel:sp0.cp :sp0.cp];	// hack to make caret reappear
	}
	return temp ? self : [super keyDown:event];
}

- unboundKey
{
	NXBeep();
	return self;
}

- disableAutodisplay
{
	// There seems to be a bug with turning off autodisplay in text fields,
	// so try to avoid doing it.
	if (charFilterFunc != &NXFieldFilter)
		[self setAutodisplay:NO];
	return self;
}

@end
