package yi.iu.imgdb.learn;

import java.util.HashMap;
import yi.util.config.Configuration;
import yi.iu.processor.resample.Resampler;
import java.util.LinkedList;

/**
 * Describe the generator, the size of the scaled image, the scaled result,
 * the representation mode, the representation type and etc of a feature
 * representation
 */

public class RepresentationDescriptor {
  /**
   * The generator of the feature
   */
  public String generator;

  /**
   * The scale of the input image
   */
  public int scale;

  /**
   * The result scale
   */
  public int rstScale;

  /**
   * The type of representation
   */
  public String representation;

  /**
   * representation mode
   */
  public int mode;

  /**
   * default feature descriptor
   */
  static HashMap m_defaultRepresentationDescriptor = new HashMap();
  static {
    // line structure feature
    m_defaultRepresentationDescriptor.put(
        "LineStructGenerator",
        new RepresentationDescriptor("LineStructGenerator",
                              0, 0,
                              "FeatureRepresentationList", 4)
        );
    // line structure feature
    m_defaultRepresentationDescriptor.put(
        "LineStructMergedGenerator",
        new RepresentationDescriptor("LineStructMergedGenerator",
                              0, 0,
                              "FeatureRepresentationList", 0)
        );
    // color segmentation
    m_defaultRepresentationDescriptor.put(
        "KMeansHSISeg",
        new RepresentationDescriptor("KMeansHSISeg",
                              256, 128,
                              "FeatureRepresentationList", 0)
        );
    // texture segmentation
    m_defaultRepresentationDescriptor.put(
        "ColorGuidedTextureSegNCC",
        new RepresentationDescriptor("ColorGuidedTextureSegNCC",
                              256, 128,
                              "FeatureRepresentationList", 0)
        );
    // mean shift
    m_defaultRepresentationDescriptor.put(
        "MeanShiftBasedImageSegmenter",
        new RepresentationDescriptor("MeanShiftBasedImageSegmenter",
                              128, 0,
                              "FeatureRepresentationList", 0)
        );
    // blobworld
    m_defaultRepresentationDescriptor.put(
        "BlobworldSegmenter",
        new RepresentationDescriptor("BlobworldSegmenter",
                              192, 128,
                              "FeatureRepresentationList", 0)
        );
    // color patch
    m_defaultRepresentationDescriptor.put(
        "ColorPatchSeg",
        new RepresentationDescriptor("ColorPatchSeg",
                              256, 128,
                              "FeatureRepresentationList", 0)
        );
    // texture patch
    m_defaultRepresentationDescriptor.put(
        "TexturePatchSeg",
        new RepresentationDescriptor("TexturePatchSeg",
                              256, 128,
                              "FeatureRepresentationList", 0)
        );
    // Prominent color
    m_defaultRepresentationDescriptor.put(
        "DPU_GongProminentColor",
        new RepresentationDescriptor("DPU_GongProminentColor",
                              256, 128,
                              "FeatureRepresentationList", 0)
        );
    // model based MRF segmenter
    m_defaultRepresentationDescriptor.put(
        "ModelBasedMRFSegmenter",
        new RepresentationDescriptor("ModelBasedMRFSegmenter",
                              128, 128,
                              "FeatureRepresentationList", 0)
        );

  }

  public RepresentationDescriptor(String generator, int scale, int rst_scale, String representation, int mode) {
    this.generator = generator;
    this.scale = scale;
    this.rstScale = rst_scale;
    this.representation = representation;
    this.mode = mode;
  }

  public static RepresentationDescriptor getDefaultRepresentationDescriptor(String generator) {
    generator = yi.util.data.StringUtil.getClassShortName(generator);
    return (RepresentationDescriptor)m_defaultRepresentationDescriptor.get(generator);
  }

