/*

File Puzzle.m

The puzzle object links a crossword matrix to a dictionary and a search.  The puzzle has various inspectable parameters that the user can set to control the type of search.

*/

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

#import "Puzzle.h"
#import "Inspector.h"
#import "StopWatch.h"
#import "Crossword.h"
#import "CrosswordSquare.h"
#import "FunctionCache.h"

#import "PlainState.h"
#import "BackjumpState.h"
#import "LeapfrogState.h"
#import "DepthFirstSearch.h"
#import "BroadeningSearch.h"


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


#define PLAIN		0
#define BACKJUMP	1
#define LEAPFROG	2


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


@implementation Puzzle

- getCrossword			{	return crossword;		}
- getInspector			{	return inspector;		}
- getDictionary			{	return dictionary;		}
- getState				{	return state;			}
- (BOOL) canContinue	{	return canContinue;		}


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


- free
{
	[dictionary  free];
	[search  free];
	[state  free];
	
	return [super  free];
}


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


/*

Here are the routines that put together the search.  The biggest step is extracting the squares and words from the puzzle.  Then the search is initialized and executed.

*/

- newSearch: sender
{
	id				stateType, searchType;
	StopWatch		* watch;
	
	[search  free];
	[state  free];
	[crossword  clear: [inspector  getColor: 0]];
	
	switch ([inspector  getStateType])
	{
		case PLAIN:		stateType = [PlainState  class];		break;
		case BACKJUMP:	stateType = [BackjumpState  class];		break;
		case LEAPFROG:	stateType = [LeapfrogState  class];		break;
		default:		stateType = nil;						break;
	}
	
	switch ([inspector  getOption: BROADENING])
	{
		case NO:	searchType = [DepthFirstSearch  class];		break;
		case YES:	searchType = [BroadeningSearch  class];		break;
		default:	searchType = nil;							break;
	}
	
	[search = [searchType  alloc]  init];
	[state = [stateType  alloc]  initPuzzle: self];
	[[watch = [inspector  getWatch]  reset]  start];
	canContinue = [search  startSearch: [state  getSquares]];
	
	[watch  stop];
	[inspector  showTime];
	
	return self;
}


- continue: sender
{
	StopWatch		* watch;
	
	[watch = [inspector  getWatch]  start];
	canContinue = [search  continue];
	[watch  stop];
	[inspector  showTime];
	
	return self;
}


- step: sender
{
	StopWatch		* watch;
	
	[watch = [inspector  getWatch]  start];
	canContinue = [search  step];
	[watch  stop];
	[inspector  showTime];
	
	return self;
}


@end