/*********************************************************************
 * Implements a 2-D array of characters
 * 
 * @author arch
 * @version Jan 23, 2014
 * 
 ********************************************************************/
public class CharMatrix
{
    private char[][] theArray;

    /******************************************************************************************
     * Constructor: creates a grid with dimensions rows, cols, and fills it with spaces
     * 
     * @param rows
     *            Rows in array
     * @param cols
     *            Columns in array
     *****************************************************************************************/
    public CharMatrix(int rows, int cols)
    {
        // ================================================
        // This one is written for you. Notice how it uses
        // the other constructor to do all the work.
        // =================================================
        this(rows, cols, ' ');
        // System.out.printf("Construct\n");
    }

    /******************************************************************************************
     * Constructor: creates a grid with dimensions rows , cols , and fills it with the fill
     * character.
     * 
     * @param rows
     *            Rows in array
     * @param cols
     *            Cols in array
     * @param fill
     *            Character to put into array
     *****************************************************************************************/
    public CharMatrix(int rows, int cols, char fill)
    {
        this.theArray = new char[rows][cols];
        this.fillRect(0, 0, rows - 1, cols - 1, fill);
        //System.out.printf("Construct2 %d %d:\n%s\n", rows, cols, this.toString());

        // ===========================================================================
        // Hint, you need to instantiate the 2D array, then populate it. And just like
        // the previous constructor used this constructor to do its work for it, this
        // method can use the "fillRect" method to do all the work of populating the array.
        // ============================================================================
    }

    /******************************************************************************************
     * Fills the given rectangle with the fill characters. row0, col0 is the upper left corner
     * and row1, col1 is the lower right corner of the rectangle.
     * 
     * @param row0
     *            Upper left row
     * @param col0
     *            Upper left column
     * @param row1
     *            Lower right row
     * @param col1
     *            Lower right column
     * @param fill
     *            Character to put into array
     *****************************************************************************************/
    public void fillRect(int row0, int col0, int row1, int col1, char fill)
    {
        for (int row = row0; row <= row1; row++)
        {
            for (int col = col0; col <= col1; col++)
            {
               // System.out.printf("fill: %d %d\n", row,  col);
               this.theArray[row][col] = fill;
            }
        }
        //System.out.printf("FillRect %d %d %d %d:\n%s\n", row0, col0, row1, col1, this.toString());
    }

    /******************************************************************************************
     * Fills the given rectangle with the SPACE character. row0, col0 is the upper left corner
     * and row1, col1 is the lower right corner of the rectangle.
     * 
     * @param row0
     *            Upper left row
     * @param col0
     *            Upper left column
     * @param row1
     *            Lower right row
     * @param col1
     *            Lower right column
     * @param fill
     *            Character to put into array
     *****************************************************************************************/
    public void clearRect(int row0, int col0, int row1, int col1)
    {
        // ================================================
        // This one is written for you. Notice how it uses
        // "fillRect" to do all the work.
        // =================================================
        this.fillRect(row0, col0, row1, col1, ' ');
    }

    /******************************************************************************************
     * Accessor that returns the number of rows in the array.
     * 
     * @return The number of rows in the array.
     *****************************************************************************************/
    public int numRows()
    {
        return this.theArray.length;
    }

    /******************************************************************************************
     * Accessor that returns the number of columns in the array.
     * 
     * @return The number of columns in the array.
     *****************************************************************************************/

    public int numCols()
    {
        return this.theArray[0].length;
    }

     /*********************************************************************
     * Method that returns true if the character at row, col is a SPACE, false otherwise
     * 
     * @param row
     *            The row
     * @param col
     *            The col
     * @return True if the character is a SPACE, false otherwise
     ********************************************************************/
    public boolean isEmpty(int row, int col)
    {
        return this.theArray[row][col] == ' ';
    }

    /*********************************************************************
     * A method that returns the count of all non-SPACE characters in the row.
     * 
     * @param row
     *            The row
     * @return The count of all non-SPACE characters in row. Returns -1 if 
     *         the row is invalid for the matrix.
     ********************************************************************/
    public int countInRow(int row)
    {
        int count = 0;
        
        for (int col = 0; col < this.numCols(); col++)
        {
            if ( this.theArray[row][col] != ' ' )
                count++;
        }
        return count;
    }

    /*********************************************************************
     * A method that returns the count of all non-SPACE characters in the column.
     * 
     * @param col
     *            The column
     * @return The count of all non-SPACE characters in the column. Returns -1 if
     *         the row is invalid for the matrix.
     ********************************************************************/
    public int countInCol(int col)
    {
        int count = 0;
        
        for (int row = 0; row < this.numRows(); row++)
        {
            if ( this.theArray[row][col] != ' ' )
                count++;
        }
    
        return count;
    }

    /***************************************************************
     * A method the return a string representation of the object.
     * 
     * @return The string representation of the object
     ***************************************************************/
    public String toString()
    {
        String arrayStr = "";
        for (int row = 0; row < this.numRows(); row++)
        {
            arrayStr += "[";
            for (int col = 0; col < this.numCols(); col++)
            {
                arrayStr += '{';
                arrayStr += this.theArray[row][col];
                arrayStr += '}';
            }
            arrayStr += "]\n";
        }
        return arrayStr;
    }
}
