package yi.iu.imgdb.learn;

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

/**
 * Describe the generator, the size of the scaled image, the scaled result,
 * the feature output and etc of a feature
 */

public class FeatureDescriptor {
  /**
   * 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 feature
   */
  public String feature;

  /**
   * default feature descriptor
   */
  static HashMap m_defaultFeatureDescriptor = new HashMap();
  static {
    // line structure feature
    m_defaultFeatureDescriptor.put(
        "LineStructGenerator",
        new FeatureDescriptor("LineStructGenerator",
                              0, 0,
                              "LineClusterSets")
        );
    // line structure feature (merged line clusters)
    m_defaultFeatureDescriptor.put(
        "LineStructMergedGenerator",
        new FeatureDescriptor("LineStructMergedGenerator",
                              0, 0,
                              "LineClusterSets")
        );

    // color segmentation
    m_defaultFeatureDescriptor.put(
        "KMeansHSISeg",
        new FeatureDescriptor("KMeansHSISeg",
                              256, 128,
                              "CIELabLabeledRgnFts")
        );
    // texture segmentation
    m_defaultFeatureDescriptor.put(
        "ColorGuidedTextureSegNCC",
        new FeatureDescriptor("ColorGuidedTextureSegNCC",
                              256, 128,
                              "TextureLabeledRgnFts")
        );
    // mean shift
    m_defaultFeatureDescriptor.put(
        "MeanShiftBasedImageSegmenter",
        new FeatureDescriptor("MeanShiftBasedImageSegmenter",
                              128, 0,
                              "CIELabLabeledRgnFts")
        );
    // blobworld
    m_defaultFeatureDescriptor.put(
        "BlobworldSegmenter",
        new FeatureDescriptor("BlobworldSegmenter",
                              192, 128,
                              "BlobworldLabeledRgnFts")
        );
    // color patch
    m_defaultFeatureDescriptor.put(
        "ColorPatchSeg",
        new FeatureDescriptor("ColorPatchSeg",
                              256, 128,
                              "CIELabLabeledRgnFts")
        );
    // texture patch
    m_defaultFeatureDescriptor.put(
        "TexturePatchSeg",
        new FeatureDescriptor("TexturePatchSeg",
                              256, 128,
                              "TextureLabeledRgnFts")
        );
    // Prominent color
    m_defaultFeatureDescriptor.put(
        "DPU_GongProminentColor",
        new FeatureDescriptor("DPU_GongProminentColor",
                              256, 128,
                              "CIELabLabeledRgnFts")
        );
    // model based MRF segmenter
    m_defaultFeatureDescriptor.put(
        "ModelBasedMRFSegmenter",
        new FeatureDescriptor("ModelBasedMRFSegmenter",
                              128, 128,
                              "CIELabLabeledRgnFts")
        );
  }

  /**
   * generator abbreviation dictionary
   */
  static HashMap m_generatorAbbrDict = new HashMap();
  static {
    // line structure feature
    m_generatorAbbrDict.put(
        "st", "yi.iu.processor.clc.LineStructGenerator"
        );
    // line structure feature (merged line clusters)
    m_generatorAbbrDict.put(
        "st2", "yi.iu.processor.clc.LineStructMergedGenerator"
        );
    // color segmentation
    m_generatorAbbrDict.put(
        "cs",
        "yi.iu.processor.color.reg.merge.KMeansHSISeg"
        );
    // texture segmentation
    m_generatorAbbrDict.put(
        "ts",
        "yi.iu.processor.texture.reg.ColorGuidedTextureSegNCC"
        );
    // mean shift
    m_generatorAbbrDict.put(
        "ms",
        "yi.iu.processor.color.seg.mb.MeanShiftBasedImageSegmenter"
        );
    // blobworld
    m_generatorAbbrDict.put(
        "bw",
        "yi.iu.processor.seg.blob.BlobworldSegmenter"
        );
    // color patch
    m_generatorAbbrDict.put(
        "cp",
        "yi.iu.processor.color.reg.ColorPatchSeg"
        );
    // texture patch
    m_generatorAbbrDict.put(
        "tp",
        "yi.iu.processor.texture.reg.TexturePatchSeg"
        );
    // Prominent color
    m_generatorAbbrDict.put(
        "pc",
        "yi.iu.processor.color.DPU_GongProminentColor"
        );
    // model based MRF segmenter
    m_generatorAbbrDict.put(
        "mb",
        "yi.iu.processor.seg.mdl.ModelBasedMRFSegmenter"
        );

    // line structure feature
    m_generatorAbbrDict.put(
        "LineStructGenerator", "yi.iu.processor.clc.LineStructGenerator"
        );
    // line structure feature (merged line clusters)
    m_generatorAbbrDict.put(
        "LineStructMergedGenerator", "yi.iu.processor.clc.LineStructMergedGenerator"
        );
    // color segmentation
    m_generatorAbbrDict.put(
        "KMeansHSISeg",
        "yi.iu.processor.color.reg.merge.KMeansHSISeg"
        );
    // texture segmentation
    m_generatorAbbrDict.put(
        "ColorGuidedTextureSegNCC",
        "yi.iu.processor.texture.reg.ColorGuidedTextureSegNCC"
        );
    // mean shift
    m_generatorAbbrDict.put(
        "MeanShiftBasedImageSegmenter",
        "yi.iu.processor.color.seg.mb.MeanShiftBasedImageSegmenter"
        );
    // blobworld
    m_generatorAbbrDict.put(
        "BlobworldSegmenter",
        "yi.iu.processor.seg.blob.BlobworldSegmenter"
        );
    // color patch
    m_generatorAbbrDict.put(
        "ColorPatchSeg",
        "yi.iu.processor.color.reg.ColorPatchSeg"
        );
    // texture patch
    m_generatorAbbrDict.put(
        "TexturePatchSeg",
        "yi.iu.processor.texture.reg.TexturePatchSeg"
        );
    // Prominent color
    m_generatorAbbrDict.put(
        "DPU_GongProminentColor",
        "yi.iu.processor.color.DPU_GongProminentColor"
        );
    // model based MRF segmenter
    m_generatorAbbrDict.put(
        "ModelBasedMRFSegmenter",
        "yi.iu.processor.seg.mdl.ModelBasedMRFSegmenter"
        );
  }


