import java.awt.*;
import java.awt.image.*;

import math.*;


/**
 * A Posterizer reduces the number of colors in an image
 *
 * @author  Prof. David Bernstein, James Madison University
 * @version 1.0
 */
public class Posterizer
{
    private double[]    aa, bb;    
    private Metric      metric;
    

    private static final int[] BLACK = {  0,  0,  0};
    private static final int[] WHITE = {255,255,255};
    
    /**
     * Default Constructor
     */
    public Posterizer()
    {
       aa = new double[3];
       bb = new double[3];
    }
    

    /**
     * Determine the distance between two colors
     *
     * @param a   The RGB values of one color
     * @param b   The RGB values of the other color
     * @return    The distance
     */
    private double distance(int[] a, int[] b)
    {
       double     result;       

       for (int i=0; i<3; i++)
       {
          aa[i] = a[i];
          bb[i] = b[i];          
       }

       result = Double.POSITIVE_INFINITY;
       if (metric != null) result = metric.distance(aa, bb);

       return result;
    }
    

    /**
     * Set the Metric to use to determine the distance
     * between colors
     *
     * @param metric  The Metric to use
     */
    public void setMetric(Metric metric)
    {
       this.metric = metric;       
    }
    

    /**
     * Convert an image to black-and-white (NOT gray scale)
     *
     * @param image   The BufferedImage to convert
     */
    public void toBlackAndWhite(BufferedImage image)
    {
       ColorModel  colorModel;       
       double      blackDistance, whiteDistance;       
       int         height, packedPixel, packedBlack, packedWhite, width;
       int[]       pixel;       

       pixel       = new int[3];
       
       height      = image.getHeight();
       width       = image.getWidth();

       colorModel  = image.getColorModel();       

       packedBlack = colorModel.getDataElement(BLACK,0);
       packedWhite = colorModel.getDataElement(WHITE,0);

       for (int x=0; x<width; x++)
       {
          for (int y=0; y<height; y++)
          {
             packedPixel = image.getRGB(x, y);
             colorModel.getComponents(packedPixel, pixel, 0);

             blackDistance = distance(pixel, BLACK);
             whiteDistance = distance(pixel, WHITE);
             
             if (blackDistance < whiteDistance)
                image.setRGB(x, y, 0x00000000);
             else
                image.setRGB(x, y, 0xFFFFFFFF);                
          }
       }
    }
    
}
