/* Document.m Subclass of NSDocument for GScheme application

   Copyright (C) 2000 Free Software Foundation, Inc.

   Author:  Fred Kiefer <fredkiefer@gmx.de>
   Date: 2000.

   Adapted by: Marko Riedel <mriedel@neuearbeit.de>.
   Date: 2002.
   
   This file is part of GNUstep.
   
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 2 of the License, or
   (at your option) any later version.
   
   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.
   
   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software
   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */
#include <AppKit/AppKit.h>
#include <AppKit/NSWindowController.h>

#include "Document.h"
#include "SCMTextView.h"

@interface Document (Private)

- (NSWindow*)makeWindow;

@end

@implementation Document

- init
{
    progstr = @"\n";
    return [super init];
}

- (void)textDidChange:(NSNotification *)textObject
{
    [self updateChangeCount: NSChangeDone];
}

- (NSData *)dataRepresentationOfType:(NSString *)aType 
{
  if(aType==nil || [aType isEqualToString:@"scm"]){
      return [[tview string] dataUsingEncoding:NSASCIIStringEncoding];
  }
  else{
      NSString *msg = [NSString stringWithFormat: @"Unknown type: %@", 
                                [aType uppercaseString]];
      NSRunAlertPanel(@"Alert", msg, @"Ok", nil, nil);
      return nil;
  }
}

- (BOOL)loadDataRepresentation:(NSData *)data ofType:(NSString *)aType 
{
    if([aType isEqualToString:@"scm"]){
        progstr = [NSString stringWithCString:[data bytes] 
                            length:[data length]];
    }
    else{
        NSString *msg = [NSString stringWithFormat: @"Unknown type: %@", 
                                  [aType uppercaseString]];
        NSRunAlertPanel(@"Alert", msg, @"Ok", nil, nil);
          return NO;
    }

    return YES;
}


- (BOOL)readFromFile:(NSString *)fileName ofType:(NSString *)docType
{
    NSFileManager *manager = [NSFileManager defaultManager];
    if([manager isWritableFileAtPath:fileName]==NO){
        NSString *msg = [NSString stringWithFormat: @"File is read only: %@", 
                                  fileName];
        readOnly = YES;

        NSRunAlertPanel(@"Alert", msg, @"Ok", nil, nil);
      }

    return [super readFromFile:fileName ofType:docType];
}

- (BOOL)writeToFile:(NSString *)fullDocumentPath ofType:(NSString *)docType 
       originalFile:(NSString *)fullOriginalDocumentPath 
      saveOperation:(NSSaveOperationType)saveOperationType;
{
    BOOL result = 
	[super writeToFile:fullDocumentPath ofType:docType
	       originalFile:fullOriginalDocumentPath
	       saveOperation:saveOperationType];
    if(result==YES && readOnly==YES && saveOperationType==NSSaveAsOperation){
        NSString *msg = [NSString stringWithFormat: @"File now writable: %@", 
                                  fullDocumentPath];
        NSRunAlertPanel(@"Alert", msg, @"Ok", nil, nil);
  
        readOnly = NO;
        [tview setEditable:YES];
    }
    else if(result==NO){
        NSString *msg = [NSString stringWithFormat: @"Write failed: %@", 
                                  fullDocumentPath];
        NSRunAlertPanel(@"Alert", msg, @"Ok", nil, nil);
    }

    return result;
}

extern VScheme *vm;
extern NSWindow *interpreterWindow;

- evaluate:(id)sender
{
    BOOL res;
    SCMInteractive *intView = 
        [[interpreterWindow contentView] documentView];
    NSString *suffix = [intView getSuffix];

    if([suffix length]>0){
        [intView appendString:@"\n> "];
    }

    progstr = [tview string];
    res = [vm processString:progstr mode:MODE_EVALUATE];

    if(res==NO){
	int errpos = [vm errpos];
	if(errpos!=-1){
	    [tview selectLineAtPos:errpos];
	}
	
        NSRunAlertPanel(@"Error", [vm errmsg], 
                        @"Ok", nil, nil);
    }
    else{
        [interpreterWindow makeKeyAndOrderFront:self];
    }

    return self;
}

- (void) makeWindowControllers
{
  NSWindowController *controller;
  NSWindow *win = [self makeWindow];
  
  controller = [[NSWindowController alloc] initWithWindow: win];
  RELEASE (win);
  [self addWindowController:controller];
  RELEASE(controller);

  // We have to do this ourself, as there is currently no nib file
  [self windowControllerDidLoadNib:controller];
} 

@end

int shiftPos = 0;
#define WREP 7

@implementation Document (Private)

- (NSWindow*)makeWindow
{
    NSWindow *window;
    NSScrollView *scrollView;
    SCMTextView *textView;
    NSRect scrollViewRect = {{0, 0}, {470, 400}};
    NSRect winRect = {{100+25*(shiftPos%WREP), 100+25*(shiftPos%WREP)},
		      {470, 400}};
    NSRect textRect;
    unsigned int style = NSTitledWindowMask | NSClosableWindowMask | 
	NSMiniaturizableWindowMask | NSResizableWindowMask;
    shiftPos++;
  
    // This is expected to be retained, as it would normaly come from a
    // nib file, where the owner would retain it.
    window = [[NSWindow alloc] initWithContentRect: winRect
			       styleMask: style
			       backing: NSBackingStoreRetained
			       defer: NO];
    [window setMinSize:NSMakeSize(300, 300)];
    [window setReleasedWhenClosed:YES];
   
    scrollView = [[NSScrollView alloc] initWithFrame: scrollViewRect];
    [scrollView setHasHorizontalScroller: NO];
    [scrollView setHasVerticalScroller: YES]; 
    [scrollView setAutoresizingMask: NSViewHeightSizable | NSViewWidthSizable];
    [[scrollView contentView] setAutoresizingMask: NSViewHeightSizable 
			      | NSViewWidthSizable];
    [[scrollView contentView] setAutoresizesSubviews:YES];
    sview = scrollView;

    // Build up the text network
    textRect = [[scrollView contentView] frame];
    textView = [[SCMTextView alloc] initWithFrame: textRect];

    [textView setBackgroundColor: [NSColor whiteColor]];

    [textView setString:progstr];
    [textView setFont:[NSFont userFixedPitchFontOfSize:12]];
    [textView setEditable:(readOnly==NO ? YES : NO)];

    [textView setDelegate: self];
    [textView setHorizontallyResizable: NO];
    [textView setVerticallyResizable: YES];
    [textView setMinSize: NSMakeSize (0, 0)];
    [textView setMaxSize: NSMakeSize (1E7, 1E7)];
    [textView setAutoresizingMask: NSViewHeightSizable | NSViewWidthSizable];
    [[textView textContainer] setContainerSize: NSMakeSize (textRect.size.width,
							    1e7)];
    [[textView textContainer] setWidthTracksTextView: YES];
    // Store the text view in an ivar
    tview = textView;

    [scrollView setDocumentView: textView];
    RELEASE(textView);
    [window setContentView: scrollView];
    RELEASE(scrollView);

    // Make the Document the delegate of the window
    [window setDelegate: self];
    [window setTitle:[self displayName]];

    // Make the text view the first responder
    [window makeFirstResponder:textView];
    [window display];
    [window orderFront: nil];

    return window;
}

@end
