//
//  EXPStockComponent.m
//  Expression
//
//  Created by ashley on 15/11/2008.
//  Copyright 2008 __MyCompanyName__. All rights reserved.
//

#import "EXPStockComponent.h"
#import "EXPCloudComponent.h"
#import "EXPFlowComponent.h"
#import "EXPModelObject.h"

@implementation EXPStockComponent

- (id)init
{
	if ((self = [super init]) != nil) {
//		NSSize size = NSMakeSize(100, 50);
		NSSize size = NSMakeSize(0, 0);
		_inflows = [[NSMutableArray alloc] init];
		_outflows = [[NSMutableArray alloc] init];
		[self setSize:size];
	}
	return self;
}

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

- (void) setFromElement:(NSXMLElement *)element
{
	[super setFromElement:element];
}

- (void) setInflows:(id)inflows
{
	[inflows retain];
	[_inflows release];
	_inflows = inflows;
}

- (id) inflows
{
	return _inflows;
}

- (void) setOutflows:(id)outflows
{
	[outflows retain];
	[_outflows release];
	_outflows = outflows;
}

- (id) outflows
{
	return _outflows;
}

- (id) inputComponents
{
	EXPModelObject *modelObject = [self modelObject];
	NSArray *objects = [modelObject objects];
	NSMutableArray *array = [NSMutableArray array];
	
	int i;
	for(i=0; i<[objects count]; i++) {
		EXPComponent *component = [objects objectAtIndex:i];
		if ([[component componentType] isEqualToString:@"Parameter"]) {
			[array addObject:component];
		}
	}

	return array;
}

- (BOOL) acceptsInputs
{
	return NO;
}

- (BOOL) acceptsOutputs
{
	return YES;
}

- (BOOL) acceptsInFlows
{
	return YES;
}

- (BOOL) acceptsOutFlows
{
	return YES;
}

- (void) dump
{
	[super dump];
	
	NSArray *inflows = [self inflows];
	int i;
	if ([inflows count]>0) {
		printf("Inflows\n");
		for (i=0; i<[inflows count]; i++) {
			EXPFlowComponent *inflow = [inflows objectAtIndex:i];
			printf("\t%s\n", [[inflow name] UTF8String]);
		}
	}
	
	NSArray *outflows = [self outflows];
	if ([outflows count]>0) {
		printf("Outflows\n");
		for (i=0; i<[outflows count]; i++) {
			EXPFlowComponent *outflow = [outflows objectAtIndex:i];
			printf("\t%s\n", [[outflow name] UTF8String]);
		}
	}
	
}

- (void) addObjectsForDeletionTo:(id)array
{
	EXPModelObject *modelObject = [self modelObject];

	NSArray *inflows = [self inflows];
	int i;
	for(i=0; i<[inflows count]; i++) {
		EXPFlowComponent *inflow = [inflows objectAtIndex:i];
		if (![array containsObject:inflow]) {
//			[inflow addObjectsForDeletionTo:array];
//			[array addObject:inflow];
			EXPCloudComponent *cloud = [[EXPCloudComponent alloc] init];
			NSPoint point = [self pos];
			[cloud setPosition:NSMakePoint(point.x, point.y)];
			[cloud setSize:[self size]];
			[inflow setEnd:cloud]; 
			[cloud setModelObject:modelObject];
			[[cloud inflows] addObject:inflow];
			[[modelObject objects] addObject:cloud];
			[cloud release];
		} 
	}
	
	NSArray *outflows = [self outflows];
	for(i=0; i<[outflows count]; i++) {
		EXPFlowComponent *outflow = [outflows objectAtIndex:i];
		if (![array containsObject:outflow]) {
//			[outflow addObjectsForDeletionTo:array];
//			[array addObject:outflow];
			EXPCloudComponent *cloud = [[EXPCloudComponent alloc] init];
			NSPoint point = [self pos];
			[cloud setPosition:NSMakePoint(point.x + 20.0, point.y)];
			[cloud setSize:[self size]];
			[outflow setEnd:cloud]; 
			[cloud setModelObject:modelObject];
			[[cloud outflows] addObject:outflow];
			[[modelObject objects] addObject:cloud];
			[cloud release];
		} 
	}
	
	[self setInflows:nil];
	[self setOutflows:nil];
	
	[super addObjectsForDeletionTo:array];
}

