//Source file: D:\\Projects\\src\\yi\\iu\\processor\\color\\reg\\DS_PolygonRegionColorStat.java

package yi.iu.processor.color.reg;

import yi.iu.region.*;
import java.awt.*;
import yi.graph.polygon.*;
import java.util.LinkedList;
import yi.iu.processor.color.reg.merge.*;
import yi.util.io.input.*;
import yi.util.config.*;
import yi.iu.imgdb.learn.*;

/**
 * DS_StatRgbColorPolygonRegion is a set of StatRgbColorPolygonRegion
 */
public class DS_PolygonRegionColorStat extends DS_PolygonRegionFeatureStat
{

  /**
   * Create DS_StatRgbColorPolygonRegion from labels
   * @param rgb
   * @param labels
   * @param width
   * @param height
   */
  public DS_PolygonRegionColorStat(int[] rgb, int[] labels, int width, int height)
  {
    m_imgWidth  = width;
    m_imgHeight = height;
    m_regions =
        PolygonRegionColorStat.getStatRgbColorPolygonRegions(rgb, labels, width, height);
  }

  /**
   * @param data
   * @param labels
   * @param width
   * @param height
   * @param ignore_zero
   */
  public DS_PolygonRegionColorStat(double[][] data, int[] labels, int width, int height, boolean ignore_zero)
  {
    super(data, labels, width, height, ignore_zero);
  }

  /**
   * @param w
   * @param h
   * @param regions
   */
  public DS_PolygonRegionColorStat(int w, int h, PolygonRegionColorStat[] regions)
  {
    super(w,h,regions);
  }

  public DS_PolygonRegionColorStat()
  {
    super();
  }

//  /**
//   * Use the color of the color regions to draw the regions in the given image
//   * pixel array
//   * @param pixels
//   * @param width
//   * @param height
//   * @return
//   */
//  public int[] getEllipseDemo(int[] pixels)
//  {
//    int n = getRegionNum();
//    int[] colors = new int[n];
//    Region[] regions = new Region[n];
//    for (int i=0;i<n;i++) {
//      PolygonRegionFeatureStat reg = m_regions[i];
//      double[] mean_color = reg.getMean();
//      int r = (int)Math.round(mean_color[0]);
//      int g = (int)Math.round(mean_color[1]);
//      int b = (int)Math.round(mean_color[2]);
//      colors[i] = 0xff000000 | (r << 16) | (g << 8) | b;
//      regions[i] = reg.getPolygonRegion().getRegion();
//    }
//    return Region.drawRegions(pixels, new Dimension(m_imgWidth, m_imgHeight), regions, colors);
//  }

  /**
   * @param pixels
   * @param fill
   * @return int[]
   */
  public int[] getPolygonDemo(int[] pixels, boolean fill)
  {
    if (pixels == null) {
      pixels = new int[m_imgWidth * m_imgHeight];
      java.util.Arrays.fill(pixels, 0xff000000);
    }
    int n = getRegionNum();
    int[] colors = new int[n];
    GenericPolygon[] regions = new GenericPolygon[n];
    for (int i=0;i<n;i++) {
      PolygonRegionFeatureStat reg = m_regions[i];
      double[] mean_color = reg.getMean();
      int r = (int)Math.round(mean_color[0]);
      int g = (int)Math.round(mean_color[1]);
      int b = (int)Math.round(mean_color[2]);
      colors[i] = 0xff000000 | (r << 16) | (g << 8) | b;
      regions[i] = reg.getPolygonRegion();
      if (fill) {
        regions[i].filledDraw(pixels, m_imgWidth, m_imgHeight, colors[i]);
      } else {
        regions[i].draw(pixels, m_imgWidth, m_imgHeight, colors[i], 1);
      }
    }
    return pixels;
  }

  /**
   * Return the feature vectors which contains the means only.  If there is no
   * features available, return null;
   * @param type
   * @return
   */
  public double[][] getFeatureVectors(int type)
  {
    // return null if no region-based feature available
    if (m_regions == null) return null;

    // get the dimension of the feature vector
    int n = m_regions[0].getFeatureLength();

    double[][] fs = new double[m_regions.length][];
    for (int i=0; i<m_regions.length; i++) {
      PolygonRegionFeatureStat f = m_regions[i];
      double[] means = f.getMean();
      float[] hsbvals = new float[3];
      java.awt.Color.RGBtoHSB((int)means[0], (int)means[1], (int)means[2], hsbvals);
      fs[i] = new double[] {hsbvals[0], hsbvals[1], hsbvals[2]};
    }
    return fs;
  }

