//Source file: D:\\Projects\\src\\yi\\iu\\imgdb\\learn\\FtCombImgDataCenter.java

package yi.iu.imgdb.learn;

import java.util.*;
import yi.iu.region.*;
import yi.graph.polygon.*;
import yi.util.config.*;
import yi.util.io.*;


/**
 * Combine region features from different feature space into one bigger feature
 * space.  The feature from one feature space for an image will be combined with
 * the features from other feature space for the same image.
 */
public class FtCombImgDataCenter extends ImgDataCenter
{

  protected FtCombImgDataCenter()
  {
  }

  /**
   * Init an image data center by combining the features in another image data
   * center
   * @param data_center
   */
  public FtCombImgDataCenter(ImgDataCenter data_center, String ft_name) {
    super();

    m_imgDescriptions = data_center.m_imgDescriptions;

    m_featureList = new LinkedList();
    m_featureList.add(ft_name);

    m_objList = data_center.m_objList;
    m_imgList = data_center.m_imgList;

    m_featureLengths = new HashMap();
    int total_len = 0;
    for (Iterator i=data_center.m_featureLengths.keySet().iterator(); i.hasNext();) {
      int len = ((Integer)data_center.m_featureLengths.get(i.next())).intValue();
      total_len += len;
    }
    m_featureLengths.put(ft_name, new Integer(total_len));



    // for each image
    LinkedList img_list = data_center.getImageList();
    LinkedList ft_list = data_center.getFeatureList();
    for (Iterator i=img_list.iterator(); i.hasNext();) {
      String img = (String)i.next();
      // find all the features
      RegionFeatureRepresentationList[] ft_rp_list = new RegionFeatureRepresentationList[ft_list.size()];
      int j_index = 0;
      for (Iterator j=ft_list.iterator(); j.hasNext(); j_index++) {
        String ft = (String)j.next();
        ft_rp_list[j_index] = (RegionFeatureRepresentationList)data_center.getImgFeatureList(img, ft);
      }
      RegionFeatureRepresentationList[] comb_ft_list = combineFeatures(ft_rp_list);
      m_imgFeatures.put(ft_name, img, comb_ft_list[0]);
      System.out.println("img = " + img + ", comb ft # = " + comb_ft_list[0].size());
    }
  }

  public double MIN_COMB_RGN_AREA = 256;

  RegionFeatureRepresentationList[] combineFeatures(PolygonFeatureRepresentationList[] ft_rp_list) {
    if (ft_rp_list.length <= 1) { // no more to combine
      return ft_rp_list;
    }
    // combine the first two features
    RegionFeatureRepresentationList ft_list1 = ft_rp_list[0];
    RegionFeatureRepresentationList ft_list2 = ft_rp_list[1];
    // the new feature list
    RegionFeatureRepresentationList comb_ft_list = new RegionFeatureRepresentationList(
        ft_list1.featureDimension + ft_list2.featureDimension, ft_list1.imgWidth, ft_list1.imgHeight);
    for (Iterator i=ft_list1.iterator(); i.hasNext(); ) {
      PolygonFeatureRepresentation ft1 = (PolygonFeatureRepresentation)i.next();
      for (Iterator j=ft_list2.iterator(); j.hasNext(); ) {
        PolygonFeatureRepresentation ft2 = (PolygonFeatureRepresentation) j.next();
        GenericPolygon rgn1 = ft1.region;
        GenericPolygon rgn2 = ft2.region;
        // the intersection of the two feature regions
        GenericPolygon intersect = GenericPolygon.gpcPolygonClip(
            GenericPolygon.GPC_INT, rgn1, rgn2);
        if (intersect.getArea() >= MIN_COMB_RGN_AREA) {
          double[] data1 = ft1.data;
          double[] data2 = ft2.data;
          double[] data_comb = new double[data1.length + data2.length];
          for (int k=0; k<data1.length; k++) data_comb[k] = data1[k];
          for (int k=0; k<data2.length; k++) data_comb[k+data1.length] = data2[k];
          PolygonRegion intersect_rgn = new PolygonRegion(intersect, null);
          comb_ft_list.add(new RegionFeatureRepresentation(data_comb, intersect_rgn));
        }
      }
    }

    // clear the first two list for garbage collection
    ft_list1.clear();
    ft_list2.clear();

    // recursive
    RegionFeatureRepresentationList[] new_ft_rp_list = new RegionFeatureRepresentationList[ft_rp_list.length - 1];
    new_ft_rp_list[0] = comb_ft_list;
    for (int i=1; i<new_ft_rp_list.length; i++) new_ft_rp_list[i] = ft_rp_list[i+1];
    return combineFeatures(new_ft_rp_list);
  }

  public final static String USAGE = "Usage: -d img_data_center [-f new_ft_name] [-o output_file_name]";

  public static void main(String[] args) {
    try {

      // init configuration
      Configuration.init(args);

      // get the datacenter
      String data_center_name = ReadArgu.getOption(
         'd', args,
         "groundtruth.ser"
      );

      ImgDataCenter data_center = ImgDataCenter.createFromFile(
         data_center_name);

      // get the feature data class names
      String ft_name = ReadArgu.getOption(
         'f', args,
         "combined"
      );

      FtCombImgDataCenter center = new FtCombImgDataCenter(data_center, ft_name);

      // write the data center to disk
      String output_file = ReadArgu.getOption('o', args);
      if (output_file != null) {
        center.writeToFile(output_file);
      }

    }catch (Exception e) {
      e.printStackTrace();
    }
  }


}
