//
//  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;
- (void)redrawImage;
@end

@implementation MPT_FaceView

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

- (void)awakeFromNib
{
	[self setFaceType:MPTFace_both];
	[self resetFaceAndEyes];
	[self setOverlayOnly:NO];
}

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

- (void)setImage:(NSImage *)newImage
{
	[self setOrigImage:newImage];
	[self redrawImage];
}

- (NSImage *)origImage {
    return [[origImage retain] autorelease];
}

- (void)setOrigImage:(NSImage *)value {
    if (origImage != value) {
        [origImage release];
        origImage = [value retain];
    }
}

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

- (NSArray *)faces
{
    return faces;
}

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

- (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 redrawImage];
		[self setNeedsDisplay:YES];
	}
}

- (BOOL)isFlipped
{
	return NO;
}

- (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;
}

- (BOOL)overlayOnly {
    return overlayOnly;
}

- (void)setOverlayOnly:(BOOL)value {
    if (overlayOnly != value) {
        overlayOnly = value;
		[self redrawImage];
		[self setNeedsDisplay];
    }
}


- (void)drawRect:(NSRect)rect
{
	if( [self overlayOnly] )
	{
		NSEraseRect( rect ); // might need to have this erase the entire view, or maybe do that in setOverlayOnly
	}
	else
	{
		[super drawRect:rect];
	}
}

// Flip the y coordinate since we're now drawing in the image itself, which has the origin at the lower left.
- (NSPoint)adjustPoint:(NSPoint)point ForRect:(NSRect)rect
{
	point.y = rect.size.height - point.y;
	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];
			faceRect.origin.y -= faceRect.size.height;
			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] )
	{
		if( [feature display] )
		{
			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];
}

- (void)redrawImage
{
	NSImage *newImage = [origImage copy];
	if( newImage )
	{
		[newImage lockFocus];
		
		//drawing
		if( [faces count] > 0 )
		{
			NSRect imgRect = NSMakeRect( 0.0, 0.0, [newImage size].width, [newImage size].height );
			NSEnumerator *faceEnum = [faces objectEnumerator];
			MPT_Face *mptFace;
			while( mptFace = [faceEnum nextObject] )
			{
				[self drawFace:mptFace inRect:imgRect];
			}
		}
		
		[newImage unlockFocus];
	}

	[super setImage:newImage];
	[newImage release];
}
@end
