
/* Generated by Interface Builder */

#import "DragCoordinator.h"
#import	"CardHolder.h"
#import	"GameCoordinator.h"
#import	"StackView.h"
#import	<appkit/View.h>
#import	<objc/List.h>


												// Recursivly search through the view hierarchy looking
												//	for a tracking view.
	static CardHolder	*findTrackingView( View * , const NXPoint *  );
	

@implementation DragCoordinator

- setTarget:anObject
{
    target = anObject;
    return self;
}

- cardDragged:( const NXPoint * )dragPoint
{

	CardHolder	*receivingView = findTrackingView([ gameWindow contentView ], dragPoint );
	
	
													// Handle highlighting.
													//	If you notice very carefully I send messages to the
													//	value nil.  Doesn't bother me.  Bother you?
	if( receivingView ) {
													
													// We're over a tracking view.
													//	Unhighlight the old tracking view and highlight
													//	the new view--if they're different.
		if( currentTrackView != receivingView ) {
			[ currentTrackView	trackingHighlighted:NO ];
			[ receivingView		trackingHighlighted:YES ];
			currentTrackView = receivingView;
		}
	} else {
	
													// We're not over a tracking view.  
													//	Unhighlight the old tracking view.
		[ currentTrackView trackingHighlighted:NO ];
		currentTrackView = nil;
	}
	
	return self;
}


- cardReleased:aCard at:( const NXPoint * )releasePoint
{

	CardHolder	*receivingView = findTrackingView([ gameWindow contentView ], releasePoint );
	
	
	if( receivingView ) {
		CardHolder	*oldHolder = [[ aCard superview ] baseHolder ],
					*newHolder = [ receivingView baseHolder ];
					
													// Inform the target of the card movement.
													//	It will decide if the move is valid and if so it
													//	will perform the view disconnect/connect.
		[ target card:aCard movedFrom:oldHolder to:newHolder ];
	} else
													// Card wasn't released over a tracking view.
													//	Beep.
		NXBeep ();

													// Unhighlight the previous tracking view.
	[ currentTrackView trackingHighlighted:NO ];
	currentTrackView = nil;

	return self;
}


													// Hits are tricky things.
													//	If you're moving a card over a stack then the
													//	hitTest: method will return the stack;  Hovever, if
													//	there is a card on the stack the hitTest: method
													//	returns the card.  Therefore, the view returned
													//	by hitTest: is recursivly searched until the ultimate
													//	goal is reached.
													// We're looking for a view under the cursor that
													//	is a enabled tracking view.
static CardHolder	*findTrackingView( View *view, const NXPoint *windowPoint )
{

	CardHolder	*theView = nil,
				*hitView = [ view hitTest:windowPoint ];
	

	if([ hitView respondsTo:@selector(isTrackingEnabled) ])
		if([ hitView isTrackingEnabled ])
			theView = hitView;

	if( !theView ) {
		do {
			if( hitView = [ hitView superview ]) {
				NXRect		boundsRect;
				NXPoint		mousePoint = *windowPoint;
					
				if([[[ hitView getBounds:&boundsRect ] convertPoint:&mousePoint fromView:nil ] mouse:&mousePoint inRect:&boundsRect ]) 
					if([ hitView respondsTo:@selector(isTrackingEnabled) ])
						if([ hitView isTrackingEnabled ])
							theView = hitView;
			}
		} while( !theView && hitView );
	}
	
	return theView;
}


@end