  /**
   * Convert the features of "scale" scaled image, img, generated by
   * "processor_name", to one kind of representation of mode "mode"
   * @param processor_name
   * @param scale
   * @param img
   * @param mode
   * @return
   */
  public FeatureRepresentationList represent(String processor_name, int mode)  throws Exception{
    double[][] fvs = getFeatureVectors(0);

    // convert double[][] to a linked list of FeatureRepresentation
    FeatureRepresentationList list = new FeatureRepresentationList(fvs[0].length);
    for (int i=0; i<fvs.length; i++) {
      list.addFeatureRepresentation(new FeatureRepresentation(fvs[i]));
    }
    return list;
  }

  public DS_PolygonRegionColorStat createFromFile(String processor_name, int scale,
                                        String img) throws Exception {
    /** @todo scale should be setable */
    String scaled_img_name = img;
    if (scale != 0)
      scaled_img_name = img +
          yi.iu.processor.resample.Resampler.RESIZED_FILE_SUFFIX + scale;
    Configuration.setParameter("SOURCE_NAME", scaled_img_name);

    KMeansHSISeg dp = (KMeansHSISeg) Class.forName(processor_name).newInstance();
    DS_PolygonRegionColorStat ds = (DS_PolygonRegionColorStat) dp.reuse(DIU.
        INPUT_XML);
    return ds;
  }

  public FeatureRepresentable createFeatureFromFile(String processor_name, int scale,
      String img) throws Exception {
    return createFromFile(processor_name, scale, img);

  }

  public PolygonFeatureRepresentationList representPolygonFeatures(
     String processor_name, int mode)  throws Exception
  {
    double[][] fvs = getFeatureVectors(0);

    double scale = getScale();
    int width = (int)Math.round(getImageWidth()/scale);  // recover the image width and height
    int height = (int)Math.round(getImageHeight()/scale);
    // get the region information
    PolygonFeatureRepresentationList list = new PolygonFeatureRepresentationList(fvs[0].length, width, height);
    for (int i=0; i<m_regions.length; i++) {
      PolygonRegionFeatureStat f = m_regions[i];
      // rescale the polygon
      GenericPolygon region = f.getPolygonRegion();
      region.scale(1/scale);
      list.add(new PolygonFeatureRepresentation(fvs[i], region));
    }

    return list;
  }


  public static void main(String[] args) {
    try {
      DS_PolygonRegionColorStat color = new DS_PolygonRegionColorStat();
//    FeatureRepresentationList data = color.represent(
//        "F:/groundtruth/arborgreens/arborgreens01.jpg");
//    double[][] vectors = data.as2DDoubleArray();
//    yi.util.io.OutputResult.print(System.out, vectors, 3, vectors.length);

      DS_PolygonRegionColorStat ds = (new DS_PolygonRegionColorStat()).createFromFile(
          "yi.iu.processor.color.reg.merge.KMeansHSISeg", 256,
          "F:/groundtruth/arborgreens/arborgreens01.jpg");
      PolygonFeatureRepresentationList data2 = color.representPolygonFeatures(
          "yi.iu.processor.color.reg.merge.KMeansHSISeg", 0);
      double[][] vectors = data2.as2DDoubleArray();
      yi.util.io.OutputResult.print(System.out, vectors, 3, vectors.length);

      int width = data2.imgWidth, height = data2.imgHeight;
      int[] pixels =
          data2.drawScoreDemo(null, new FeatureScoringCapable() { // a inner class give sequence score
        int count = 1;
        public double getFeatureScore(double[] feature, Object obj) {
          return count++;
        }
      }

      , 0, 1);
      int[] pixels_img = yi.util.ImageUtil.makeNewImageFromLabel(pixels, true);
      yi.util.io.OutputResult.outputGIFImage("score.gif", pixels_img, width,
                                             height);
    } catch (Exception e) {
      e.printStackTrace();
    }

  }
  public FeatureRepresentable createFeatureFromFile(String processor_name, int scale, int rst_scale, String img) throws Exception {
    /**@todo Implement this yi.iu.imgdb.learn.FeatureRepresentable method*/
    throw new java.lang.UnsupportedOperationException("Method createFeatureFromFile() not yet implemented.");
  }

}
