/*

File CrosswordSquare.m

Crossword squares are the elements of a crossword matrix.  Each square is either transparent, in which case it appears as black, or contains a letter.  A square with a letter may be drawn using any color combination.  A square can also display a clue number in its upper left hand corner.

*/

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

#import "CrosswordSquare.h"
#import "CrosswordSquarePS.h"
#import "Crossword.h"


/* 行行行行行行行行行行行行行行行行行行行行行行行行行行行行行行行行行行行行行行  */


#define VERSION			1


/* 行行行行行行行行行行行行行行行行行行行行行行行行行行行行行行行行行行行行行行  */


@implementation CrosswordSquare

- (BOOL) isOpaque			{	return opaque;		}
- (char) getLetter			{	return letter;		}
- (int) getNumber			{	return number;		}
- (squareColor) getColor	{	return color;		}
- (id) getData				{	return data;		}

- setLetter: (char) theLetter		{	letter = theLetter;		return self;	}
- setNumber: (int) theNumber		{	number = theNumber;		return self;	}
- setColor: (squareColor) theColor	{	color = theColor;		return self;	}
- setData: (id) theData				{	data = theData;			return self;	}


/* 行行行行行行行行行行行行行行行行行行行行行行行行行行行行行行行行行行行行行行  */


/*

There are currently two different versions of crossword squares that need to be unarchived.

*/

+ initialize
{
    [CrosswordSquare  setVersion: VERSION];
	
	return self;
}


- init
{
	[super  init];
	
	opaque = YES;
	color.background = NXConvertGrayToColor(1.0);
	color.text = NXConvertGrayToColor(0.0);
	letter = number = EMPTY;
	
	return self;
}


- write: (NXTypedStream *) stream
{
	[super  write: stream];
    
	NXWriteTypes(stream, "cci", &opaque, &letter, &number);
	NXWriteColor(stream, color.background);
	NXWriteColor(stream, color.text);
	
	return self;
}


- read: (NXTypedStream *) stream
{
	[super  read: stream];
    switch (NXTypedStreamClassVersion(stream, "CrosswordSquare"))
	{
		case 1:
			NXReadTypes(stream, "cci", &opaque, &letter, &number);
			color.background = NXReadColor(stream);
			color.text = NXReadColor(stream);
			break;
		
		default:
			break;
	}
	
	return self;
}


- readOld: (NXTypedStream *) stream
{
	[super  read: stream];
	NXReadTypes(stream, "cc", &opaque, &letter);
	color.background = NXReadColor(stream);
	color.text = NXReadColor(stream);
	
	return self;
}


/* 行行行行行行行行行行行行行行行行行行行行行行行行行行行行行行行行行行行行行行  */


/*

Here are the routines that concern drawing and tracking the mouse.  The user can fill and erase squares symmetrically across the puzzle by holding down one of the modifier keys.  Squares are drawn using two colors: one for the background, one for the text.

*/

- (BOOL) startTrackingAt: (NXPoint *) point  inView: (id) matrix
{
	int		r, c;
	int		h, w;
	
	[self  paint: matrix];
	if ([matrix  mouseDownFlags] & (NX_ALTERNATEMASK | NX_SHIFTMASK))
	{
		[matrix  getRow: &r  andCol: &c  ofCell: self];
		[matrix  getNumRows: &h  numCols: &w];
		[[matrix  cellAt: (h - r - 1): (w - c - 1)]  paint: matrix];
	}
	
	return NO;
}


- paint: (id) matrix
{
	if (opaque != [matrix  getFill])
	{
		opaque = !opaque;
		[matrix  drawCell: self];
	}
	
	return self;
}


- drawInside: (const NXRect *) frame  inView: (id) matrix
{
	id		font;

	if (opaque)
	{
		[matrix  lockFocus];
		[font = [matrix  font]  set];
		
		NXSetColor(color.background);
		NXRectFill(frame);
		NXSetColor(color.text);
		
		PSWdrawSquare(
	
				letter,
				number,
				frame->origin.x,
				frame->origin.y,
				frame->size.width,
				[font  metrics]->capHeight * [font  pointSize] );
		
		[matrix  unlockFocus];
	}
	
	return NO;
}


@end