/*
 * @(#)BWSolver.java
 */
package ereinionbw;

import ereinion.search.SearchExceptionFail;
import ereinion.search.SearchStats;
import ereinion.search.SNExpander;
import ereinion.search.Solver;
import ereinion.search.BaseSolver;
import ereinion.search.SearchOp;
import ereinion.search.SearchState;
import ereinion.search.SearchProblem;
import ereinion.search.SearchNode;

/*
 * classe di package : BWSolver
 *
 * Risolutore di BWProblem
 */
class BWSolver
{

	public final static String[] SEARCH_MENU = { "Width", "Depth", "Limited Depth", "Iterative Deep.", "Uniform Cost", "Greedy", "A*", "IDA*" };

	public final static String[] EXP_MENU = { "All Node", "No Parent Nodes", "No Predecessors Nodes", "No Generated States" };

	public final static String[] STATS = { "Time (milliseconds)", "Maximum Space (nodes)", "Maximum Depth", "Expanded Nodes", "Solution Depth", "Solution Cost" };


	private SearchStats stats;

	private int searchDepth, searchTimeOut, currentExpansionType, currentSearchType;

	public BWSolver()
	{
		searchDepth = Integer.MAX_VALUE;
		searchTimeOut = 0;
		currentExpansionType = 0;
		currentSearchType = 0;
	}

	public SearchNode searchSolution(BWProblem problem, SearchStats stats) throws ProblemNotInformed, SearchExceptionFail {
		stats.reset(searchTimeOut);
		SNExpander expander = new SNExpander();
		if (currentExpansionType == 1)
			expander = SNExpander.noParentExpander();
		else if (currentExpansionType == 2)
			expander = SNExpander.noPredecessorsExpander();
		else if (currentExpansionType == 3)
			expander = SNExpander.noCycleExpander();
		Solver solver = BaseSolver.makeWidthSearchSolver(expander);
		if (currentSearchType == 1)
			solver = BaseSolver.makeDepthSearchSolver(expander);
		else if (currentSearchType == 2)
			solver = BaseSolver.makeLimitedDepthSolver(expander,searchDepth);
		else if (currentSearchType == 3)
			solver = BaseSolver.makeIterativeDeepeningSolver(expander);
		else if (currentSearchType == 4)
			solver = BaseSolver.makeUniformSearchSolver(expander);
		else if (currentSearchType == 5)
			solver = BaseSolver.makeGreedySearchSolver(expander,problem.getEvalFunction());
		else if (currentSearchType == 6)
			solver = BaseSolver.makeASearchSolver(expander,problem.getEvalFunction());
		else if (currentSearchType == 7)
			solver = BaseSolver.makeIDASearchSolver(expander,problem.getEvalFunction());
		SearchNode solution = solver.search(problem.getSearchProblem(),stats);
		return solution;
	}

	public int getCurrentTimeOut() { return searchTimeOut; }

	public int getCurrentDepth() { return searchDepth; }

	public int getExpansionType() { return currentExpansionType; }

	public int getSearchType() { return currentSearchType; }

	public void setCurrentTimeOut(int value) { searchTimeOut = value; }

	public void setCurrentDepth(int value) { searchDepth = value; }

	public void setExpansionType(int value) { currentExpansionType = value; }

	public void setSearchType(int value) { currentSearchType = value; }

}
