//
//  EXPConnectorComponent.m
//  Expression
//
//  Created by ashley on 20/11/2008.
//  Copyright 2008 __MyCompanyName__. All rights reserved.
//

#import "EXPConnectorComponent.h"
#import "EXPModelObject.h"

float controlSquareSize = 8.0;

@implementation EXPConnectorComponent

/*- (void) setLastControlPoint:(int)lastControlPoint
{
	_lastControlPoint = lastControlPoint;
}

- (int) lastControlPoint
{
	return _lastControlPoint;
} */

- (id) componentType
{
	return @"Connector";
}

- (BOOL) process:(id)symbolTable
{
	BOOL success = [super process:symbolTable];
	
	EXPComponent *startComponent = [self start];
	[[startComponent outputs] addObject:self];
	
	EXPComponent *endComponent = [self end];
	[[endComponent inputs] addObject:self];	
	
	return success;
}

- (void) unlinkFromConnections
{
	EXPComponent *start = [self start];
	[start removeOutput:self];
	EXPComponent *end = [self end];
	[end removeInput:self];
}

- (void) addObjectsForDeletionTo:(id)array
{
	[self unlinkFromConnections];
	[super addObjectsForDeletionTo:array];
}

- (BOOL) containsPoint:(NSPoint)point
{
	if ([self path]==nil) {
		[self computePath];
	}

	NSRect rect = [self drawingBounds];
	BOOL containsPoint = NSPointInRect(point, rect);
	
	return containsPoint;
}

- (int) controlPointSelected
{
	return _controlPointSelected;
}

- (BOOL) controlAreaContainsPoint:(NSPoint)point
{
	NSBezierPath *path;
	NSPoint pos = [self pos];
	NSPoint pos2 = [self pos2];
	NSPoint controlVector2 = [self controlVector2];
	NSPoint controlVector = [self controlVector];
	NSPoint controlPoint1 = NSMakePoint(pos.x + controlVector.x,  pos.y + controlVector.y);
	NSPoint controlPoint2 = NSMakePoint(pos2.x - controlVector2.x,  pos2.y - controlVector2.y);
	
	NSRect rect1 = NSMakeRect(pos.x - controlSquareSize/2.0, pos.y - controlSquareSize/2.0, controlSquareSize, controlSquareSize);
	if (NSPointInRect(point, rect1)) {
		[self setControlPointSelected:3];
		return YES;
	}
	
	NSRect rect2 = NSMakeRect(pos2.x - controlSquareSize/2.0, pos2.y - controlSquareSize/2.0, controlSquareSize, controlSquareSize);
	if (NSPointInRect(point, rect2)) {
		[self setControlPointSelected:4];
		return YES;
	}

	path = [NSBezierPath bezierPathWithOvalInRect:
		NSMakeRect(controlPoint1.x - controlSquareSize/2.0, controlPoint1.y - controlSquareSize/2.0, controlSquareSize, controlSquareSize)];
	if ([path containsPoint:point]) {
		[self setControlPointSelected:1];
		return YES;
	}

	path = [NSBezierPath bezierPathWithOvalInRect:
		NSMakeRect(controlPoint2.x - controlSquareSize/2.0, controlPoint2.y - controlSquareSize/2.0, controlSquareSize, controlSquareSize)];
	if ([path containsPoint:point]) {
		[self setControlPointSelected:2];
		return YES;
	}

	[self setControlPointSelected:0];
	return NO;
}

- (NSRect) drawingBounds
{
	if ([self path]==nil) {
		[self computePath];
	}
	NSBezierPath *path = [self path];
	
	return [path bounds];
}

