import java.util.ArrayList;
import java.util.List;

//skeleton - needs more tests
public class Tests {
   /* Your methods from Maze and Solve
  * findMarker - returns the coordinates of the character in the maze, if not in the maze (-1,-1) is returned
  * isInMaze - returns true iff the coordinate given is within the given maze
  * next - given a coordinate and a direction finds the next coordinates once that move is made, there is no assurance that the
  * isPossible - true iff the position in the maze is available for moving to
  * isValidPath - is true iff following the path on the given maze gives a correct solution
  * putPathInMaze - takes a valid path and alters the maze to show the path in the maze
  * findPath - takes a maze and returns the path through the maze, if there isn't one then the path returned is empty
  */

  public static void main(String[] args) {

    // findsMarker();

    // isInMazeOrNot();

    // goesToNextPositionInMaze();

    // isAvailablePositionOrNot();

    // isGoodPathOrNot();

    // placesPathInMaze();

    // findsPathThroughMaze();

    // put it all together - find the path, through the given maze and print the resultant maze on
    // the screen putItAllTogether();

  }

  static void findsMarker() {
    Maze maze = tinyMaze();
    char marker = '>';
    Coords expected = new Coords(1, 0);
    Coords actual = maze.findMarker('>');
    if (!actual.equals(expected)) {
      System.out.print("Maze.findMarker returned: ");
      System.out.print(actual);
      System.out.print(", expected: ");
      System.out.println(expected);
    }
  }

  static void isInMazeOrNot() {
    Maze maze = tinyMaze();
    Coords provided = new Coords(1, 0);
    boolean actual = maze.isInMaze(provided);
    if (!actual) {
      System.out.println("Maze.isInMaze returned:" + actual
          + ", expected: true");
    }
  }

  static void goesToNextPositionInMaze() {
    Maze maze = tinyMaze();
    Coords provided = new Coords(1, 0);
    Coords expected = new Coords(0, 0);
    Coords actual = maze.next(provided, Dir.N);
    if (!actual.equals(expected)) {
      System.out.print("Maze.next returned: ");
      System.out.print(actual);
      System.out.print(", expected: ");
      System.out.println(expected);
    }

  }

  /*
  static void isAvailablePositionOrNot() {
  }

  static void isGoodPathOrNot() {
  }

  static void placesPathInMaze() {
  }

  static void findsPathThroughMaze() {
  }
  */

  static void putItAllTogether() {
    Solution s1 = new Solution(tinyMaze(),null);
    s1.solve();
    Solution s2 = new Solution(lineMaze(),null);
    s2.solve();
    Solution s3 = new Solution(goodMaze(),null);
    s3.solve();
    Solution s4 = new Solution(tinyNoStartMaze(),null);
    s4.solve();
    Solution s5 = new Solution(tinyNoFinishMaze(),null);
    s5.solve();
    Solution s6 = new Solution(badMaze(),null);
    s6.solve();
  }

//sample mazes and paths suitable for test data



  public static Maze lineMaze() {
    //for debugging - this currently fails
    char[][] m = {
        {'-', 'X', '-', '-', '-', '-', '-'},
        {'>', ' ', ' ', ' ', ' ', ' ', '|'},
        {'-', '-', '-', '-', '-', '-', '-'}
    };
    Maze maze = new Maze(m);
    return maze;
  }

  public static Maze tinyMaze() {
    //for debugging - this currently fails
    char[][] m = {
        {'-', 'X', '-'},
        {'>', ' ', '|'},
        {'-', '-', '-'}
    };
    Maze maze = new Maze(m);
    return maze;
  }

  public static Maze tinyNoStartMaze() {
    //for debugging - this currently fails
    char[][] m = {
        {'-', 'X', '-'},
        {'|', ' ', '|'},
        {'-', '-', '-'}
    };
    Maze maze = new Maze(m);
    return maze;
  }

  public static Maze tinyNoFinishMaze() {
    //for debugging - this currently fails
    char[][] m = {
        {'-', '-', '-'},
        {'>', ' ', '|'},
        {'-', '-', '-'}
    };
    Maze maze = new Maze(m);
    return maze;
  }

  public static Maze goodMaze() {
    char[][] m = {
        {'-', '-', '-', '-', '-', '-', '-', '-', '-'},
        {'>', ' ', ' ', ' ', ' ', ' ', '|', 'U', '|'},
        {'|', ' ', '|', '-', '|', ' ', '|', '-', '|'},
        {'|', ' ', '|', ' ', '|', ' ', ' ', ' ', '|'},
        {'|', ' ', '|', ' ', '-', '-', '-', '-', '|'},
        {'|', ' ', ' ', ' ', '|', ' ', ' ', ' ', '|'},
        {'|', ' ', '-', '-', '|', '-', '-', ' ', '|'},
        {'|', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'X'},
        {'-', '-', '-', '-', '-', '-', '-', '-', '-'}
    };
    Maze maze = new Maze(m);
    return maze;
  }

  public static Maze solvedMaze() {
    char[][] m = {
        {'-', '-', '-', '-', '-', '-', '-', '-', '-'},
        {'#', '#', ' ', ' ', ' ', ' ', '|', 'U', '|'},
        {'|', '#', '|', '-', '|', ' ', '|', '-', '|'},
        {'|', '#', '|', ' ', '|', ' ', ' ', ' ', '|'},
        {'|', '#', '|', ' ', '-', '-', '-', '-', '|'},
        {'|', '#', ' ', ' ', '|', ' ', ' ', ' ', '|'},
        {'|', '#', '-', '-', '|', '-', '-', ' ', '|'},
        {'|', '#', '#', '#', '#', '#', '#', '#', '#'},
        {'-', '-', '-', '-', '-', '-', '-', '-', '-'}
    };
    Maze maze = new Maze(m);
    return maze;
  }

  public static Maze badMaze() {
    char[][] m = {
        {'-', '-', '-', '-', '-', '-', '-', '-', '-'},
        {'>', ' ', ' ', ' ', ' ', ' ', '|', 'U', '|'},
        {'|', ' ', '|', '-', '|', ' ', '+', '-', '|'},
        {'|', ' ', '|', ' ', '|', ' ', ' ', ' ', '|'},
        {'|', ' ', '|', ' ', '-', '-', '-', '-', '|'},
        {'|', ' ', ' ', ' ', '|', ' ', ' ', ' ', '|'},
        {'|', '-', '-', '-', '|', '-', '-', ' ', '|'},
        {'|', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'X'},
        {'-', '-', '-', '-', '-', '-', '-', '-', '-'}
    };
    Maze maze = new Maze(m);
    return maze;
  }

  public static List<Dir> tinyPath() {
    List<Dir> l = new ArrayList<Dir>();
    l.add(Dir.E);
    l.add(Dir.N);
    return l;
  }

  public static List<Dir> tinyBadPath() {
    List<Dir> l = new ArrayList<Dir>();
    l.add(Dir.N);
    l.add(Dir.E);
    return l;
  }

  public static List<Dir> goodPath() {
    List<Dir> l = new ArrayList<Dir>();
    l.add(Dir.E);
    for (int i = 0; i < 6; i++) {
      l.add(Dir.S);
    }
    for (int i = 0; i < 7; i++) {
      l.add(Dir.E);
    }
    return l;
  }

  public static List<Dir> badPath() {
    List<Dir> l = new ArrayList<Dir>();
    l.add(Dir.E);
    for (int i = 0; i < 6; i++) {
      l.add(Dir.S);
    }
    for (int i = 0; i < 6; i++) {
      l.add(Dir.E);
    }
    ;
    l.add(Dir.N);
    return l;
  }
}
