/**
 * This RectangularArray class represents
 * a rectangular array of objects in memory
 * as a one dimensional array. It provides
 * implements for modifying it just like
 * any other array or collection. ex.
 * get, put
 *
 * @author Kristopher Kalish
 * @version 1 - April 18th, 2007
 * 
 * Lab26
 * Section 1 
 * 
 ************************************************/
 /*
  *  References and Acknowledgements: I have recieved
  *  no unauthorized help on this assignment.
  */
  
  // to make the array typesafe we simply at this <T> at the 
  // end of the declartion.  Now whenever a capital "T" is 
  // found in the body of the class it will be replaced with
  // the type specified by the driver
   public class RectangularArrayTS<T>
   {
      private int       columns, rows;
      // we make the array of type T[]
		private T[]  data;

    /**
     * Explicit Value Constructor
     *
     * @param rows    The number of rows
     * @param columns The number of columns
     */
      public RectangularArrayTS(int rows, int columns)
      {
			this.columns = columns;
			this.rows    = rows;
			
			// java won't let us make an array of type T[]
			// easily.  To accomplish this we'll cast
			// an array of Object[] to T[] and store
			// it in data.  
      	data = (T[]) new Object[rows * columns];
      }

    /**
     * Returns the number of columns in this RectangularArray
     *
     * @return   The number of columns
     */
      public int columns()
      {
      	return columns;
      }

    /**
     * Get the element at a particular row and column
     *
     * @param row     The row index
     * @param column  The column index
     * @return        The Object at the given row and column
     */
      public T getElementAt(int row, int column) 
						throws IndexOutOfBoundsException
      {
			T found;  // will store the object we find
			found = null;  // needed to compile
			
			if(row < rows && column < columns)
				found = data[index(row, column)];

			return found;
      }
   
    /**
     * This implementation uses an ordinary array as the underlying
     * data structure.  This converts from row and column indexes
     * to an index into the underlying data structure.
     *
     * @param row     The row index
     * @param column  The column index
     * @return        The corresponding index in the data array
     */
      private int index(int row, int column) 
                     throws IndexOutOfBoundsException
      {
			int index;
			
			// check for index out of bounds
			if(row >= rows || row < 0 || column >= columns || column < 0)
				throw new IndexOutOfBoundsException();
			
			index = (row * columns) + column;
      	return index;
      }
   
    /**
     * Returns the number of rows in this RectangularArray
     *
     * @return   The number of rows
     */
      public int rows()
      {
      	return rows;
      }
    
    /**
     * Set the element at a particular row and column
     *
     * @param row     The row index
     * @param column  The column index
     * @param o       The Object to put in the array
     */
      public void setElementAt(int row, int column, T o)
							throws IndexOutOfBoundsException
      {
			if(row < this.rows && column < this.columns)
      		data[index(row, column)] = o;
      }
   }
