//
//  MPT_FaceView.m
//  AUCoderDemo
//
//  Created by Andrew Salamon on 5/19/06.
//  Copyright (c) 2006 Machine Perception Laboratory 
//  University of California San Diego.//

#import "MPT_FaceView.h"
#import "MPT_Face.h"

@interface MPT_FaceView(PrivateMethods)
-  (void)drawFace:(MPT_Face *)face inRect:(NSRect)rect;
- (NSPoint)adjustPoint:(NSPoint)point ForRect:(NSRect)rect;
@end

@implementation MPT_FaceView

- (id)initWithFrame:(NSRect)frame
{
    self = [super initWithFrame:frame];
    if (self)
	{
		[self setFaceType:MPTFace_both];
        [self resetFaceAndEyes];
    }
    return self;
}

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

- (void)resetFaceAndEyes
{
	[self setFaces:nil];
}

- (NSArray *)faces
{
    return faces;
}

- (void)setFaces:(NSArray *)value
{
    if( faces != value )
    {
        [faces release];
        faces = [value retain];
    }
}

- (NSString *)lastDropPath {
    return [[lastDropPath retain] autorelease];
}

- (void)setLastDropPath:(NSString *)value {
    if (lastDropPath != value) {
        [lastDropPath release];
        lastDropPath = [value copy];
    }
}

- (DisplayFaceType)faceType
{
    return faceType;
}

- (void)setFaceType:(DisplayFaceType)value
{
	if( faceType != value )
	{
		faceType = value;
		[self setNeedsDisplay:YES];
	}
}

- (BOOL)isFlipped
{
	return YES;
}

- (NSRect)imageRect
{
	NSSize mySize = [self frame].size;
	NSImage *myImage = [self image];
	NSSize size = [myImage size];
	float xdiff = (mySize.width - size.width) / 2;
	float ydiff = (mySize.height - size.height) / 2;
	NSRect imgRect = [self frame];
	imgRect.origin.x = xdiff;
	imgRect.origin.y = ydiff;
	imgRect.size.width = size.width;
	imgRect.size.height = size.height;
	
	return imgRect;
}

- (void)drawRect:(NSRect)rect
{
    [super drawRect:rect];
	
	if( [faces count] > 0 )
	{
		NSRect imgRect = [self imageRect];
		NSEnumerator *faceEnum = [faces objectEnumerator];
		MPT_Face *mptFace;
		while( mptFace = [faceEnum nextObject] )
		{
			[self drawFace:mptFace inRect:imgRect];
		}
	}
}

// Make sure that a point is adjusted for the images actual location within the view
- (NSPoint)adjustPoint:(NSPoint)point ForRect:(NSRect)rect
{
	float xdiff = rect.origin.x;
	float ydiff = rect.origin.y;
	point.x += xdiff;
	point.y += ydiff;
	return point;
}

-  (void)drawFace:(MPT_Face *)face inRect:(NSRect)rect
{
	static NSColor *foreColor = nil;
	
	NSRect faceRect = [face face];
	NSArray *points = [face points];
	BOOL havePoints = [points count] > 1;
	
	if( !foreColor )
		foreColor = [NSColor blueColor];
	
	if( (faceType != MPTFace_facefinderOnly) && havePoints )
	{
		[[NSColor greenColor] setStroke];
		NSBezierPath* aPath = [NSBezierPath bezierPath];
		
		NSPoint start = [self adjustPoint:NSPointFromString([points objectAtIndex:0]) ForRect:rect];
		[aPath moveToPoint:start];
		
		for( unsigned int x=[points count]-1; x > 0; --x )
		{
			[aPath lineToPoint:[self adjustPoint:NSPointFromString([points objectAtIndex:x]) ForRect:rect]];
		}
		
		[aPath lineToPoint:start];
		[aPath closePath];
		
		[aPath stroke];
	}

	if( (faceType != MPTFace_modifiedFace) || !havePoints )
	{
		[foreColor setFill];
		
		//	if( faceRect.origin.x > 0 )
		{
			faceRect.origin = [self adjustPoint:faceRect.origin ForRect:rect];
			NSFrameRect( faceRect );
		}
	}
	
	float eyeSize = faceRect.size.width * 0.04; // 4.0;
	float eyeOffset = eyeSize / 2.0;
	
	NSArray *features = [face features];
	NSEnumerator *featureEnum = [features objectEnumerator];
	MPT_Feature *feature;
	while( feature = [featureEnum nextObject] )
	{
		NSPoint loc = [self adjustPoint:[feature location] ForRect:rect];
		NSRect aRect = NSMakeRect(loc.x-eyeOffset, loc.y-eyeOffset, eyeSize, eyeSize);
		if( [feature color] )
			[[feature color] setFill];
		else
			[[NSColor redColor] setFill];
		NSFrameRect( aRect );
	}
}

- (void)concludeDragOperation:(id <NSDraggingInfo>)sender
{
	NSPasteboard *pboard = [sender draggingPasteboard];
	NSURL *url = [NSURL URLFromPasteboard:pboard];
	
	if( [url isFileURL] )
		[self setLastDropPath:[url path]];
	else
		[self setLastDropPath:nil];

	[super concludeDragOperation:sender];
}

@end
