/** Array2D - Provides tools for manipulating a 2D array
   
	@author - YOUR NAME GOES HERE
	@version - V1 - YOUR DATE GOES HERE
 */
public class Array2D
{
	private double [][] matrix;
	
	/** Explicit value constructor
	 * 
	 * @param inArray The array to use to create this Array2D object
	 */
	public Array2D(double [][] inArray)
	{
		if (inArray != null)
		{
			this.matrix = new double [inArray.length][];
			
			for (int ii = 0; ii < inArray.length; ii++)
			{
				if (inArray[ii] != null)
				{ 
					this.matrix[ii] = new double[inArray[ii].length];
					
					for (int jj = 0; jj < inArray[ii].length; jj++)
						this.matrix[ii][jj] = inArray[ii][jj];
				}
				else 
					this.matrix[ii] = null;
			}
		}
		else 
			this.matrix = null;
	}
	
	/** getAverage averages all of the values of this array.
	 *
	 * @return The average of the array elements
	 */

	public  double getAverage()
	{
		double sum = 0;
		double count = 0;
		double average;
		
		if (matrix != null)
		{
			sum = getTotal();
			
			for (int ii = 0; ii < matrix.length; ii++)
			{
				if (matrix[ii] != null)
				{
					count = count + matrix[ii].length;
				}
			}
			if (count > 0)
				average = sum / count;
			else 
				average = 0;
		}
		else throw new NullPointerException ("Matrix is null");
		
		return average;
	}
	
	/** getColumnTotal sums all of the values in one column of this array.
	 * This method was named sumColumn in the worksheet
	 *
	 * @param col The number (0 based) of the col to sum
	 *
	 * @return The sum of the array elementsin that column.  
	 *				If the row does not exist in matrix....throw 
	 *				ArrayIndexOutOfBoundsException.
	 * @throws ArrayOutOfBoundsException if the row does not exist in the matrix
	 */
	public  double getColumnTotal (int col)
	{
		double sum = 0;
		
		if (matrix != null)
		{
			if (isCol(col))
			{
				for (int row = 0; row < matrix.length; row++)
				{
					if (matrix[row] != null && matrix[row].length > col)
						sum = sum + matrix[row][col]; 
				}
			}
			else 
				throw new ArrayIndexOutOfBoundsException("COL: " + col);
		}
		else throw new NullPointerException("Matrix is null");
		
		return sum;
	}
	
	/** getHighestInRow finds the largest value one row of this array.
	 *
	 * @param row The number (0 based) of the row to find the largest
	 *
	 * @return The highest of the row array elements.  If the row does not exist
	 *         in matrix....throw ArrayOutOfBoundsException.
	 * @throws ArrayOutOfBoundsException if the row does not exist in the matrix
	 */
	public  double getHighestInRow(int row)
	{
		double highest = 0;
		
		if (matrix != null)
		{
			if (isRow(row) && matrix[row] != null)
			{
				if (matrix[row].length > 0)
				{
					highest = matrix[row][0];  // starter
					for (int col = 0; col < matrix[row].length; col++)
						if (matrix[row][col] > highest)
							highest = matrix[row][col];
				}
			}
			else 
				throw new ArrayIndexOutOfBoundsException("ROW: " + row);
		}
		else throw new NullPointerException("Matrix is null");
		
		return highest;
	}
	
	/** getLowestInRow finds the lowest value one row of this array.
	 * This method was not in the worksheet, but is similar to getHighestInRow
	 *
	 * @param row The number (0 based) of the row to find the lowest
	 *
	 * @return The lowest of the row array elements.  If the row does not exist
	 *         in matrix....YOU FILL IN THE REST.
	 */
	public  double getLowestInRow(int row)
	{
			double lowest = 0;
			
			if (matrix != null)
			{
				if (isRow(row) && matrix[row] != null)
				{
					if (matrix[row].length > 0)
					{
						lowest = matrix[row][0];  // starter
						for (int col = 0; col < matrix[row].length; col++)
							if (matrix[row][col] < lowest)
								lowest = matrix[row][col];
					}
				}
				else 
					throw new ArrayIndexOutOfBoundsException("ROW: " + row);
			}
			else throw new NullPointerException("Matrix is null");
			return lowest;
		
	}

	/** getRowTotal sums all of the values in one row of this array.
	 * This method was named sumRow on the worksheet
	 *
	 * @param row The number (0 based) of the row to sum
	 *
	 * @return The sum of the row array elements.  If the row does not exist
	 *         in matrix....throw ArrayIndexOutOfBoundsException.
	 */

	public  double getRowTotal(int row)
	{
		double sum = 0;
		if (matrix != null)
		{	
			if(isRow(row))
			{
				for (int col = 0; col < matrix[row].length; col++)
					sum = sum + matrix[row][col];
			}
			else throw new ArrayIndexOutOfBoundsException("ROW: " + row);
		}
		else throw new NullPointerException("Matrix is null");
		
		return sum;
	}
	
	/** getTotal sums all of the values of this array.
	 *
	 * @return The sum of the array elements
	 */
	public  double getTotal()
	{
		double total = 0;
		
		if (matrix != null)
		{
			for (int row = 0; row < matrix.length; row ++)
			{
				if (matrix[row] != null)
				{
					for (int col = 0; col < matrix[row].length; col++)
					{
						total = total + matrix [row][col];
					}
				}
			}
		}
		else
			throw new NullPointerException ("Matrix is null");
		
		return total;
	}

	/**
	 * @param col The column to check
	 * @return true if the row exists in this array, false otherwise
	 */
    public boolean isCol(int col)
    {
    	boolean column = false;
    	
	    if (matrix != null)
	    {
	    	for (int row = 0; row < matrix.length && !column; row++)
	    		if (matrix[row].length > col)
	    			column = true;
	    }
	    else throw new NullPointerException ("Matrix is null");
	    
	    return column;
    }
	/**
	 * @param row The row to check
	 * @return true if the row exists in this array, false otherwise
	 */
    public boolean isRow(int row)
    {
    	boolean isRow = false;
    	
	    if (matrix != null)
	    {
	    	if (matrix.length > row)
	    		isRow = true;
	    }
	    else throw new NullPointerException("Matrix is null");
	    
	    return isRow;
    }
}