package yi.iu.ft.local;

import java.util.*;
import yi.ds.hd.*;

public class AttributeWithSelectedBins {

  /**
   * this attribute uses which attribute of the original feature
   */
  IntArray m_attributeSelector;

  /**
   * which bins are selected.  For example, lines have 2 attribute, orientation
   * and length.  Orientaion corresponds to 72 bins; while length corresponds to
   * 50.  Not all the bins will be selected.  For example, for
   * (orientation, length) histogram, may be only the bin corresponding to
   * orientation = 3 and length = 4 is useful.  The m_binSelector has a entry
   * of {3, 4}. The element are instances of HighDimensionCoordinates
   */
  HashSet m_binSelector;

  public AttributeWithSelectedBins(IntArray attr_selector, HashSet bin_selector) {
    m_attributeSelector = attr_selector;
    m_binSelector = bin_selector;
  }

  public IntArray getAttributeSelector() {
    return m_attributeSelector;
  }

  public HashSet getBinSelector() {
    return m_binSelector;
  }

  public int[] getHistogram(QuantizedFeature feature) {
    int[] bins = new int[m_binSelector.size()];

    // make a hash map for easily to find whether a bin is selected
    HashMap hash = new HashMap();
    Iterator it = m_binSelector.iterator(); int count = 0;
    while (it.hasNext()) {
      IntArray selector = (IntArray)it.next();
      hash.put(selector, new Integer(count));
      count++;
    }

    int[][] quans = feature.getQuantized();
    for (int i=0; i<quans.length; i++) {
      int[] selected = selectValues(quans[i], m_attributeSelector);
      IntArray bin_key = new IntArray(selected);
      if (hash.containsKey(bin_key)) {
        int bin_index = ((Integer)hash.get(bin_key)).intValue();
        bins[bin_index]++;
      }
    }
    return bins;
  }

  public String toString() {
    StringBuffer str = new StringBuffer();

    Iterator it = m_binSelector.iterator();
    while (it.hasNext()) {
      IntArray selector = (IntArray)it.next();
      str.append(m_attributeSelector);
      str.append("=" + selector + "\n");
    }
    return str.toString();
  }

  int[] selectValues(int[] data, IntArray selector) {
    int[] selected_index = selector.getCoordinates();
    int[] selected = new int[selected_index.length];
    for (int i=0; i<selected.length; i++) {
      selected[i] = data[selected_index[i]];
    }
    return selected;
  }

}