
#import "DragView.h"
#import "Controller.h"
#import <appkit/appkit.h>

@implementation DragView

/*-------------------- methods to get things set up */

- initFrame:(const NXRect *)theFrame
{
	const char *const types[] = {NXPostScriptPboardType};
	
    [super initFrame:theFrame];
	
	//register which pasteboard types you will accept
    [self registerForDraggedTypes:(const char *const*)&types count:1];
	drawBackground = YES;
	
    return self;
}

- awakeFromNib
{	
	framed = NO;
    return self;
}

/*-------------------- methods to be the source of a dragging operation */

- mouseDown:(NXEvent *)theEvent
{
    NXPoint 	zero = {0.0, 0.0};
	NXPoint		hitPoint;
    id 			thePboard;
	
	hitPoint = theEvent->location;
    [self convertPoint:&hitPoint fromView:nil];
			
	// Prevent default window ordering (this is a new appkit feature)
    [NXApp preventWindowOrdering];

    //get the Pboard
    thePboard = [Pasteboard newName:NXDragPboard];
    [thePboard declareTypes:&NXPostScriptPboardType num:1 owner:self];
    
    //put an EPS of the image on the Pboard
	drawBackground = NO;
	[self writePSCodeInside:&hotRect to:thePboard];
	drawBackground = YES;
    
    //start the drag
    [self dragImage:epsIcon		// visable on screen during drag
		at:& hotRect.origin    	// offset the mouse point for the drag
		offset:&zero			// offset the inital mouse pt
		event:theEvent			// theEvent structure
		pasteboard:thePboard	// a Pasteboard with data on it
		source:self				// source object
		slideBack:YES];			// if no destination animate back to source
	
    return self;
}

- draggedImage:(NXImage *)image beganAt:(NXPoint *)screenPoint
{
	return self;
}

- (NXDragOperation)draggingSourceOperationMaskForLocal:(BOOL)flag
{	
    return (NX_DragOperationCopy | NX_DragOperationGeneric);
}


/*-------------------- methods to display, and other useful stuff */

- (BOOL)acceptsFirstMouse
{
    return YES;
}

- (BOOL)acceptsFirstResponder
{
    return YES;
}

- (BOOL)shouldDelayWindowOrderingForEvent:(NXEvent *)theEvent
{
 	// This is the other portion of the new appkit functionality
	// which allows you to drag a partially obscure object without
	// making the source window become main, and without making the
	// source application the current app.
    return YES;
}


- setImage:(id)anImage
{
    // free epsIcon it if is been used
	if(epsIcon) [epsIcon free];
	
	framed = NO;
	epsIcon = anImage;
	[epsIcon getSize:&(hotRect.size)];
    hotRect.origin.x = floor((NX_WIDTH(&bounds) - NX_WIDTH(&hotRect)) / 2.0);
    hotRect.origin.y = floor((NX_HEIGHT(&bounds) - NX_HEIGHT(&hotRect)) / 2.0);
    [self display];

	return self;
}

- drawSelf:(const NXRect *)rects :(int)num
{	
	// if we are copying the PS code onto the Pboard, then we don't want
	// the white background.  Only the image.
    if (drawBackground) NXEraseRect(rects);
	
	// Composite the image into the view.
    [epsIcon composite:NX_SOVER toPoint:&hotRect.origin];
	
	// if we are in the middle of a drag operation then we can frame the
	// view rect to show our acceptance of the incomming data.  Another way
	// would be to create a ghost image similar to the shelf in Workspace.
	if(framed) {
		NXFrameRectWithWidth(&bounds, (NXCoord)3.0);
	}
    return self;
}

- copy:sender
{
	id pBoard = [Pasteboard new];
	[pBoard declareTypes:&NXPostScriptPboardType num:1 owner:self];
	[self writePSCodeInside:&hotRect to:pBoard];
	return self;
}

- free
{
	// be a good object and free things up
	[epsIcon free];
	return [super free];
}

@end
