/*

File States/Plain.m

The state object keeps track of information specific to the current state of the puzzle.  Different types of search need different types of information.  The basic state object is intended for plain depth first search.  It keeps track of squares, words, and a cache for letter counts.

*/

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

#import "Plain.h"
#import "Puzzle.h"
#import "FunctionCache.h"
#import "Crossword.h"
#import "CrosswordSquare.h"


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


#define CACHESIZE		3000


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


@implementation PlainState

- squareClass							{	return [PlainSquare  class];	}
- wordClass								{	return [PlainWord  class];		}
- getPuzzle								{	return puzzle;					}
- getWords								{	return words;					}
- getSquares							{	return squares;					}
- (FunctionCache *) getCountCache		{	return countCache;				}


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


- initPuzzle: (id) thePuzzle
{
	[super  init];
	puzzle = thePuzzle;
	countCache = [[FunctionCache  alloc]
	
			initKey: "*"
			value: "!"
			capacity: CACHESIZE
			freeKey: free
			freeValue: free ];
	
	[self  makeSquares];
	[self  makeWords];
	
	return self;
}


- free
{
	[[squares  freeObjects]  free];
	[[words  freeObjects]  free];
	[countCache  free];
	
	return [super  free];
}


- makeSquares
{
	int		i, j;
	int		rows, cols;
	id		crossword, cell;
	id		square;
	id		squareClass;
	
	[crossword = [puzzle  getCrossword]  getNumRows: &rows  numCols: &cols];
	squareClass = [self  squareClass];
	
	for (squares = [[List  alloc]  init], i = 0; i < rows; i++)
	for (j = 0; j < cols; j++)
	if ([cell = [crossword  cellAt: i: j]  isOpaque])
	{
		square = [[squareClass  alloc]  initPuzzle: puzzle  cell: cell];
		[squares  addObject: square];
		[cell  setData: square];
	}
	
	return self;
}


- makeWords
{
	int		i, j;
	id		wordSquares;
	id		wordList, squareList;
	id		word, square;
	id		wordClass;
	
	wordList = [[puzzle  getCrossword]  getWords];
	wordClass = [self  wordClass];
	i = [wordList  count];
	
	while (i--) if ([[wordList  objectAt: i]  count] >= MINLETTERS)
	{
		word = [[wordClass  alloc]  initPuzzle: puzzle];
		wordSquares = [[List  alloc]  init];
		squareList = [wordList  objectAt: i];
		j = [squareList  count];
		
		while (j--) 
		{
			square = [[squareList  objectAt: j]  getData];
			[wordSquares  addObject: square];
			[square  addToWord: word  at: j];
		}
		
		[word  setSquares: wordSquares];
	}
	
	return self;
}


@end