//
//  EXPParameterComponent.m
//  Expression
//
//  Created by ashley on 24/11/2008.
//  Copyright 2008 __MyCompanyName__. All rights reserved.
//

#import "EXPParameterComponent.h"
#import "EXPModelObject.h"

@implementation EXPParameterComponent

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

- (BOOL) acceptsInputs
{
	return YES;
}

- (BOOL) acceptsOutputs
{
	return YES;
}

- (void) computePath
{
	NSSize size = [self size];
	NSPoint pos = [self pos];
	float x = pos.x;
	float y = pos.y;
	float w = size.width;
	float h = size.height;
	NSBezierPath *path = [[NSBezierPath alloc] init];
	[path moveToPoint:NSMakePoint(x, y + h/2.0)];
	[path lineToPoint:NSMakePoint(x + w/2.0, y + h)];
	[path lineToPoint:NSMakePoint(x + w, y + h/2.0)];
	[path lineToPoint:NSMakePoint(x + w/2.0, y)];
	[path closePath];	
	[self setPath:path];
	[path release];

}

- (NSPoint) normalVectorForPoint:(NSPoint)point length:(float)length
{
//	NSPoint surfacePoint = [self closestSurfacePointToPoint:point];
	NSSize size = [self size];
	float w = size.width;
//	float radius = w/2.0;

//	float xp = point.x;
//	float yp = point.y;
	NSPoint pos = [self pos];
	float x = pos.x - point.x - w;
	float y = pos.y - point.y - w;
//	NSPoint norm;

	float nx;
	float ny;
	if ((x>=0.0) && (y>=0.0)) {
		nx = length;
		ny = length;
	} else if ((x>=0.0) && (y<=0.0)) {
		nx = length;
		ny = -length;
	} else if ((x<=0.0) && (y>=0.0)) {
		nx = -length;
		ny = length;
	} else {
		nx = -length;
		ny = -length;
	}
	return NSMakePoint(nx, ny);
}

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

	NSBezierPath *path = [self path];
	
	return [path containsPoint:point];
}

- (NSPoint) closestSurfacePointToPoint:(NSPoint)point
{
/*	NSPoint pos = [self pos];
	float x = pos.x;
	float y = pos.y;
	NSSize size = [self size];
	float h = size.width/2.0;

	float xp = point.x - (x + h);
	float yp = point.y - (y + h);
	
	float a;
	float b;
	if ((xp>=0.0) && (yp>=0.0)) {
		a = 1.0;
		b = -1.0;
	} else if ((xp>=0.0) && (yp<=0.0)) {
		a = -1.0;
		b = 1.0;
	} else if ((xp<=0.0) && (yp<=0.0)) {
		a = -1.0;
		b = -1.0;
	} else {
		a = 1.0;
		b = 1.0;
	}
	
	float delta = (yp/xp - b);
	if (fabs(delta)<=1.0e-7) {
		printf("OOps\n");
		return NSMakePoint(0.0, 0.0);
	}
	float temp = a*h/delta;
	float xs = x + h + temp;
	float ys = y + h + temp*(yp/xp);
	printf("closestSurfacePointToPoint = (%g, %g)\n", xs, ys); */

	NSPoint pos = [self pos];
	NSSize size = [self size];
	float h = size.height/2.0;
	float w = size.width/2.0;
	
/*	float root2 = 1.41421356237;
	float x = (point.x - pos.x - w)/w;
	float y = (point.y - pos.y - h)/h;
	NSPoint pt = EXPNearestPointOnUnitSquareToPoint((x + y)/root2, (-x + y)/root2);
	x = (pt.x - pt.y)/root2;
	y = (pt.x + pt.y)/root2;
	float xs = x*w + w + pos.x;
	float ys = y*h + h + pos.y; */

//	float root2 = 1.41421356237;
	float x = (point.x - pos.x - w)/w;
	float y = (point.y - pos.y - h)/h;
//	NSPoint pt = EXPNearestPointOnUnitSquareToPoint((x + y)/root2, (-x + y)/root2);
	NSPoint pt = EXPNearestPointOnUnitSquareToPoint((x + y)/2, (-x + y)/2);
	x = (pt.x - pt.y)/2.0;
	y = (pt.x + pt.y)/2.0;
	float xs = x*w + w + pos.x;
	float ys = y*h + h + pos.y;

	printf("closestSurfacePointToPoint = (%g, %g)\n", xs, ys);
	return NSMakePoint(xs, ys);
}

