#import "AppController.h"
#import "PreferenceController.h"
#import "CLIPSTerminalController.h"
#import "CLIPSAgendaController.h"
#import "CLIPSFactController.h"
#import "CLIPSInstanceController.h"
#import "CLIPSConstructInspectorController.h"
#import "CLIPSEnvironment.h"
#import <CLIPS/clips.h>
@implementation AppController
@synthesize mainEnvironment, mainTerminal, constructInspectorText;
+ (void) initialize
{
NSDictionary *appDefaults;
NSUserDefaults *defaults;
NSFont *theFont;
theFont = [NSFont userFixedPitchFontOfSize:0.0];
appDefaults =
[NSDictionary dictionaryWithObjectsAndKeys:
[theFont fontName], @"editorTextFontName",
[NSNumber numberWithDouble:[theFont pointSize]], @"editorTextFontSize",
[NSNumber numberWithBool:YES], @"editorBalanceParens",
[theFont fontName], @"dialogTextFontName",
[NSNumber numberWithDouble:[theFont pointSize]], @"dialogTextFontSize",
[NSNumber numberWithBool:YES], @"dialogBalanceParens",
nil];
defaults = [NSUserDefaults standardUserDefaults];
[defaults registerDefaults: appDefaults];
[[NSUserDefaultsController sharedUserDefaultsController] setInitialValues:appDefaults];
}
- (void) awakeFromNib
{
factControllers = [[NSMutableArray alloc] init];
instanceControllers = [[NSMutableArray alloc] init];
agendaControllers = [[NSMutableArray alloc] init];
fileOpenLock = [[NSLock alloc] init];
}
- (void) setWatchMenuItemState: (NSMenuItem *) menuItem forItem: (WatchItem) watchItem
{
if ([mainEnvironment getWatchState: watchItem])
{ [menuItem setState: NSOnState]; }
else
{ [menuItem setState: NSOffState]; }
}
- (BOOL) validateMenuItem: (NSMenuItem *) menuItem
{
if ([menuItem action] == @selector(watchCompilations:))
{ [self setWatchMenuItemState: menuItem forItem: COMPILATIONS]; }
if ([menuItem action] == @selector(watchStatistics:))
{ [self setWatchMenuItemState: menuItem forItem: STATISTICS]; }
if ([menuItem action] == @selector(watchFacts:))
{ [self setWatchMenuItemState: menuItem forItem: FACTS]; }
if ([menuItem action] == @selector(watchRules:))
{ [self setWatchMenuItemState: menuItem forItem: RULES]; }
if ([menuItem action] == @selector(watchActivations:))
{ [self setWatchMenuItemState: menuItem forItem: ACTIVATIONS]; }
if ([menuItem action] == @selector(watchFocus:))
{ [self setWatchMenuItemState: menuItem forItem: FOCUS]; }
if ([menuItem action] == @selector(watchGlobals:))
{ [self setWatchMenuItemState: menuItem forItem: GLOBALS]; }
if ([menuItem action] == @selector(watchDeffunctions:))
{ [self setWatchMenuItemState: menuItem forItem: DEFFUNCTIONS]; }
if ([menuItem action] == @selector(watchGenericFunctions:))
{ [self setWatchMenuItemState: menuItem forItem: GENERIC_FUNCTIONS]; }
if ([menuItem action] == @selector(watchMethods:))
{ [self setWatchMenuItemState: menuItem forItem: METHODS]; }
if ([menuItem action] == @selector(watchInstances:))
{ [self setWatchMenuItemState: menuItem forItem: INSTANCES]; }
if ([menuItem action] == @selector(watchSlots:))
{ [self setWatchMenuItemState: menuItem forItem: SLOTS]; }
if ([menuItem action] == @selector(watchMessageHandlers:))
{ [self setWatchMenuItemState: menuItem forItem: MESSAGE_HANDLERS]; }
if ([menuItem action] == @selector(watchMessages:))
{ [self setWatchMenuItemState: menuItem forItem: MESSAGES]; }
if (([menuItem action] == @selector(haltRules:)) ||
([menuItem action] == @selector(haltExecution:)))
{
if ([[mainEnvironment executionLock] tryLock])
{
[[mainEnvironment executionLock] unlock];
return NO;
}
else
{ return YES; }
}
else if (([menuItem action] == @selector(clear:)) ||
([menuItem action] == @selector(loadConstructs:)) ||
([menuItem action] == @selector(loadBatch:)) ||
([menuItem action] == @selector(setDirectory:)) ||
([menuItem action] == @selector(reset:)) ||
([menuItem action] == @selector(run:)) ||
([menuItem action] == @selector(clearScrollback:)))
{
if ([[mainEnvironment executionLock] tryLock])
{
[[mainEnvironment executionLock] unlock];
return YES;
}
else
{ return NO; }
}
return YES;
}
- (void) addFactController: (CLIPSFactController *) theController
{
[factControllers addObject: theController];
}
- (void) removeFactController: (CLIPSFactController *) theController
{
[factControllers removeObject: theController];
}
- (void) addInstanceController: (CLIPSInstanceController *) theController
{
[instanceControllers addObject: theController];
}
- (void) removeInstanceController: (CLIPSInstanceController *) theController
{
[instanceControllers removeObject: theController];
}
- (void) addAgendaController: (CLIPSAgendaController *) theController
{
[agendaControllers addObject: theController];
}
- (void) removeAgendaController: (CLIPSAgendaController *) theController
{
[agendaControllers removeObject: theController];
}
- (IBAction) clear: (id) sender
{
[mainEnvironment doCommand: @"(clear)\n"];
}
- (IBAction) loadConstructs: (id) sender
{
[mainTerminal loadConstructs: self];
}
- (IBAction) loadBatch: (id) sender
{
[mainTerminal loadBatch: self];
}
- (IBAction) setDirectory: (id) sender
{
[mainTerminal setDirectory: self];
}
- (IBAction) reset: (id) sender
{
[mainEnvironment doCommand: @"(reset)\n"];
}
- (IBAction) run: (id) sender
{
[mainEnvironment doCommand: @"(run)\n"];
}
- (IBAction) haltRules: (id) sender
{
SetHaltRules([mainEnvironment environment],true);
}
- (IBAction) haltExecution: (id) sender
{
SetHaltCommandLoopBatch([mainEnvironment environment],true);
SetHaltExecution([mainEnvironment environment],true);
}
- (IBAction) clearScrollback: (id) sender
{
[mainTerminal clearScrollback: self];
}
- (IBAction) showPreferencePanel: (id) sender
{
if (! preferenceController)
{ preferenceController = [[PreferenceController alloc] init]; }
[preferenceController showPanel];
}
- (void) toggleWatchItem: (WatchItem) watchItem
{
[mainEnvironment setWatchState: watchItem
toValue: ! [mainEnvironment getWatchState: watchItem]];
}
- (void) setWatchState: (WatchItem) watchItem toValue: (bool) value
{
[mainEnvironment setWatchState: watchItem
toValue: value];
}
- (IBAction) watchCompilations: (id) sender
{
[self toggleWatchItem: COMPILATIONS];
}
- (IBAction) watchStatistics: (id) sender
{
[self toggleWatchItem: STATISTICS];
}
- (IBAction) watchFacts: (id) sender
{
[self toggleWatchItem: FACTS];
}
- (IBAction) watchRules: (id) sender
{
[self toggleWatchItem: RULES];
}
- (IBAction) watchActivations: (id) sender
{
[self toggleWatchItem: ACTIVATIONS];
}
- (IBAction) watchFocus: (id) sender
{
[self toggleWatchItem: FOCUS];
}
- (IBAction) watchGlobals: (id) sender
{
[self toggleWatchItem: GLOBALS];
}
- (IBAction) watchDeffunctions: (id) sender
{
[self toggleWatchItem: DEFFUNCTIONS];
}
- (IBAction) watchGenericFunctions: (id) sender
{
[self toggleWatchItem: GENERIC_FUNCTIONS];
}
- (IBAction) watchMethods: (id) sender
{
[self toggleWatchItem: METHODS];
}
- (IBAction) watchInstances: (id) sender
{
[self toggleWatchItem: INSTANCES];
}
- (IBAction) watchSlots: (id) sender
{
[self toggleWatchItem: SLOTS];
}
- (IBAction) watchAll: (id) sender
{
[self setWatchState: COMPILATIONS toValue: YES];
[self setWatchState: FACTS toValue: YES];
[self setWatchState: RULES toValue: YES];
[self setWatchState: STATISTICS toValue: YES];
[self setWatchState: ACTIVATIONS toValue: YES];
[self setWatchState: FOCUS toValue: YES];
[self setWatchState: GLOBALS toValue: YES];
[self setWatchState: DEFFUNCTIONS toValue: YES];
[self setWatchState: GENERIC_FUNCTIONS toValue: YES];
[self setWatchState: METHODS toValue: YES];
[self setWatchState: INSTANCES toValue: YES];
[self setWatchState: SLOTS toValue: YES];
[self setWatchState: MESSAGE_HANDLERS toValue: YES];
[self setWatchState: MESSAGES toValue: YES];
}
- (IBAction) watchNone: (id) sender
{
[self setWatchState: COMPILATIONS toValue: NO];
[self setWatchState: FACTS toValue: NO];
[self setWatchState: RULES toValue: NO];
[self setWatchState: STATISTICS toValue: NO];
[self setWatchState: ACTIVATIONS toValue: NO];
[self setWatchState: FOCUS toValue: NO];
[self setWatchState: GLOBALS toValue: NO];
[self setWatchState: DEFFUNCTIONS toValue: NO];
[self setWatchState: GENERIC_FUNCTIONS toValue: NO];
[self setWatchState: METHODS toValue: NO];
[self setWatchState: INSTANCES toValue: NO];
[self setWatchState: SLOTS toValue: NO];
[self setWatchState: MESSAGE_HANDLERS toValue: NO];
[self setWatchState: MESSAGES toValue: NO];
}
- (IBAction) watchMessageHandlers: (id) sender
{
[self toggleWatchItem: MESSAGE_HANDLERS];
}
- (IBAction) watchMessages: (id) sender
{
[self toggleWatchItem: MESSAGES];
}
- (IBAction) agendaBrowser: (id) sender
{
CLIPSAgendaController *theController;
theController = [[CLIPSAgendaController alloc] init];
[self addAgendaController: theController];
[theController showWindow: self];
}
- (IBAction) factBrowser: (id) sender
{
CLIPSFactController *theController;
theController = [[CLIPSFactController alloc] init];
[self addFactController: theController];
[theController showWindow: self];
}
- (IBAction) instanceBrowser: (id) sender
{
CLIPSInstanceController *theController;
theController = [[CLIPSInstanceController alloc] init];
[self addInstanceController: theController];
[theController showWindow: self];
}
- (IBAction) constructInspector: (id) sender
{
if (! constructInspectorController)
{ constructInspectorController = [[CLIPSConstructInspectorController alloc] init]; }
[constructInspectorController showPanel];
}
- (IBAction) showCLIPSDocumentation: (id) sender
{
[[NSWorkspace sharedWorkspace]
openURL: [NSURL URLWithString: @"http://www.clipsrules.net/?q=Documentation"]];
}
- (IBAction) showCLIPSHomePage: (id) sender
{
[[NSWorkspace sharedWorkspace]
openURL: [NSURL URLWithString: @"http://www.clipsrules.net/"]];
}
- (IBAction) showCLIPSExamples: (id) sender
{
[[NSWorkspace sharedWorkspace]
openURL: [NSURL URLWithString: @"https://sourceforge.net/p/clipsrules/code/HEAD/tree/branches/64x/examples/"]];
}
- (IBAction) showCLIPSExpertSystemGroup: (id) sender
{
[[NSWorkspace sharedWorkspace]
openURL: [NSURL URLWithString: @"http://groups.google.com/group/CLIPSESG/"]];
}
- (IBAction) showCLIPSSourceForgeDiscussion: (id) sender
{
[[NSWorkspace sharedWorkspace]
openURL: [NSURL URLWithString: @"http://sourceforge.net/p/clipsrules/discussion"]];
}
- (IBAction) showCLIPSStackOverflow: (id) sender
{
[[NSWorkspace sharedWorkspace]
openURL: [NSURL URLWithString: @"http://stackoverflow.com/questions/tagged/clips"]];
}
- (void) setPreferencesFromWatchFlags
{
NSUserDefaults *theValues;
NSNumber *watchValue;
AppController *theDelegate = [NSApp delegate];
CLIPSTerminalController *theController = [theDelegate mainTerminal];
CLIPSEnvironment *theEnv = [theController environment];
NSUserDefaultsController *theDefaultsController;
theDefaultsController = [NSUserDefaultsController sharedUserDefaultsController];
theValues = [theDefaultsController values];
watchValue = [NSNumber numberWithBool: [theEnv getWatchState: COMPILATIONS]];
[theValues setValue: watchValue forKey: @"compilations"];
watchValue = [NSNumber numberWithBool: [theEnv getWatchState: FACTS]];
[theValues setValue: watchValue forKey: @"facts"];
watchValue = [NSNumber numberWithBool: [theEnv getWatchState: RULES]];
[theValues setValue: watchValue forKey: @"rules"];
watchValue = [NSNumber numberWithBool: [theEnv getWatchState: STATISTICS]];
[theValues setValue: watchValue forKey: @"statistics"];
watchValue = [NSNumber numberWithBool: [theEnv getWatchState: ACTIVATIONS]];
[theValues setValue: watchValue forKey: @"activations"];
watchValue = [NSNumber numberWithBool: [theEnv getWatchState: FOCUS]];
[theValues setValue: watchValue forKey: @"focus"];
watchValue = [NSNumber numberWithBool: [theEnv getWatchState: GLOBALS]];
[theValues setValue: watchValue forKey: @"globals"];
watchValue = [NSNumber numberWithBool: [theEnv getWatchState: DEFFUNCTIONS]];
[theValues setValue: watchValue forKey: @"deffunctions"];
watchValue = [NSNumber numberWithBool: [theEnv getWatchState: GENERIC_FUNCTIONS]];
[theValues setValue: watchValue forKey: @"generic-functions"];
watchValue = [NSNumber numberWithBool: [theEnv getWatchState: METHODS]];
[theValues setValue: watchValue forKey: @"methods"];
watchValue = [NSNumber numberWithBool: [theEnv getWatchState: INSTANCES]];
[theValues setValue: watchValue forKey: @"instances"];
watchValue = [NSNumber numberWithBool: [theEnv getWatchState: SLOTS]];
[theValues setValue: watchValue forKey: @"slots"];
watchValue = [NSNumber numberWithBool: [theEnv getWatchState: MESSAGE_HANDLERS]];
[theValues setValue: watchValue forKey: @"message-handlers"];
watchValue = [NSNumber numberWithBool: [theEnv getWatchState: MESSAGES]];
[theValues setValue: watchValue forKey: @"messages"];
[theDefaultsController save: self];
}
- (void) applicationDidFinishLaunching: (NSNotification *) aNotification
{
mainEnvironment = [[CLIPSEnvironment alloc] init];
mainTerminal = [[CLIPSTerminalController alloc] initWithEnvironment: mainEnvironment];
[mainTerminal showWindow: self];
[[mainTerminal window] makeKeyAndOrderFront: self];
}
- (BOOL) applicationShouldOpenUntitledFile: (NSApplication *) sender
{
return NO;
}
- (NSApplicationTerminateReply) applicationShouldTerminate: (NSApplication *) app
{
[self setPreferencesFromWatchFlags];
if (preferenceController != nil)
{ return [preferenceController reviewPreferencesBeforeQuitting]; }
return NSTerminateNow;
}
- (NSLock *) fileOpenLock
{
return fileOpenLock;
}
@end