// HotShape.m
// By Charles G. Fleming, Educational Computing Services, Allegheny College.
// Copyright 1992 Allegheny College
// You may freely copy, distribute and reuse this code. 
// Allegheny College and the author disclaim any warranty of any kind, 
// expressed or implied, as to its fitness for any particular use.
// This work was partially supported by a grant from the Vira Heinz Endowment.

#import "HotShape.h"
#import "HotPath.h"

#import "SmallCell.h"

#import <appkit/Application.h>

#import <dpsclient/wraps.h>

#import <stdlib.h>
#import <strings.h>

#ifndef	MIN
#define	MIN(a,b) (((a)<(b))?(a):(b))
#endif	MIN

@implementation HotShape

// Scale the HotShape object so that it has unit length and height.
// Give it a custom cell so that it can be resized to an arbitrarily small
// size in Interface Builder.  The default shape will be a diamond shape.
- initFrame:(const NXRect *)frameRect
{
	SmallCell *smallCell;
	
	self = [super initFrame:frameRect];
	
	hotPathName = malloc(1);
	visible = YES;
	[self scale:bounds.size.width :bounds.size.height];

	smallCell = [[SmallCell allocFromZone:[self zone]] init];
	[self setCell:smallCell];

	setHotPaths();
	tag = 0;
	[self setHotPathName:"diamond"];
	return self;
}

- (BOOL)acceptsFirstMouse
{
	return YES;
}
	
- drawSelf:(const NXRect *)rects :(int)rectCount
{
	drawHotPath(hotPathName, visible);
	return self;
}	

- mouseDown:(NXEvent *)theEvent
{
	SEL action;
	NXEvent *nextEvent;
	BOOL done = NO;	
	int inRegion;
	NXPoint viewCoords = {theEvent->location.x, theEvent->location.y};
	
	[self convertPoint:&viewCoords fromView:nil];
	[self lockFocus];	
	inHotRegion(hotPathName, viewCoords.x, viewCoords.y, &inRegion);
	[self unlockFocus];	

	if(inRegion)
		while(!done)
		{
			nextEvent = [NXApp getNextEvent:NX_MOUSEUPMASK];
			if(nextEvent->type == NX_MOUSEUP)
			{
			    viewCoords.x = nextEvent->location.x;
				viewCoords.y = nextEvent->location.y;
				[self convertPoint:&viewCoords fromView:nil];
				
				[self lockFocus];	
				inHotRegion(hotPathName, viewCoords.x, viewCoords.y,
						&inRegion);
				[self unlockFocus];	
				
				if(inRegion)
				{
					action = [cell action];
					if(action)
						[self sendAction:action to:[cell target]];
				}
				done = YES;	
			}
		}				
	return self;	
}

- awake
{
	setHotPaths();
	return self;
}

- sizeTo:(NXCoord)width :(NXCoord)height
{
	[super sizeTo:width :height];
	[self scale:bounds.size.width :bounds.size.height];
	return self;
}

- setHotPathName:(char *)name
{
	free(hotPathName);
	hotPathName = malloc(strlen(name) + 1);
	strcpy(hotPathName, name);	
	return self;
}	

- (char *)hotPathName
{
	return hotPathName;
}
		
- (const char *)inspectorName
{
	return "HotShapeInspector";
}	

- (BOOL)visible
{
	return visible;
}

- setVisible:(BOOL)seeIt
{
	visible = seeIt;
	return self;
}	
	
- read:(NXTypedStream *)typedStream
{
	[super read:typedStream];
	NXReadTypes(typedStream, "*s", &hotPathName, &visible);
	return self;
}		

- write:(NXTypedStream *)typedStream
{
	[super write:typedStream];
	
	NXWriteTypes(typedStream, "*s", &hotPathName, &visible);
	return self;
}		
@end
