
#import "AbstractSquare.h"

@implementation AbstractSquare

- (short) column {
    return column;
}

- (short) distanceTo: otherSquare {
    return MAX(ABS([self  row ]  - [otherSquare  row ]),
	       ABS([self column] - [otherSquare column]));
}

- drawSelf: (const NXRect *) rects : (int) rectCount {
    [super drawSelf: rects : rectCount];
    NXDrawGrayBezel(&bounds, rects);
    if ([self isHighlighted])
	[self highlight: rects];
    return self;
}

- (BOOL) isHighlighted {
    return isHighlighted;
}

- mouseExited: (NXEvent *) theEvent {
    if ([self isHighlighted])
	[self setIsHighlighted: NO];
    return self;
}

- (short) row {
    return row;
}

- setIsHighlighted: (BOOL) state {
    if (isHighlighted = state)
	[[self window] setHighlightedSquare: self];
    return [self display];
}

/* Private methods: */

- awake {				/* added since I.B. palette objects */
    return [self initFrame: &frame];	  /* never get sent an initFrame: */
}			    /* (we want to allow NIBs created via palettes) */

- appDidInit {
    return [self appDidInitInside: NO];
}

- appDidInitInside: (BOOL) state {
    return [self setTrackingRect: &frame inside: state];
}

- become: newSquareClass {
    BOOL  wasHighlighted = [self isHighlighted];
    id    theSuperView = [self superview];
    id    newSquare = [[newSquareClass alloc] initFrame: &frame];

    [[[self freeTrackingRect] removeFromSuperview] free];
    [theSuperView addSubview: newSquare];
    return [newSquare appDidInitInside: wasHighlighted];
}

- capture: sender {
    return self;
}

- checkAdjacencyWith: sender {
    return self;
}

- free {
    if ([self isHighlighted])
	[[self window] setHighlightedSquare: nil];
    return [super free];
}

- freeTrackingRect {
    if (trackingRectNumber > 0)
	[[self window] discardTrackingRect: trackingRectNumber];
    return self;
}

#define INSET  2
#define WIDTH  7

- highlight: (const NXRect *) aRect {
    NXRect  theRect = *aRect;

    NXInsetRect(&theRect, INSET, INSET);
    PSsetgray(NX_DKGRAY);
    NXFrameRectWithWidth(&theRect, WIDTH);
    return self;
}

- initFrame: (const NXRect *) frameRect {
    [super initFrame: frameRect];	/* the below only works with small */
    row    = frameRect->origin.y / frameRect->size.height; 	/* borders */
    column = frameRect->origin.x / frameRect->size.width;
    return self;
}

- setTrackingRect: (const NXRect *) aRect inside: (BOOL) state {
    static int  rectNumber = 1;
    NXRect      winRect = *aRect;

    trackingRectNumber = rectNumber;
    [[self superview] convertRect: &winRect toView: nil];
    [[self window] setTrackingRect: &winRect
		   inside: state	/* cursor is inside/outside rect */
		   owner: self tag: rectNumber++ left: NO right: NO];
    return self;
}

@end
