package yi.iu.processor.color.quan;

import java.awt.*;
import yi.ds.hd.*;

/**
 * Quantize the color using hue information and to gray if the saturation is
 * too low
 */
public class HueQuantizer {
  static final double FIRST_SIXTH = 1.0/6;
  static final int DEFAULT_HUE_LEVEL = 16;
  static final int DEFAULT_GRAY_LEVEL = 4;

  /**
   * how many hue level available
   */
  public int m_hueLevel = DEFAULT_HUE_LEVEL;
  /**
   * how many gray level available
   */
  public int m_grayLevel = DEFAULT_GRAY_LEVEL;
  /**
   * the threshold of saturation value to decide using hue and gray
   */
  public double m_chromaticThreshold = FIRST_SIXTH;

  public HueQuantizer(double chromatic_threshold, int hue_level, int gray_level) {
    m_chromaticThreshold = chromatic_threshold;
    m_hueLevel = hue_level;
    m_grayLevel = gray_level;
  }

  /**
   * Hue takes [0, HUE_LEVEL), gray takes [HUE_LEVEL, HUE_LEVEL + GRAY_LEVEL)
   * @param rgb
   * @return
   */
  public int quantize(int rgb) {
    int[] rgb_array = yi.iu.processor.color.ColorUtil.RGB2IntArray(rgb);
    float[] hsb = Color.RGBtoHSB(rgb_array[0], rgb_array[1], rgb_array[2], null);
    float h=hsb[0],s=hsb[1],v=hsb[2];
    if (s < m_chromaticThreshold) {
      int index = (int)(v * m_grayLevel);
      if (index >= m_grayLevel) {
//        System.err.println("gray level is out of range in quantizeRgb: " + v + "(" + new IntArray(rgb_array) + ")" + "->" + index);
        index = m_grayLevel - 1;
      }
      return index + m_hueLevel;
    }
    int index_h = (int)(h * m_hueLevel);
    if (index_h >= m_hueLevel) {
//      System.err.println("hue level is out of range in quantizeRgb: " + index_h);
      index_h = m_hueLevel - 1;
    }
    return index_h;
  }

  public int[] quantize(int[] rgb) {
    int[] quantized = new int[rgb.length];
    for (int i=0; i<rgb.length; i++) quantized[i] = quantize(rgb[i]);
    return quantized;
  }

}