package examples.maze;


public class MazeUtility {
  private final static int right = 1, left = 3, up = 2, down = 0;
  private static int w = 0;
  private static int h = 0;

  private static String mazeString[] = null;
  private static char maze[][] = null;

  public static void setMazeString(String ms[]) {
    mazeString = ms;
    maze = getChars(mazeString);
  }

  public void setMaze(char c[][]) {
    maze = c;
  }


  public static char[][] getChars(String s[]) {
    char c[][] = new char[s.length][s[0].length()];
    for (int r = 0; r < s.length; r++)
      s[r].getChars(0, s[0].length(), c[r], 0);

    return c;
  }

  public static void print() {
    char c[][] = maze;
    for (int r = 0; r < c.length; r++) {
      for (int col = 0; col < c[r].length; col++)
        System.out.print(c[r][col]);
      System.out.println();
    }
  }

  public static java.awt.Point getStart() {
    for (int r = 0; r < maze.length; r++)
      for (int c = 0; c < maze[0].length; c++)
        if (maze[r][c] == 'S')
          return new java.awt.Point(r, c);
    return new java.awt.Point(0, 0);
  }

  public static java.awt.Point getExit() {
    return new java.awt.Point(6, 16);
  }

  public static void markExit(java.awt.Point p) {
    maze[p.x][p.y] = 'E';
  }

  public static boolean isDone(
      char maze[][],
      java.awt.Point p) {
    return maze[p.x][p.y] == 'E';
  }

  public static void markStart(
      java.awt.Point p) {
    maze[p.x][p.y] = 'S';
  }

  public static void mark(java.awt.Point p) {
    maze[p.x][p.y] = 'X';
  }

  public static void solve() {
    java.awt.Point start = getStart();
    //System.out.println("Start="+start);
    //Point exit = getExit();
    //System.out.println("Exit="+exit);
    //markStart( start);
    //markExit(exit);
    mazeTraverse(start, left);
  }

  public static void mazeTraverse(java.awt.Point loc, int direction) {
    if (isDone(maze, loc)) {
      System.out.println("I am done!");
      return;
    }
    w = maze.length;
    h = maze[0].length;
    int x = loc.x;
    int y = loc.y;
    mark(loc);
    for (int move = direction, count = 0; count < 4; ++count, ++move, move %= 4) {
      switch (move) {
        case down:
          if (validMove(x + 1, y)) {
            mazeTraverse(new java.awt.Point(x + 1, y), left);
            return;
          }
          break;
        case right:
          if (validMove(x, y + 1)) {
            mazeTraverse(new java.awt.Point(x, y + 1), down);
            return;
          }
          break;
        case up:
          if (validMove(x - 1, y)) {
            mazeTraverse(new java.awt.Point(x - 1, y), right);
            return;
          }
          break;
        case left:
          if (validMove(x, y - 1)) {
            mazeTraverse(new java.awt.Point(x, y - 1), up);
            return;
          }
          break;
      }

    }
  }

  public static boolean validMove(int r, int c) {
    return (r >= 0 && r <= w && c >= 0 && c < h && maze[r][c] != '#');
  }

  public static int getRight() {
    return right;
  }

  public static int getLeft() {
    return left;
  }

  public static int getUp() {
    return up;
  }

  public static int getDown() {
    return down;
  }

  public static int getW() {
    return w;
  }

  public static void setW(int w) {
    MazeUtility.w = w;
  }

  public static int getH() {
    return h;
  }

  public static void setH(int h) {
    MazeUtility.h = h;
  }

  public static String[] getMazeString() {
    return mazeString;
  }

  public static char[][] getMaze() {
    return maze;
  }

}