- (NSRect) drawingBounds
{
/*	NSPoint pos = [self pos];
	NSSize size = [self size];
	NSRect rect = NSMakeRect(pos.x, pos.y, size.width, size.height); */
	if ([self path]==nil) {
		[self computePath];
	}
	NSBezierPath *path = [self path];
	NSRect rect = [path bounds];
	return rect;
	
/*	EXPModelObject *modelObject = [self modelObject];
	NSDictionary *attribs = [modelObject textAttributes];
	NSString *name = [self name];
	NSSize nameSize = [name sizeWithAttributes:attribs];
	float xp = pos.x + (size.width - nameSize.width)/2.0;
	float yp = pos.y - nameSize.height - 2.0;
	NSRect nameBounds = NSMakeRect(xp, yp, nameSize.width, nameSize.height);
	
	return NSUnionRect(rect, nameBounds); */
}

- (void) drawInView:(id)view isSelected:(BOOL)flag
{
	if ([self path]==nil) {
		[self computePath];
	}
	NSBezierPath *path = [self path];

	EXPModelObject *modelObject = [self modelObject];
	NSDictionary *defaults = [modelObject defaults];
	
/*	NSSize size = [self size];
	NSPoint pos = [self pos];
	float x = pos.x;
	float y = pos.y;
	float w = size.width; */
/*	float h = size.height;
	NSBezierPath *path = [[NSBezierPath alloc] init];
	[path moveToPoint:NSMakePoint(x, y + h/2.0)];
	[path lineToPoint:NSMakePoint(x + w/2.0, y + h)];
	[path lineToPoint:NSMakePoint(x + w, y + h/2.0)];
	[path lineToPoint:NSMakePoint(x + w/2.0, y)];
	[path closePath]; */
	
	[[defaults objectForKey:@"ParameterFillColour"] set];
	[path fill];
	[[defaults objectForKey:@"ParameterStrokeColour"] set];
	[path stroke];
//	[path release];
	if (flag) {
		NSSize size = [self size];
		NSPoint pos = [self pos];
		float controlSquareSize = [[defaults objectForKey:@"ControlSquareSize"] floatValue];
		[[NSColor magentaColor] set];

		NSFrameRect(NSMakeRect(pos.x - controlSquareSize/2.0, pos.y - controlSquareSize/2.0, controlSquareSize, controlSquareSize));
		NSFrameRect(NSMakeRect(pos.x + size.width - controlSquareSize/2.0, pos.y - controlSquareSize/2.0, controlSquareSize, controlSquareSize));
		NSFrameRect(NSMakeRect(pos.x - controlSquareSize/2.0, pos.y + size.height - controlSquareSize/2.0, controlSquareSize, controlSquareSize));
		NSFrameRect(NSMakeRect(pos.x + size.width - controlSquareSize/2.0, pos.y + size.height - controlSquareSize/2.0, controlSquareSize, controlSquareSize));
	}


/*	NSString *name = [self name];
	float xp = x + w/2.0;
	float yp = y;
	NSDictionary *attribs = [[NSDictionary alloc] initWithObjectsAndKeys:
							[NSFont fontWithName:[defaults objectForKey:@"FontName"] size:[[defaults objectForKey:@"FontSize"] floatValue]], NSFontAttributeName,
							[defaults objectForKey:@"TextColour"], NSForegroundColorAttributeName,
							nil];
	NSSize nameSize = [name sizeWithAttributes:attribs];
	[name drawAtPoint:NSMakePoint(xp - nameSize.width/2.0, yp - nameSize.height  - 2.0) withAttributes:attribs];
	[attribs release]; */
	[self drawName];

}

@end