//Source file: D:\\Projects\\src\\yi\\iu\\region\\DS_PolygonRegionFeatureStat.java

package yi.iu.region;

import java.awt.*;
import yi.graph.polygon.*;
import yi.iu.imgdb.learn.Featurelizable;
import java.io.Serializable;
import yi.iu.imgdb.learn.FeatureRepresentable;
import yi.iu.imgdb.learn.*;
import yi.util.io.*;
import yi.iu.processor.resample.*;

/**
DS_PolygonRegionFeatureSet is a set of PolygonRegionFeatureStat
 */
public abstract class DS_PolygonRegionFeatureStat implements java.io.Serializable, PolygonFeatureRepresentable, FeaturePickDemoable
{
   protected int m_imgWidth;
   protected int m_imgHeight;

   /**
   For quick processing, the image may be scaled down and m_scale is the scale
   rate
    */
   double m_scale = 1.0;
   protected PolygonRegionFeatureStat m_regions[];

   /**
   Shallow copy constructor
   @param another
   @roseuid 3F994FC6005F
    */
   public DS_PolygonRegionFeatureStat(DS_PolygonRegionFeatureStat another)
   {
    this(another.m_imgWidth, another.m_imgHeight, another.m_regions);
   }

   /**
   @param data
   @param labels
   @param width
   @param height
   @param ignore_zero
   @roseuid 3F994FC6004E
    */
   public DS_PolygonRegionFeatureStat(double[][] data, int[] labels, int width, int height, boolean ignore_zero)
   {
    m_imgWidth  = width;
    m_imgHeight = height;
    m_regions =
        PolygonRegionFeatureStat.createPolygonRegionFeatureStats(data, labels, width, height, ignore_zero);
   }

   /**
   @param w
   @param h
   @param regions
   @roseuid 3F994FC6002E
    */
   public DS_PolygonRegionFeatureStat(int w, int h, PolygonRegionFeatureStat[] regions)
   {
    this();
    m_imgWidth  = w;
    m_imgHeight = h;
    m_regions = regions;
   }

   /**
   @roseuid 3F994FC6001F
    */
   public DS_PolygonRegionFeatureStat()
   {

   }

   /**
   @return int
   @roseuid 3F994FC6006E
    */
   public int getRegionNum()
   {
    return m_regions == null? 0: m_regions.length;
   }

   /**
   @roseuid 3F994FC6007D
    */
   public void setRegionNum()
   {

   }

   /**
   @return int
   @roseuid 3F994FC6007E
    */
   public int getImageWidth()
   {
    return m_imgWidth;
   }

   /**
   @param w
   @roseuid 3F994FC6008C
    */
   public void setImageWidth(int w)
   {
    m_imgWidth = w;
   }

   /**
   @return int
   @roseuid 3F994FC6009C
    */
   public int getImageHeight()
   {
    return m_imgHeight;
   }

   /**
   @param h
   @roseuid 3F994FC6009D
    */
   public void setImageHeight(int h)
   {
    m_imgHeight = h;
   }

   /**
   @return yi.iu.region.PolygonRegionFeatureStat[]
   @roseuid 3F994FC600AC
    */
   public PolygonRegionFeatureStat[] getRegions()
   {
    return m_regions;
   }

   /**
   @param regions
   @roseuid 3F994FC600CB
    */
   public void setRegions(PolygonRegionFeatureStat[] regions)
   {
    m_regions = regions;
   }

   /**
   @return double
   @roseuid 3F994FC600EA
    */
   public double getScale()
   {
    return m_scale;
   }

   /**
   @param scale
   @roseuid 3F994FC600EB
    */
   public void setScale(double scale)
   {
    m_scale = scale;
   }

//   /**
//   Use the color of the color regions to draw the regions in the given image
//   pixel array
//   @param pixels
//   @param width
//   @param height
//   @return
//   @roseuid 3F994FC600FB
//    */
//   public int[] getEllipseDemo(int[] pixels)
//   {
//    int n = getRegionNum();
//    int[] colors = yi.util.ImageUtil.labels2Colors(n-1, false);
//    Region[] regions = new Region[n];
//    for (int i=0;i<n;i++) {
//      PolygonRegionFeatureStat reg = m_regions[i];
//      regions[i] = reg.getPolygonRegion().getRegion();
//    }
//    return Region.drawRegions(pixels, new Dimension(m_imgWidth, m_imgHeight), regions, colors);
//   }

   /**
   @param pixels
   @param fill
   @return int[]
   @roseuid 3F994FC6010A
    */
   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 = yi.util.ImageUtil.labels2Colors(n-1, false);
    GenericPolygon[] regions = new GenericPolygon[n];
    for (int i=0;i<n;i++) {
      PolygonRegionFeatureStat reg = m_regions[i];
      if (reg.getPolygonRegion()!=null) {

        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;
   }

   /**
   Output the regions (one region per image).  The region's boundary will be
   marked with the given boundary color (the boundary will be outside the
   region to show)
   @param file_name the root file name
   @param pixels the pixels to display
   @param size_threshold the minimum size of the region to output
   @param color the boundary color
   @roseuid 3F994FC6011B
    */
   public void demoRegions(String file_name, int[] pixels, int size_threshold, int color)
   {
    int n = getRegionNum();

    for (int i=0; i<n; i++) {
      PolygonRegionFeatureStat reg = m_regions[i];
      int count = 0;
      GenericPolygon polygon = reg.getPolygonRegion();
      double area = polygon.getArea();
      // output the result
      if (area >= size_threshold) {
        int[] demo = (int[])pixels.clone();
        polygon.filledDraw(demo, m_imgWidth, m_imgHeight, color);
        yi.util.io.OutputResult.outputColorImage(
          file_name + ".region." + i + ".ppm", demo, m_imgWidth, m_imgHeight);

      }
    }
   }

   /**
   Return the feature vectors which contains the means only.  If there is no
   features available, return null;
   @param type
   @return
   @roseuid 3F994FC60139
    */
   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();
      fs[i] = (double[]) means.clone();
    }
    return fs;
   }

   /**
    * Draw picked features.  The picked features will have "true" in the
    * corresponding "picked" boolean array.  Image name are given in case the
    * demo uses the original image pixels.  Those un-picked features will be
    * drawn by the "bg_color"
    * @param picked
    * @param img
    * @param scale
    * @param bg_color
    * @return
    */
   public int[] drawPickedFeatures(boolean[] picked, String img_name, int bg_color, Dimension d, int mode) {

     try {
       int[] orig_img = ImageIOUtil.read(img_name, d);

       // rescale the image if necessary
       int scale = (d.width == m_imgWidth) ? 1 : Math.max(m_imgWidth, m_imgHeight);
       if (scale != 1 && scale != 0) {
          orig_img = Resampler.scaleDown(
             orig_img, new Dimension(d.width, d.height),
             Resampler.NEAREST_RESAMPLER, m_imgWidth, m_imgHeight);
         d.width = m_imgWidth;
         d.height = m_imgHeight;
       }

       int[] pixels = new int[m_imgWidth * m_imgHeight];
       // loop through each feature
       for (int i=0; i<m_regions.length; i++) {
         if (picked[i]) {
           GenericPolygon poly = m_regions[i].getPolygonRegion();
           poly.filledDraw(pixels, m_imgWidth, m_imgHeight, 1);
         }
       }
       for (int i=0; i<pixels.length; i++) {
         pixels[i] = (pixels[i] > 0) ? orig_img[i] : bg_color;
       }
       return pixels;

     } catch (java.io.IOException e) {
       System.err.println("can read image " + img_name);
       return null;
     }

   }

}