/*- (id) path
{
	NSPoint pos = [self pos];
	NSSize size = [self size];
	NSRect rect = NSMakeRect(pos.x, pos.y, size.width, size.height);
	return [NSBezierPath bezierPathWithRect:rect];
} */

/*- (void) computePath
{
	NSPoint pos = [self pos];
	NSSize size = [self size];
	NSRect rect = NSMakeRect(pos.x, pos.y, size.width, size.height);
	
	NSBezierPath *path = [[NSBezierPath alloc] init];
	[path appendBezierPathWithRect:rect];
	[self setPath:path];
	[path release];
} */

- (void) moveConnectedComponentsBy:(NSPoint)change
{
	NSSet *selection = [[self modelObject] selection];

	NSArray *inflows = [self inflows];
	int i;
	for(i=0; i<[inflows count]; i++) {
		EXPFlowComponent *inflow = [inflows objectAtIndex:i];
		if (![selection containsObject:inflow]) {
//			 [self moveFlow:(EXPFlowComponent *)inflow by:change moveStart:NO];
			 [inflow  moveBy:change moveStart:NO];
		}
	}

	NSArray *outflows = [self outflows];
	for(i=0; i<[outflows count]; i++) {
		EXPFlowComponent *outflow = [outflows objectAtIndex:i];
		if (![selection containsObject:outflow]) {
//			 [self moveFlow:(EXPFlowComponent *)outflow by:change moveStart:YES];
			 [outflow moveBy:change moveStart:YES];
		}
	}

	[super moveConnectedComponentsBy:change];
}

- (BOOL) containsPoint:(NSPoint)point
{
	NSPoint pos = [self pos];
	NSSize size = [self size];
	NSRect rect = NSMakeRect(pos.x, pos.y, size.width, size.height);
	BOOL contains = NSPointInRect(point, rect);
	
	return contains;
}

- (NSPoint) normalVectorForPoint:(NSPoint)point length:(float)length
{
	float nx;
	float ny;
	NSSize size = [self size];
	float w = size.width;
	float h = size.height;
	float a = h/w;
	NSPoint pos = [self pos];
	float x = point.x - pos.x - w;
	float y = point.y - pos.y - h;	
	
	if ((y>=a*x) && (y>=-a*x)) {
		nx = 0.0;
		ny = -length;
	} else if ((y<=a*x) && (y<=-a*x)) {
		nx = 0.0;
		ny = length;
	} else if ((y<=a*x) && (y>=-a*x)) {
		nx = -length;
		ny = 0.0;
	} else {
		nx = length;
		ny = 0.0;
	}
	
	return NSMakePoint(nx, ny);
}

- (NSPoint) closestSurfacePointToPoint:(NSPoint)point
{
	NSPoint pos = [self pos];
	NSSize size = [self size];
	float h = size.height/2.0;
	float w = size.width/2.0;
	
	float x = (point.x - pos.x - w)/w;
	float y = (point.y - pos.y - h)/h;
	NSPoint pt = EXPNearestPointOnUnitSquareToPoint(x, y);
	return NSMakePoint(pt.x*w + w + pos.x, pt.y*h + h + pos.y);
}

- (NSRect) drawingBounds
{
	NSPoint pos = [self pos];
	NSSize size = [self size];
	NSRect rect = NSMakeRect(pos.x, pos.y, size.width, size.height);
	
	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
{
	EXPModelObject *modelObject = [self modelObject];
	NSDictionary *defaults = [modelObject defaults];
	
	NSPoint pos = [self pos];
	NSSize size = [self size];
	NSRect rect = NSMakeRect(pos.x, pos.y, size.width, size.height);
	
	NSBezierPath *path = [[NSBezierPath alloc] init];
	[path appendBezierPathWithRect:rect];

	[[defaults objectForKey:@"StockFillColour"] set];
	[path fill];
	[[defaults objectForKey:@"StockStrokeColour"] 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));
	}
//	NSLog(@"Drawing %@: document =%@.", [self name], [self document]);

/*	NSString *name = [self name];
	float xp = pos.x + size.width/2.0;
	float yp = pos.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];
	
/*	if (flag) {
		float controlSquareSize = 8.0;
		[[NSColor magentaColor] set];
		NSFrameRect(NSMakeRect(pos.x - controlSquareSize/2.0, pos.y - controlSquareSize/2.0, controlSquareSize, controlSquareSize));
	} */
}

/* - (void) draw
{
} */

- (void) dealloc
{
	[_inflows release];
	[_outflows release];
	[super dealloc];
}

@end