#import <Foundation/Foundation.h>

#import "SplineView.h"
#import "Spline.h"
#import "BezierORShape.h"
 
@implementation SplineView

- initWithFrame:(NSRect)frameRect
{
	[super initWithFrame:frameRect];
	spline = nil;
	drawFlags = DRAW_ALL;
	return self;
}

- (void)dealloc
{
	if(spline)
		[spline release];
	return [super dealloc];
}

- (void)drawRect:(NSRect)r
{   
	PSsetgray(NSWhite);
	NSRectFill([self bounds]);
	if(spline){
		if([[NSDPSContext currentContext] isDrawingToScreen])
			[spline drawWithFlags:drawFlags];    	         	         	     
		else
			[spline drawSpecial];
	}
}

- (void)mouseDown:(NSEvent *)event 
{
	[self  lockFocus];
	if(([event modifierFlags] & NSControlKeyMask) == NSControlKeyMask)
		[self createSpline:event];
	else
		[self changeSpline:event];
	[self drawRect:[self bounds]];
	[[self window] flushWindow];
	PSWait();
	[self unlockFocus];
}

- (void)createSpline:(NSEvent *)event 
{
	NSPoint p;
	BOOL finished = NO;
	
	if(spline)
		[spline empty];
	else 
		spline = [[Spline alloc] init];
	[spline setParametrisationType:[parametrisationMatrix selectedTag]];
	[spline setEndPointAType:[endPointAMatrix selectedTag]];
	[spline setEndPointBType:[endPointBMatrix selectedTag]];
	do {
		event = [[self window] nextEventMatchingMask:NSLeftMouseUpMask|NSLeftMouseDownMask|NSLeftMouseDraggedMask];
		if([event type] == NSLeftMouseUp && [event clickCount] >= 2)
			finished = YES;
		else {
			p = [event locationInWindow]; 
    			p = [self convertPoint:p fromView:nil];
			PSsetgray(NSWhite);
			NSRectFill([self bounds]);
			[spline drawWithPoint:p :drawFlags];
			[[self window] flushWindow];
			PSWait();
			if([event type] == NSLeftMouseUp)
				[spline addPoint:p];
		}
	} while(!finished);
}

- (void)changeSpline:(NSEvent *)event 
{
	NSPoint p;
	int pointNr;
	BOOL finished = NO;
	
	if(!spline)
		return;
	p = [event locationInWindow]; 
    	p = [self convertPoint:p fromView:nil];
	pointNr = [spline hitWithPoint:p];
	if(pointNr == -1)
		return;
	do {
		event = [[self window] nextEventMatchingMask:NSLeftMouseUpMask|NSLeftMouseDraggedMask];
		p = [event locationInWindow]; 
    		p = [self convertPoint:p fromView:nil];
		PSsetgray(NSWhite);
		NSRectFill([self bounds]);
		[spline changePointNr:pointNr to:p];
		[spline drawWithFlags:drawFlags];
		[[self window] flushWindow];
		PSWait();
		if([event type] == NSLeftMouseUp)
			finished = YES;
	} while(!finished);
}

- (void)changeParametrisation:(id)sender
{
	if(!spline)
		return;
	[spline setParametrisationType:[parametrisationMatrix selectedTag]];
	[self display];
}

- (void)changeEndPointA:(id)sender
{
	if(!spline)
		return;
	[spline setEndPointAType:[endPointAMatrix selectedTag]];
	[self display];
}

- (void)changeEndPointB:(id)sender
{
	if(!spline)
		return;
	[spline setEndPointBType:[endPointBMatrix selectedTag]];
	[self display];
}

- (void)changeDrawFlags:(id)sender
{
	drawFlags = DRAW_NONE;
	if([[sender cellAtRow:0 column:0] state])
		drawFlags = drawFlags | DRAW_LINE;
	if([[sender cellAtRow:1 column:0] state])
		drawFlags = drawFlags | DRAW_CURVE;
	if([[sender cellAtRow:2 column:0] state])
		drawFlags = drawFlags | DRAW_BEZIER;
	[self display];
}

- (void)saveAsEve:(id)sender
{
    	 NSSavePanel *savepanel = [NSSavePanel savePanel];
         NSString *file, *directory, *nibfile;
         int runResult;
	 NSBundle *bundle = [NSBundle mainBundle];
         NSMutableData *eveData;
         NSFileManager *fm = [NSFileManager defaultManager];
         BOOL isDir;


         if(!spline)
                 return;
   	 [savepanel setRequiredFileType:@"wwModel"];
      	 runResult = [savepanel runModalForDirectory:NSHomeDirectory() file:@""];
    	 if(runResult == NSOKButton){
    		if(!(file = [bundle pathForResource:@"model" ofType:@"eve"])){
                    	NSLog(@"Could not find model.eve file");
        		NSBeep();
        		return;
    		}
                if(!(nibfile = [bundle pathForResource:@"controls" ofType:@"nib"])){
                    	NSLog(@"Could not find controls.nib file");
                        NSBeep();
                        return;
                }
                directory = [savepanel filename];
                if([fm fileExistsAtPath:directory isDirectory:&isDir]){
                       if(![fm removeFileAtPath:directory handler:nil]){
                                NSLog(@"Could not remove old directory %@",directory);
                           	NSBeep();
                                return;
                       } 
                }
                if(![fm createDirectoryAtPath:directory attributes:nil]){
                        NSLog(@"Could not create directory %@",directory);
                    	NSBeep();
                   	return;
                }
                if(![fm copyPath:nibfile toPath:[NSString stringWithFormat:@"%@/controls.nib",directory] handler:nil]){
                        NSLog(@"Could not copy file %@ to directory %@",nibfile,directory);
                        NSBeep();
                        return;
                }
                eveData = [NSMutableData dataWithContentsOfFile:file];
                [eveData appendData:[[spline rot3DShape] eveData]];
                file = [NSString stringWithFormat:@"%@/model.eve",directory];
                if(![eveData writeToFile:file atomically:YES]){
                        NSLog(@"Could not write file %@ into directory %@",file,directory);
                    	NSBeep();
                    	return;
                }
    	}
}

@end

