package jp.crestmuse.cmx.bayesband.inference;

import java.util.LinkedList;

import jp.crestmuse.cmx.bayesband.filewrappers.BayesNetWrapper;
import jp.crestmuse.cmx.inference.MusicRepresentation.MusicElement;
import jp.crestmuse.cmx.inference.*;

public class BayesianCalculator implements Calculator {

  //private MusicRepresentation musicRepresentation;
  private BayesNetWrapper bayesNet;
  private LinkedList<BayesianMapping> readMappings;
  private LinkedList<BayesianMapping> writeMappings;

  public BayesianCalculator(BayesNetWrapper bayesNet) {
    //this.musicRepresentation = musicRepresentation;
    this.bayesNet = bayesNet;
    readMappings = new LinkedList<BayesianMapping>();
    writeMappings = new LinkedList<BayesianMapping>();
  }

  public void update(MusicRepresentation musRep, MusicElement me, int index) {
    int measure = index / musRep.getDivision() + 1;
    if (measure == musRep.getMeasureNum())
      return;
    for(BayesianMapping bm : readMappings) {
      MusicElement e = musRep.getMusicElement(bm.layer, bm.musicRepIndex(musRep, index));
      bayesNet.setEvidence(bm.bayesnetIndex, e.getLabel(e.getHighestProbIndex()));
    }
    bayesNet.update();
    for(BayesianMapping bm : writeMappings) {
      MusicElement e = musRep.getMusicElement(bm.layer, bm.musicRepIndex(musRep, index));
      double[] margins = bayesNet.getMargin(bm.bayesnetIndex);
      for(int i=0; i<margins.length; i++)
        e.setProb(i, margins[i]);
      if(bm.update)
        musRep.update(bm.layer, bm.musicRepIndex(musRep, index));
    }
  }

  public void addReadMapping(BayesianMapping bm) {
    readMappings.add(bm);
  }

  public void addWriteMapping(BayesianMapping bm) {
    writeMappings.add(bm);
  }
}
