/*******************************************************************************
Main Class:			Concentration

Author:				Rebecca Hasti, hasti@cs.wisc.edu
					copyright 2000, all rights reserved
Course:				CS 302, Summer 2000

Compiler:			Metrowerks CodeWarrior (JDK 1.2)
Platform:			Windows NT 4.0 (or Windows 95)
*******************************************************************************/

/**
 * Represents a 4 X 13 board of cards.  The cards can be either face up or face 
 * down.  Cards can also be removed from the board.
 *
 * Bugs:	none known
 **/
public class Board {

	////////////////////////////////////////
	// Data Members
	////////////////////////////////////////
	private GameCard[][] board;       // the grid of game cards
	private int cardsLeft;            // the number of cards left on the board
	private static int NUM_ROWS = 4;  // number of rows in the board
	private static int NUM_COLS = 13; // number of columns in the board
	
	////////////////////////////////////////
	// Constructor
	////////////////////////////////////////
	
	/**
	 * Constructs a Board object.  The board is initialized to be a 4 x 13 grid 
	 * of face down game cards.  
	 **/	
	public Board() {
		board = new GameCard[NUM_ROWS][NUM_COLS];
		cardsLeft = 52;
		Deck deck = new Deck();
		deck.shuffle();
		for (int i = 0; i < board.length; i++)
			for (int j = 0; j < board[i].length; j++) 
				board[i][j] = new GameCard(deck.deal(), false);
	}
	
	////////////////////////////////////////
	// Public Methods
	////////////////////////////////////////

	/**
	 * Returns the card at the given row and column.  If the position is 
	 * invalid, null is returned.
	 *
	 * @param row the row index (starting at 0)
	 * @param col the column index (starting at 0)
	 * @return the card at (row, col); null if (row, col) is not valid
	 **/
	public GameCard getCard(int row, int col) {
		if (invalidBoardPosition(row, col)) 
			return null;
		else
			return board[row][col];
	}
	
	/** 
	 * Removes the card at the given row and column.  If the position is
	 * invalid or there is no card in that position, false is returned; 
	 * otherwise, true is returned.
	 * 
	 * @param row the row index (starting at 0)
	 * @param col the column index (starting at 0)
	 * @return true if a card was sucessfully removed; false otherwise
	 **/
	public boolean removeCard(int row, int col) {
	
		if (invalidBoardPosition(row, col) ||
			board[row][col] == null)
			return false;
			
		board[row][col] = null;
		cardsLeft--;
		return true;
	}
	
	/** 
	 * Removes the given card from the board.  If the card is not found,
	 * false is returned; otherwise, true is returned.
	 * 
	 * @param card the card to remove from the board
	 * @return true if a card was sucessfully removed; false otherwise
	 **/
	public boolean removeCard(GameCard card) {
		for (int i = 0; i < NUM_ROWS; i++)
			for (int j = 0; j < NUM_COLS; j++)
				if (board[i][j] == card) {
					board[i][j] = null;
					cardsLeft--;
					return true;
				}
				
		return false;
	}
	
	/**
	 * Returns true if there are no more cards on the board.
	 * @return true if no more cards on board; false otherwise
	 **/
	public boolean isEmpty() {
		return cardsLeft == 0;
	}	
	
	/** 
	 * Returns true if and only if (row, col) is not a valid position on the
	 * board.
	 *
	 * @param row the row index (starting at 0)
	 * @param col the column index (starting at 0)
	 * @return is (row, col) an invalid position? 
	 **/ 
	public boolean invalidBoardPosition(int row, int col) {
		return (row < 0 || row >= board.length ||
		        col < 0 || col >= board[row].length ||
		        board[row][col] == null); 

	}
	
	/**
	 * Returns a string representation of the board suitable for printing
	 * with System.out.
	 * @return string representation of the board
	 **/
	public String toString() {
		StringBuffer strBuff = new StringBuffer(
		"     1   2   3   4   5   6   7   8   9   10  11  12  13\n");
		strBuff.append(
		"---------------------------------------------------------\n");
		strBuff.append("  |\n");
		for (int i = 0; i < board.length; i++) {
			strBuff.append((i+1) + " | ");
			for (int j = 0; j < board[i].length; j++) {
				if (board[i][j] != null)
					strBuff.append(board[i][j].toString() + " ");
				else
					strBuff.append("    ");
			}
			strBuff.append("\n  |\n");
		}
		strBuff.append(
		"---------------------------------------------------------\n");
		return strBuff.toString();
	}
}