//
//  MyDocument.m
//  PythonLauncher
//
//  Created by Jack Jansen on Fri Jul 19 2002.
//  Copyright (c) 2002 __MyCompanyName__. All rights reserved.
//

#import "MyDocument.h"
#import "MyAppDelegate.h"
#import "doscript.h"

@implementation MyDocument

- (id)init
{
    self = [super init];
    if (self) {

        // Add your subclass-specific initialization here.
        // If an error occurs here, send a [self dealloc] message and return nil.
        script = [@"<no script>.py" retain];
        filetype = [@"Python Script" retain];
        settings = NULL;
    }
    return self;
}

- (NSString *)windowNibName
{
    // Override returning the nib file name of the document
    // If you need to use a subclass of NSWindowController or if your document supports multiple NSWindowControllers, you should remove this method and override -makeWindowControllers instead.
    return @"MyDocument";
}

- (void)close
{
    NSApplication *app = [NSApplication sharedApplication];
    [super close];
    if ([(MyAppDelegate*)[app delegate] shouldTerminate])
        [app terminate: self];
}

- (void)load_defaults
{
    settings = [FileSettings newSettingsForFileType: filetype];
}

- (void)update_display
{
    [interpreter setStringValue: [settings interpreter]];
    [honourhashbang setState: [settings honourhashbang]];
    [debug setState: [settings debug]];
    [verbose setState: [settings verbose]];
    [inspect setState: [settings inspect]];
    [optimize setState: [settings optimize]];
    [nosite setState: [settings nosite]];
    [tabs setState: [settings tabs]];
    [others setStringValue: [settings others]];
    [scriptargs setStringValue: [settings scriptargs]];
    [with_terminal setState: [settings with_terminal]];

    [commandline setStringValue: [settings commandLineForScript: script]];
}

- (void)update_settings
{
    [settings updateFromSource: self];
}

- (BOOL)run
{
    const char *cmdline;
    int sts;

     cmdline = [[settings commandLineForScript: script] UTF8String];
   if ([settings with_terminal]) {
        sts = doscript(cmdline);
    } else {
        sts = system(cmdline);
    }
    if (sts) {
        NSLog(@"Exit status: %d\n", sts);
        return NO;
    }
    return YES;
}

- (void)windowControllerDidLoadNib:(NSWindowController *) aController
{
    [super windowControllerDidLoadNib:aController];
    // Add any code here that need to be executed once the windowController has loaded the document's window.
    [self load_defaults];
    [self update_display];
}

- (NSData *)dataRepresentationOfType:(NSString *)aType
{
    // Insert code here to write your document from the given data.  You can also choose to override -fileWrapperRepresentationOfType: or -writeToFile:ofType: instead.
    return nil;
}

- (BOOL)readFromFile:(NSString *)fileName ofType:(NSString *)type;
{
    // Insert code here to read your document from the given data.  You can also choose to override -loadFileWrapperRepresentation:ofType: or -readFromFile:ofType: instead.
    BOOL show_ui;

    // ask the app delegate whether we should show the UI or not.
    show_ui = [(MyAppDelegate*)[[NSApplication sharedApplication] delegate] shouldShowUI];
    [script release];
    script = [fileName retain];
    [filetype release];
    filetype = [type retain];
    settings = [FileSettings newSettingsForFileType: filetype];
    if (show_ui) {
        [self update_display];
        return YES;
    } else {
        [self run];
	[self performSelector:@selector(close) withObject:nil afterDelay:0.0];
        return YES;
    }
}

- (IBAction)do_run:(id)sender
{
    [self update_settings];
    [self update_display];
    if ([self run])
        [self close];
}

- (IBAction)do_cancel:(id)sender
{
    [self close];
}


- (IBAction)do_reset:(id)sender
{
    [settings reset];
    [self update_display];
}

- (IBAction)do_apply:(id)sender
{
    [self update_settings];
    [self update_display];
}

// FileSettingsSource protocol
- (NSString *) interpreter { return [interpreter stringValue];};
- (BOOL) honourhashbang { return [honourhashbang state];};
- (BOOL) debug { return [debug state];};
- (BOOL) verbose { return [verbose state];};
- (BOOL) inspect { return [inspect state];};
- (BOOL) optimize { return [optimize state];};
- (BOOL) nosite { return [nosite state];};
- (BOOL) tabs { return [tabs state];};
- (NSString *) others { return [others stringValue];};
- (NSString *) scriptargs { return [scriptargs stringValue];};
- (BOOL) with_terminal { return [with_terminal state];};

// Delegates
- (void)controlTextDidChange:(NSNotification *)aNotification
{
    [self update_settings];
    [self update_display];
};

@end
