
/* Generated by Interface Builder */

#import "CardView.h"
#import	"CardHolder.h"
#import	"cards.h"
#import	<appkit/appkit.h>
#import	<assert.h>
#import	<mach.h>


	CardImage	*topFaceBitmap = nil;

	Window		*compositeWindow = nil;

	NXZone		*cardZone = NULL;
	
	
@implementation CardView


+ initialize
{


	if( !cardZone )
		cardZone = NXCreateZone( vm_page_size, vm_page_size, YES );
	assert( cardZone );
	
	if( !topFaceBitmap )
		topFaceBitmap = [[ CardImage allocFromZone:cardZone ] initFromFile:TOP_FACE ];
	assert( topFaceBitmap );
	
	if( !compositeWindow ) {
		NXRect	windowFrame = { 0, 0, CARD_WIDTH, CARD_HEIGHT };
	
		compositeWindow = [ Window newContent:&windowFrame 
								style:NX_PLAINSTYLE 
								backing:NX_RETAINED 
								buttonMask:0 
								defer:NO ];
	}
	
	return nil;
}


- init
{

	NXRect	cardFrame = { 0, 0, CARD_WIDTH, CARD_HEIGHT };


	[ super init ];
	showTopFaceFlag 	= YES;
	eventsEnabledFlag	= NO;
	[[ self setFrame:&cardFrame ] setClipping:NO ];

	return self;
}


- free
{

	[ bottomFaceBitmap free ];
	
	return [ super free ];
}


- setEventsEnabled:( BOOL )flag
{

	eventsEnabledFlag = flag;
	
	return self;
}


- mouseDown:( NXEvent * )theEvent
{


	if( eventsEnabledFlag ) {
		NXRect	windowFrame;
		NXPoint	cardLocation = bounds.origin;
	
												// Composite our card face to the composite window.
												//	Bring the window to the location of this view.
		[[ compositeWindow contentView ] lockFocus ];
		[[ compositeWindow contentView ] getFrame:&windowFrame ];
		[ self drawSelf:&windowFrame : 1 ];
		[[ compositeWindow contentView ] unlockFocus ];
		[ self convertPoint:&cardLocation toView:nil ];
		[ window convertBaseToScreen:&cardLocation ];
		[[ compositeWindow moveTo: cardLocation.x : cardLocation.y ] orderFront:nil ];
	
												// Add dragging to the window's mask and save the old
												//	mask to be restored when the mouse is released.
												//	This is not necessarily a good programming technique.
												//	(Bad programming on my part. For instance, what if 
												//	some other object, like one responding to the tracking
												//	rect altered the mask?  i'd clobber it when it is 
												//	restored in the mouseUp: method.).
		oldMask = [ window addToEventMask:NX_MOUSEDRAGGEDMASK ];
	
												//	Calculate the delta offset within the card's view
												//	for easy arithmetic while the card is being dragged.
		cardDelta = theEvent->location;
		[ self convertPoint:&cardDelta fromView:nil ];
	} else
		[[ self nextResponder ] mouseUp:theEvent ];
	
	return self;
}


- mouseUp:( NXEvent * )theEvent
{

	if( eventsEnabledFlag ) {
		[ window setEventMask:oldMask ];
		[ compositeWindow orderOut:self ];
		[ dragCoordinator cardReleased:self at:&theEvent->location ];
	} else
		[[ self nextResponder ] mouseUp:theEvent ];
		
	return self;
}


- mouseDragged:( NXEvent * )theEvent
{

			
	if( eventsEnabledFlag ) {
		NXPoint		currentPoint = theEvent->location;
		
		[ window convertBaseToScreen:&currentPoint ];
		[ compositeWindow moveTo:currentPoint.x - cardDelta.x : currentPoint.y - cardDelta.y ];
		[ dragCoordinator cardDragged:&theEvent->location ];
	} else
		[[ self nextResponder ] mouseUp:theEvent ];

	return self;
}


- setDragCoordinator:( DragCoordinator * )anObject
{

	dragCoordinator = anObject;

	return self;
}


- setShowTopFace:( BOOL )flag
{

	showTopFaceFlag = flag;
	
	return self;
}


- drawSelf:( const NXRect * )rects :( int )rectCount
{

	BOOL	performDraw = YES;
	
	
	if([ superview respondsTo:@selector(subviewVisible:)])
		if( ![ superview subviewVisible:self ])
			performDraw = NO;
	
	if( performDraw ) {
		if( showTopFaceFlag )
			[ topFaceBitmap composite:NX_SOVER toPoint:&bounds.origin ];
		else {
			assert( bottomFaceBitmap );
			[ bottomFaceBitmap composite:NX_SOVER toPoint:&bounds.origin ];
		}
	}
	
	return self;
}


@end
