package jp.crestmuse.cmx.bayesband.inference;
import jp.crestmuse.cmx.inference.*;
import jp.crestmuse.cmx.inference.MusicRepresentation.MusicElement;

public class BayesianMapping {

  final String layer;
  final int musRepPosition;
  final int option;
  final int bayesnetIndex;
  final boolean update;

  /*
     00000xxy  
     xx = 00 => NORMAL
     xx = 01 => BY_TIED_LENGTH
     xx = 10 => MEASURE_HEAD
     y = 0   => NORMAL
     y = 1   => SET_ONLY
  */

  public static final int NORMAL = 0;
  public static final int SET_ONLY = 1;
  public static final int BY_TIED_LENGTH = 2;
    public static final int MEASURE_HEAD = 4;

  public BayesianMapping(String layer, int musRepPosition, int option, 
                            int bayesnetIndex, boolean update) {
    this.layer = layer;
    this.musRepPosition = musRepPosition;
    this.option = option;
    this.bayesnetIndex = bayesnetIndex;
    this.update = update;
  }

  public BayesianMapping(String layer, int musRepPosition, int option, 
                            int bayesnetIndex) {
    this(layer, musRepPosition, option, bayesnetIndex, false);
  }

  /*
    public String getLayer() {
      return layer;
    }

    public int getBayesnetIndex() {
      return bayesnetIndex;
    }
  */
  protected int musicRepIndex(MusicRepresentation musRep, 
                                 int current) {
    if (musRepPosition == 0) return current;
    int index = 0;
    int inc;
    if ((option & BY_TIED_LENGTH) == BY_TIED_LENGTH) {
      inc = musRep.getTiedLength(layer);
    } else if ((option & MEASURE_HEAD) == MEASURE_HEAD) {
      inc = musRep.getDivision();
      current = (current / musRep.getDivision()) * musRep.getDivision();
      if (musRepPosition < 0) current += musRep.getDivision();
    } else {
      inc = 1;
    }
    if ((option & SET_ONLY) == SET_ONLY) {
      int sgn = musRepPosition > 0 ? 1 : -1;
        current += sgn;
        for (int i = 0; i < sgn * musRepPosition && current >= 0; 
             current += sgn) {
	    MusicElement e = musRep.getMusicElement(layer, current);
	    if (e.set()) i++;
        }
    } else {
      index = current + musRepPosition * inc;
    }
    int max_index;
    return index >= 0 ? index : 0;
//    if (index < 0) index = 0;
//    else if (index >= (max_index=musRep.getDivision()*musRep.MeasureNum()))
//      index = max_index;
//    return index;
  }
      


/*
  protected int getMusicRepresentationIndex(MusicRepresentation musRep,
      int source) {
    return source;
  }
*/
  /*
    public int filter(int index) {
      return index;
    }
  */
//  protected boolean update() {
//    return false;
//  }
}