  public FeatureDescriptor(String generator, int scale, int rst_scale, String feature) {
    this.generator = generator;
    this.scale = scale;
    this.rstScale = rst_scale;
    this.feature = feature;
  }

  public static FeatureDescriptor getDefaultFeatureDescriptor(String generator) {
    generator = yi.util.data.StringUtil.getClassShortName(generator);
    return (FeatureDescriptor)m_defaultFeatureDescriptor.get(generator);
  }


  public static String getGeneratorFullName(String short_name) {
    if (m_generatorAbbrDict.containsKey(short_name)) {
      return (String)m_generatorAbbrDict.get(short_name);
    }
    return short_name;
  }
  /**
   * Parse FeatureDescriptor(s) from the format of
   * generator,feature,scale,rstScale;generator,feature,scale,rstScale;...
   * @param str
   * @return
   */
  public static FeatureDescriptor[] parse(String str) {
    String[] desc_str = str.split(";");
    FeatureDescriptor[] desc = new FeatureDescriptor[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 = getGeneratorFullName(generator);
      FeatureDescriptor default_desc = getDefaultFeatureDescriptor(generator);
      // feature
      String feature = null;
      if (desc_items.length >= 2) {
        feature = desc_items[1];
      }
      else if (default_desc != null) {
        feature = default_desc.feature;
      }
      // 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;
      }
      // the descriptor
      desc[i] = new FeatureDescriptor(generator, scale, rst_scale, feature);
    }
    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 FeatureDescriptor[] parse(String str, LinkedList default_ft_list) {

    if (str == null || str.length() == 0) {
      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 getFeatureOutputName(FeatureDescriptor desc, String img_name, boolean add_path) {

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

    // write to disk
    return ft_path + img_name + "." +
        yi.util.data.StringUtil.getClassShortName(desc.generator) + "." +
        yi.util.data.StringUtil.getClassShortName(desc.feature) +
        ".ser";
  }

  public static String getFeatureIndexHtmlName(FeatureDescriptor desc, String output_html_str, boolean add_path) {

    String ft_path = add_path? Configuration.getParameter("FEATURE_PATH", "") : "";

    return ft_path + output_html_str +
        "." +
        yi.util.data.StringUtil.getClassShortName(desc.generator) +
        "." +
        yi.util.data.StringUtil.getClassShortName(desc.feature) + ".html";
  }

  public static String getFeatureGraphicDemoName(FeatureDescriptor desc, String img_name, boolean add_path) {

    String ft_path = add_path? Configuration.getParameter("FEATURE_PATH", "") : "";

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

    return ft_path + img_name + "." +
        yi.util.data.StringUtil.getClassShortName(desc.generator) + "." +
        yi.util.data.StringUtil.getClassShortName(desc.feature) +
        ".gdemo.gif";
  }

  public static String getFeatureColorDemoName(FeatureDescriptor desc, String img_name, boolean add_path) {

    String ft_path = add_path? Configuration.getParameter("FEATURE_PATH", "") : "";

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

    return ft_path + img_name + "." +
        yi.util.data.StringUtil.getClassShortName(desc.generator) + "." +
        yi.util.data.StringUtil.getClassShortName(desc.feature) +
        ".cdemo.gif";
  }

}