#import <appkit/appkit.h>
// #import <dpsclient/psops.h>
// #import <dpsclient/wraps.h>

#import "ImageView.h"
#import "PhotoWinProcs.h"
#import "Controller.h"		// for nextPasteCounter...

@implementation ImageView

- initForImage:(id)img :(const NXRect *)rect;
{
    NXSize  sz;
    
    self = [super initFrame:rect];
    
    theImage = img;
    sz.width = [theImage pixelsWide];
    sz.height = [theImage pixelsHigh];
    [self sizeTo:sz.width :sz.height];
    selectRect.size.width = 0; selectRect.size.height = 0;
    
    return self;
}

- (BOOL)acceptsFirstResponder
{
    return YES;
}

- (BOOL)acceptsFirstMouse
{
    return YES;
}

- (id) image
{
    return theImage;
}
	
- drawSelf:(const NXRect *)rects :(int)rectCount
{
    [theImage draw];
    return self;
}



#define DRAG_MASK (NX_MOUSEUPMASK|NX_MOUSEDRAGGEDMASK)
- mouseDown:(NXEvent *)event
{
    NXPoint	p, start, last, maxBound;
    NXSize	imSize, imPixelSize;
    static const NXPoint hot = {7., 7.};
    int		oldMask;
    BOOL	doAlternateDrag = NO;
    NXCoord	faceTiffSize = 64.0, altDragSize = 0;
    static id	crossCursor = nil;
    
    [theImage getSize:&imSize];
    imPixelSize.width = [theImage pixelsWide];
    imPixelSize.height = [theImage pixelsHigh];

    if (NX_ALTERNATEMASK &  event->flags) {
	doAlternateDrag = YES;
	altDragSize = faceTiffSize;
	maxBound.x = imSize.width;
	maxBound.y = imSize.height - altDragSize;
	[self convertPoint:&maxBound fromView:nil];
	}
        
    oldMask = [window addToEventMask:NX_MOUSEDRAGGEDMASK|NX_MOUSEUPMASK];
    if( !crossCursor ) {
	crossCursor = [[NXCursor alloc] initFromImage:
			  [[NXImage alloc] initFromSection:"cross.tiff"]];
	[crossCursor setHotSpot:&hot];
    }
    [crossCursor push];
    p = start = event->location;
    [self convertPoint:&start fromView:nil];
    last = start;

    [self lockFocus];
       
    PSsetlinewidth(0.0);
    PSsetinstance(YES);
    event = [NXApp getNextEvent:DRAG_MASK];
       
    while( event->type != NX_MOUSEUP ) {
	p = event->location;
	[self convertPoint:&p fromView:nil];
	PSnewinstance();
	if( p.x != last.x || p.y != last.y ) {
	    PSsetinstance(YES);
	    PSsetgray(1.0);
	    if ( doAlternateDrag ) {
		start = p;
		if ( start.x < altDragSize ) start.x = altDragSize;
		if ( start.y < 0 ) start.y = 0;
		if ( start.x > maxBound.x ) start.x = maxBound.x;
		if ( start.y > maxBound.y ) start.y = maxBound.y;
		PSrectstroke(start.x, start.y,
			     - (altDragSize + 1), (altDragSize + 1) );
		}
	    else {
		PSrectstroke(start.x, start.y,
			     (p.x - start.x),
			     (p.y - start.y));
		}
	    PSsetinstance(NO);
	    last = p;
	    NXPing();
	    }
	p = event->location;
	event = [NXApp getNextEvent:DRAG_MASK];
    }
	    
    [self convertPoint:&p fromView:nil];
    selectRect.origin.x = start.x; selectRect.origin.y = start.y;
    if ( doAlternateDrag ) {
	selectRect.size.width  = -altDragSize;
	selectRect.size.height = altDragSize;
	}
    else {
	selectRect.size.width  = p.x - start.x; 
	selectRect.size.height = p.y - start.y;
	}

    [self unlockFocus];
    [window flushWindow];
    [window setEventMask:oldMask];
    [crossCursor pop];

    return self;
}

- copy:sender
{
    NXStream	*st;
    NXBitmapImageRep *bm;
    int		i = 0;
    const char	*types[2];
    id		pb = [Pasteboard new];
    
    //	note that "owner:" in the following can not be "self", or the
    //    id of anything else which might be freed inbetween "Copy"
    //	  operations.
    types[i++] = NXTIFFPboardType;
    [pb declareTypes:types num:i owner:NXApp];

    [self lockFocus];
    bm = [[NXBitmapImageRep alloc] initData:NULL fromRect:&selectRect];
    [self unlockFocus];

    st = NXOpenMemory(NULL, 0, NX_WRITEONLY);
    [bm writeTIFF:st];
    [pb writeType:NXTIFFPboardType fromStream:st];
    NXCloseMemory(st, NX_FREEBUFFER);
    [bm free];

    return self;
}

- paste:sender
{
    NXStream 	*st;
    char	tmpName[40];
    int		pasteCount;
    id  	pb;

    pb = [Pasteboard new];	
    (void)[pb types];
    st = [pb readTypeToStream:NXTIFFPboardType];
    
    pasteCount = [[NXApp delegate] nextPasteCounter];
    sprintf(tmpName, "%d_PasteImage", pasteCount);
    
    [[window delegate]
    		displayImage: [[NXBitmapImageRep alloc] initFromStream:st]
		withName:tmpName  atResolution:0];
    NXCloseMemory(st, NX_FREEBUFFER);

    return self;
}

@end