- (void) computePath
{
	EXPModelObject *modelObject = [self modelObject];
	NSDictionary *defaults = [modelObject defaults];
//	NSLog(@"Drawing %@", [self name]);
	NSPoint pos = [self pos];
	NSPoint pos2 = [self pos2];
	NSPoint controlVector2 = [self controlVector2];
//	float arrowheadSize = [[defaults objectForKey:@"ConnectorArrowheadSize"] floatValue];
	
	float x = pos.x;
	float y = pos.y;
	float x2 = pos2.x;
	float y2 = pos2.y;

	NSPoint controlVector = [self controlVector];
	float cv1x = controlVector.x;
	float cv1y = controlVector.y;
	float cv2x = controlVector2.x;
	float cv2y = controlVector2.y;

	float thickness  = [[defaults objectForKey:@"ConnectorThickness"] floatValue];
	
	NSPoint controlPoint1 = NSMakePoint(x + cv1x, y + cv1y);
	NSPoint controlPoint2 = NSMakePoint(x2 - cv2x, y2 - cv2y);

	NSBezierPath *path = [[NSBezierPath alloc] init];
	[path moveToPoint:NSMakePoint(x, y)];
	[path curveToPoint:NSMakePoint(x2, y2) controlPoint1:controlPoint1 controlPoint2:controlPoint2];
//	[self addCurveFrom:pos to:pos2 normal1:controlPoint1 normal2:controlPoint2 toPath:path];
	
	float lineDash[2];
	lineDash[0] = 4.0;
	lineDash[1] = 4.0;
	[path setLineDash:lineDash count:2 phase:0.0];
	[path setLineWidth:thickness];
	[self setPath:path];
	[path release];
}

- (void) drawInView:(id)view isSelected:(BOOL)flag
{
	EXPModelObject *modelObject = [[view delegate] modelObject];
	NSDictionary *defaults = [modelObject defaults];
//	NSLog(@"Drawing %@", [self name]);
	NSPoint pos = [self pos];
	NSPoint pos2 = [self pos2];
	NSPoint controlVector = [self controlVector];
//	float cv1x = controlVector.x;
//	float cv1y = controlVector.y;
	NSPoint controlVector2 = [self controlVector2];
	float arrowheadSize = [[defaults objectForKey:@"ConnectorArrowheadSize"] floatValue];
	
	if ([self path]==nil) {
		[self computePath];
	}
	[[defaults objectForKey:@"ConnectorColour"] set];
	[[self path] stroke];
	
	[self drawArrowheadAt:pos2 inDirection:controlVector2 size:NSMakeSize(2.0*arrowheadSize, arrowheadSize)];
	
//	[self drawName];
	
	if (flag) {
//		int controlPointSelected = [self controlPointSelected];
		[[NSColor magentaColor] set];
		NSFrameRect(NSMakeRect(pos.x - controlSquareSize/2.0, pos.y - controlSquareSize/2.0, controlSquareSize, controlSquareSize));
		NSFrameRect(NSMakeRect(pos2.x - controlSquareSize/2.0, pos2.y - controlSquareSize/2.0, controlSquareSize, controlSquareSize));
		NSBezierPath *path;
		NSPoint controlPoint1 = NSMakePoint(pos.x + controlVector.x,  pos.y + controlVector.y);
		NSPoint controlPoint2 = NSMakePoint(pos2.x - controlVector2.x,  pos2.y - controlVector2.y);
		path = [NSBezierPath bezierPathWithOvalInRect:
			NSMakeRect(controlPoint1.x - controlSquareSize/2.0, controlPoint1.y - controlSquareSize/2.0, controlSquareSize, controlSquareSize)];
		[path stroke];
		path = [NSBezierPath bezierPathWithOvalInRect:
			NSMakeRect(controlPoint2.x - controlSquareSize/2.0, controlPoint2.y - controlSquareSize/2.0, controlSquareSize, controlSquareSize)];
		[path stroke];
		
		[NSBezierPath strokeLineFromPoint:pos toPoint:controlPoint1];
		[NSBezierPath strokeLineFromPoint:pos2 toPoint:controlPoint2];
//		[path stroke];
		
	}

}

@end