/**
 * Maze.java
 *
 * Caitlin Ross
 * 100735219
 */
 
 import java.util.*;

class Maze {
	
	//Private variables
	private Cell[][] mazeArray;
	private int numberOfRows;
	private int numberOfColumns;
	private Cell entrance;
	private Cell exit;
	
	
	//Constructors
	public Maze(){
		//Not sure if this is needed - probably not
		numberOfRows = 0;
		numberOfColumns = 0;
	}
	
	public Maze(int rows, int cols, int arr[][]){
		numberOfRows = rows;
		numberOfColumns = cols;
		mazeArray = new Cell[rows][cols];
		
		for(int i=0; i<rows; i++){
			for(int j=0; j<cols; j++){
				mazeArray[i][j] = new Cell(i, j, arr[i][j]);
			}
		}
		
		entrance = mazeArray[0][0];
		exit = mazeArray[rows-1][cols-1];
	}
	
	
	//Public methods
	public void print(){
		//Print the values of the maze array
		for(int i=0; i<numberOfRows; i++){
			for(int j=0; j<numberOfColumns; j++){
				System.out.print(mazeArray[i][j] + "  ");
			}
			System.out.println();
		}
	}
	
	public void solve(){
		Stack aStack = new Stack( );
		entrance.visited();							//Mark the entrance as visited
		aStack.push(entrance);						//Push the entrance onto the stack
		while (!aStack.empty( ))
		{
			Cell current = (Cell)aStack.peek();		//peek at a Cell to deal with
			if(current == exit){					//if the square is the exit, done, mark the solution
				markSolutionPath(aStack);
				return;
			}
			/*if(aStack.empty()){						//if the stack is empty, no path exists
				noSolution();
				break;
			}*/
			else{ 
				Cell next = getAdjacent(current);	//find a free square adjacent to the popped square
				if(next != null){					//if the square exists, mark as visited and push onto stack
					next.visited();
					aStack.push(next);
				}
				else{								//if square doesn't exist, pop current
					aStack.pop();
				}
			}
		}
		System.out.println("No solution found\n");
	}
	
	
	//Private Methods
	private void markSolutionPath(Stack s){
		while(!s.empty()){
			Cell current = (Cell)s.pop();
			current.markAsSolution();
		}
	}
	
	/*private void noSolution(){
		System.out.println("No solution found");
	}*/
	
	private Cell getAdjacent(Cell c){
		Cell check;
		//Check top
		if(c.getRow() > 0){
			check = mazeArray[c.getRow()-1][c.getColumn()];
			if(check.isFree()){
				return check;
			}
		}
		//Check right
		if(c.getColumn() < (numberOfColumns-1)){
			check = mazeArray[c.getRow()][c.getColumn()+1];
			if(check.isFree()){
				return check;
			}
		}
		//Check bottom
		if(c.getRow() < (numberOfRows-1)){
			check = mazeArray[c.getRow()+1][c.getColumn()];
			if(check.isFree()){
				return check;
			}
		}
		//Check left
		if(c.getColumn() > 0){
			check = mazeArray[c.getRow()][c.getColumn()-1];
			if(check.isFree()){
				return check;
			}
		}
		return null;
	}
}