  /**
   * Parse RepresentationDescriptor(s) from the format of
   * generator,representation,scale,rstScale,mode;generator,representation,scale,rstScale,mode;...
   * @param str
   * @return
   */
  public static RepresentationDescriptor[] parse(String str) {
    String[] desc_str = str.split(";");
    RepresentationDescriptor[] desc = new RepresentationDescriptor[desc_str.length];
    for (int i=0; i<desc.length; i++) {
      String[] desc_items = desc_str[i].split(",");
      // generator
      String generator = desc_items[0];
      generator = FeatureDescriptor.getGeneratorFullName(generator);
      RepresentationDescriptor default_desc = getDefaultRepresentationDescriptor(generator);
      // representation
      String representation = null;
      if (desc_items.length >= 2) {
        representation = desc_items[1];
      }
      else if (default_desc != null) {
        representation = default_desc.representation;
      }
      // scale
      int scale = 0;
      if (desc_items.length >= 3) {
        scale = Integer.parseInt(desc_items[2]);
      }
      else if (default_desc != null) {
        scale = default_desc.scale;
      }
      // rst_scale
      int rst_scale = 0;
      if (desc_items.length >= 4) {
        rst_scale = Integer.parseInt(desc_items[3]);
      }
      else if (default_desc != null) {
        rst_scale = default_desc.rstScale;
      }
      // mode
      int mode = 0;
      if (desc_items.length >= 5) {
        mode = Integer.parseInt(desc_items[4]);
      }
      else if (default_desc != null) {
        mode = default_desc.mode;
      }
      // the descriptor
      desc[i] = new RepresentationDescriptor(generator, scale, rst_scale, representation, mode);
    }
    return desc;
  }

  /**
   * Parse FeatureDescriptor(s) from the format of
   * generator,feature,scale,rstScale;generator,feature,scale,rstScale;...
   * @param str
   * @param default_ft_list default feature list if the str is null
   * @return
   */
  public static RepresentationDescriptor[] parse(String str, LinkedList default_ft_list) {

    if (str == null) {
      str = (String) default_ft_list.get(0);
      for (int i = 1; i < default_ft_list.size(); i++) {
        str = str + ";" + default_ft_list.get(i);
      }
    }
    return parse(str);
  }

  public static String getRepresentationOutputName(RepresentationDescriptor rep_desc, String img_name, boolean add_path) {

    String rep_path = add_path? Configuration.getParameter("REPRESENTATION_PATH", "") : "";
    if (rep_desc.scale != 0) {
      img_name = img_name + Resampler.RESIZED_FILE_SUFFIX + rep_desc.scale;
    }
    if (rep_desc.rstScale != 0) {
      img_name = img_name + ".r" + rep_desc.rstScale;
    }

    // write to disk
    return rep_path + img_name + "." +
        yi.util.data.StringUtil.getClassShortName(rep_desc.generator) + "." +
        yi.util.data.StringUtil.getClassShortName(rep_desc.representation) +
        ".m" + rep_desc.mode + ".ser";
  }

  public static String getRepresentationIndexHtmlName(RepresentationDescriptor rep_desc, String output_html_str, boolean add_path) {

    String rep_path = add_path? Configuration.getParameter("REPRESENTATION_PATH", "") : "";

    return rep_path + output_html_str +
        "." +
        yi.util.data.StringUtil.getClassShortName(rep_desc.generator) +
        "." +
        yi.util.data.StringUtil.getClassShortName(rep_desc.representation) + ".html";
  }

  public static String getRepresentationGraphicDemoName(RepresentationDescriptor rep_desc, String img_name, boolean add_path) {

    String rep_path = add_path? Configuration.getParameter("REPRESENTATION_PATH", "") : "";

    if (rep_desc.scale != 0) {
      img_name = img_name + Resampler.RESIZED_FILE_SUFFIX + rep_desc.scale;
    }
    if (rep_desc.rstScale != 0) {
      img_name = img_name + ".r" + rep_desc.rstScale;
    }

    return rep_path + img_name + "." +
        yi.util.data.StringUtil.getClassShortName(rep_desc.generator) + "." +
        yi.util.data.StringUtil.getClassShortName(rep_desc.representation) +
        ".gdemo.gif";
  }

  public static String getRepresentationColorDemoName(RepresentationDescriptor rep_desc, String img_name, boolean add_path) {

    String rep_path = add_path? Configuration.getParameter("REPRESENTATION_PATH", "") : "";

    if (rep_desc.scale != 0) {
      img_name = img_name + Resampler.RESIZED_FILE_SUFFIX + rep_desc.scale;
    }
    if (rep_desc.rstScale != 0) {
      img_name = img_name + ".r" + rep_desc.rstScale;
    }

    return rep_path + img_name + "." +
        yi.util.data.StringUtil.getClassShortName(rep_desc.generator) + "." +
        yi.util.data.StringUtil.getClassShortName(rep_desc.representation) +
        ".cdemo.gif";
  }
}