/*
**	LispApp.m
**	Appkit-based front-end for a separate lisp process.
**	Lee Boynton, NeXT, Inc., 1989
*/

#import <string.h>
#import <stdio.h>
#import <defaults/defaults.h>
#import <appkit/Listener.h>
#import <appkit/Window.h>
#import "LispListener.h"
#import "LispApp.h"

/*
** This new Listener responds to the "appEvaluate:" message, which can be
** sent from any speaker (in another process, for example). See the 
** 'lispEvaluate' example of sending this message. This appkit 'Listener'
** subclass should not be confused with the Lisp 'Listener', a completely
** different animal.
*/

@interface  LispAppListener : Listener {}
- (int)appEvaluate:(char *)theString;
@end

@implementation LispAppListener
static NXRemoteMethod evalMethod;
-(int)appEvaluate:(char *)theString
{
    id _NXd;
    int r;
    if (_NXd = NXResponsibleDelegate(self, @selector(appEvaluate:))) {
	[_NXd appEvaluate:theString];
	return 0;
    } else
	return -1;
}
- (NXRemoteMethod *)remoteMethodFor:(SEL)aSel
{
    evalMethod.key = @selector(appEvaluate:);
    evalMethod.types = "c";
    if (evalMethod.key == aSel)
	return &evalMethod;
    else
	return [super remoteMethodFor:aSel];
}

- (int) performRemoteMethod : (NXRemoteMethod *) method
                  paramList : (NXParamValue *) paramList;
{
    if (method == &evalMethod)
	return [self appEvaluate:paramList[0].bval.p];
    else
	return [super performRemoteMethod:method paramList:paramList];
}
@end

/*
**
*/

@implementation LispApp

+ initialize
{
    const NXDefaultsVector LispDefaults = {
	{ "LispImage", "cl" },
	{ NULL, NULL }
    };
    NXRegisterDefaults("Lisp", LispDefaults);
    return self;
}

+ new
{
    self = [super new];
    [self setAppListener:[LispAppListener new]];
    return self;
}

- setListener:anObject
{
    listener = anObject;
    return self;
}

- free
{
    [listener free];
    return [super free];
}

- windowWillClose:sender
{
    extern exit();
    [listener removeFromSuperview];
    [listener free];
    exit(0);
}

- (int)appOpenFile:(const char *)path type:(const char *)type
{
    if (type && (!strcmp(type, "lisp") || !strcmp(type, "fasl"))) {
	char buf[1024];
	sprintf(buf,"(load \"%s\")\n",path);
	[listener evaluate:buf];
	return YES;
    } else
	return NO;
}

- (BOOL)appAcceptsAnotherFile:sender
{
    return YES;
}

- (int)appEvaluate:(char *)theString
{
    [listener evaluate:theString];
    return 0;
}

- (int)activateSelf:(BOOL)flag
{
    [[listener window] makeKeyAndOrderFront:self];
    return [super activateSelf:flag];
}


@end





