package game;

import exception.PlacementFailedException;

/**
 * This class creates a 2d array of squares and keeps track of the piece
 * locations, win conditions, and text display.
 */
public abstract class CharBoard {
	/**
	 * board a 2d array of characters that keep track of the pieces on the board
	 */
	private Square[][] board;

	/**
	 * This constructor takes the size of the board and Initializes the board.
	 * 
	 * @param size
	 */
	public CharBoard(int size) {
		board = new Square[size][size];

		initializeBoard();
	}

	/**
	 * This method sets the board the the position that it should initially be
	 * for the game that is running. The default version is turning every square
	 * into an empty square.
	 */
	public void initializeBoard() {
		for (int j = 0; j < board.length; j++)
			for (int i = 0; i < board[j].length; i++)
				board[j][i] = new Square(' ');
	}

	/**
	 * This method attempts to place the piece on the coordinate. If the
	 * placement fails, then it throws an exception.
	 * 
	 * @return if the piece was successfully placed or not
	 */
	public void attemptPlace(PieceType piece, Coordinate c) {
		if (canPlace(piece, c)) {
			place(piece, c);
		} else {
			throw new PlacementFailedException("The piece cannot be placed on square \"" + c.toAlphaNumerical() + '\"');
		}
	}

	/**
	 * This method places a piece on the square the coordinates corresponds to
	 * without verification.
	 * 
	 * @param piece
	 *            the piece that will be placed
	 * @param c
	 *            the coordinates of the square the piece will be placed on
	 */
	public void place(PieceType piece, Coordinate c) {
		board[c.getX()][c.getY()].setChar(piece.getChar());
	}

	/**
	 * This method verifies that a piece can be placed on this square.
	 * 
	 * @param piece
	 *            the piece that will be checked
	 * @param c
	 *            the coordinates the piece will be checked on
	 * @return if the piece can be placed on the coordinate
	 */
	public abstract boolean canPlace(PieceType piece, Coordinate c);

	/**
	 * This method tells the user if the square has no piece on it.
	 * 
	 * @param c
	 *            the coordinate
	 * @return if the coordinate is empty
	 */
	public boolean isEmpty(Coordinate c) {
		return board[c.getX()][c.getY()].getChar() == ' ';
	}

	/**
	 * For every column, put a number. For every row, put a letter. Place the
	 * single letter representation of the piece inside the grid.
	 * 
	 * @return a text created board with all the square names and pieces on the
	 *         squares shown.
	 */
	public String toString() {
		String out = " ";
		out += labelEachColumn();
		out += "\n";
		out += printAllRows();
		out += "\n";

		return out;
	}
	
	private String labelEachColumn() {
		String out = "";
		for (int i = 1; i <= board.length; i++)
			out += " " + (i % 10 == 0 ? i / 10 : i % 10);
		return out;
	}
	
	private String printAllRows() {
		String out = "";
		for (int j = 0; j < board[0].length; j++) {
			out += printRowLabel(j) + " ";
			out += printBoardRow(j) + "\n";
			out += printRowDivider(!isBottomRow(j)) + "\n";
		}
		return out;
	}

	private String printRowLabel(int row) {
		return "" + (char)('A'+row);
	}
	
	private String printBoardRow(int j) {
		String out = "" + board[j][0].getChar();
		for (int i = 1; i < board.length; i++) {
			out += "|" + board[j][i].getChar();
		}
		return out;
	}
	
	private String printRowDivider(boolean shouldPrint) {
		if(shouldPrint) {
			String out = "  -";
			for (int i = 1; i < board.length; i++)
				out += "--";
			return out;
		}
		else {
			return "";
		}
	}

	private boolean isBottomRow(int row) {
		return board.length -1 == row;
	}
	
	/**
	 * This method detects if the game has ended and returns a notification a
	 * character that corresponds to the state of the game.
	 */
	public abstract char gameEnd();

	/**
	 * This method detects if the square at a coordinate exists.
	 * 
	 * @return if the square exists
	 */
	public boolean squareExists(Coordinate out) {
		return out.getX() >= 0 && out.getX() < board[0].length && out.getY() >= 0 && out.getY() < board.length;
	}

	/**
	 * This method returns the board that the game is placed on.
	 * 
	 * @return the board
	 */
	public char[][] getCharBoard() {
		char[][] out = new char[board.length][board[0].length];
		for (int j = 0; j < board.length; j++)
			for (int i = 0; i < board[j].length; i++)
				out[j][i] = board[j][i].getChar();
		return out;
	}
}
@@ -2707,27 +2707,18 @@
 Column()
-;%0D%0A%09%09out
  +
-=
  %22%5Cn%22;%0D%0A
@@ -2740,27 +2740,18 @@
 llRows()
-;%0D%0A%09%09out
  +
-=
  %22%5Cn%22;%0D%0A
@@ -2769,37 +2769,39 @@
 out;%0D%0A%09%7D%0D%0A%09%0D%0A%09pr
-ivate
+otected
  String labelEac
@@ -2891,16 +2891,113 @@
 += %22 %22 +
+ labelColumn(i);%0D%0A%09%09%0D%0A%09%09return out;%0D%0A%09%7D%0D%0A%09%0D%0A%09protected String labelColumn(int i) %7B%0D%0A%09%09return %22%22 +
  (i %25 10
@@ -3027,38 +3027,24 @@
 );%0D%0A
-%09%09return out;%0D%0A
 %09%7D%0D%0A
-%09
 %0D%0A%09pr
-ivate
+otected
  Str
@@ -3280,29 +3280,31 @@
 ;%0D%0A%09%7D%0D%0A%0D%0A%09pr
-ivate
+otected
  String prin
@@ -3359,37 +3359,39 @@
 ow);%0D%0A%09%7D%0D%0A%09%0D%0A%09pr
-ivate
+otected
  String printBoa
@@ -3564,21 +3564,23 @@
 %0D%0A%09%0D%0A%09pr
-ivate
+otected
  String 
@@ -3785,21 +3785,23 @@
 %7D%0D%0A%0D%0A%09pr
-ivate
+otected
  boolean

change toString methods to proctected