package visual.statik.sampled;

/**
 * An enumeration of the different convolutions
 * that are supported in the BufferedImageOpFactory
 *
 * This (partial) implementation is difficult to maintain 
 * because each time a value is added the switch
 * statement must be changed.
 *
 * @author  Prof. David Bernstein, James Madison University
 * @version 1.0
 */
enum UnmaintainableConvolutions
{
   BLUR,
   EDGE;
   
   

   /**
    * Get the kernel values
    *
    * @param size  The size of the convolution kernel
    */
   float[] getKernelValues(int size)
   {
      switch (this)
      {
         case BLUR:     return getBlurValues(size);
         case EDGE:     return getEdgeValues(size);
       
         default:       return getIdentityValues(size);
      }
   }
   
   
   /**
    * Get the kernel values for a blurring convolution
    *
    * @param size   The size of the kernel
    * @return       The array of kernel values
    */
   private static float[] getBlurValues(int size)
   {
      float       denom;      
      float[]     result;
      
      denom  = (float)(size*size);      
      result = new float[size*size];

      for (int row=0; row<size; row++)
         for (int col=0; col<size; col++)
            result[indexFor(row,col,size)] = 1.0f/denom;      

      return result;      
   }


   /**
    * Get the kernel values for an edge detecting convolution
    *
    * @param size   The size of the kernel
    * @return       The array of kernel values
    */
   private static float[] getEdgeValues(int size)
   {
      float[]     result;
      int         center;
      
      
      center = size/2;
      result = new float[size*size];

      result[indexFor(center-1, center  , size)] = -1.0f;      
      result[indexFor(center  , center-1, size)] = -1.0f;      
      result[indexFor(center  , center  , size)] =  4.0f;      
      result[indexFor(center  , center+1, size)] = -1.0f;      
      result[indexFor(center+1, center  , size)] = -1.0f;      

      return result;      
   }
   

   /**
    * Get the kernel values for an identity convolution
    *
    * @param size   The size of the kernel
    * @return       The array of kernel values
    */
   private static float[] getIdentityValues(int size)
   {
      float[]     result;
      int         center;
      
      center = size/2;
      result = new float[size*size];
      result[indexFor(center,center,size)] = 1.0f;
      
      return result;      
   }
   

   /**
    * Convert row and column indexes (i.e., matrix indices)
    * into a linear index (i.e., vector index)
    *
    * @param row   The row index
    * @param col   The column index
    * @param size  The size of the square matrix
    */
   private static int indexFor(int row, int col, int size)
   {
      return row*size + col;      
   }

}
