package jp.crestmuse.cmx.inference;

import java.util.List;

import jp.crestmuse.cmx.amusaj.filewrappers.TimeSeriesCompatible;
import jp.crestmuse.cmx.amusaj.sp.MidiEventWithTicktime;
import jp.crestmuse.cmx.amusaj.sp.SPDummyObject;
import jp.crestmuse.cmx.amusaj.sp.SPModule;
import jp.crestmuse.cmx.inference.MusicRepresentation;
import jp.crestmuse.cmx.inference.MusicRepresentation.MusicElement;
import jp.crestmuse.cmx.inference.MusicRepresentation.Type;
import jp.crestmuse.cmx.misc.QueueReader;
import jp.crestmuse.cmx.misc.MIDIConst;

public class MusicRepresentationModule extends
    SPModule<MidiEventWithTicktime, SPDummyObject> {

  private MusicRepresentation musicRepresentation;
  private boolean writeLog;

  public MusicRepresentationModule(MusicRepresentation mr){
    this(mr, false);
  }

  public MusicRepresentationModule(MusicRepresentation mr, boolean writeLog) {
    musicRepresentation = mr;
    this.writeLog = writeLog;
  }

  public void execute(List<QueueReader<MidiEventWithTicktime>> src,
      List<TimeSeriesCompatible<SPDummyObject>> dest)
      throws InterruptedException {
    MidiEventWithTicktime w = src.get(0).take();
    byte[] message = w.getMessage().getMessage();
    if ((message[0] & 0xF0) == MIDIConst.NOTE_ON && message[2] > 0) {
      int index = musicRepresentation.getIndex(w.music_position);
      MusicElement me = musicRepresentation.addMelodyElement(index);
      me.setEvidence(message[1]);
      musicRepresentation.update(Type.Melody, me, index);
      if(writeLog && index < musicRepresentation.getDivision()*musicRepresentation.getMeasureNum() - 2){
        System.out.println(w.music_position + ", " + message[1] + ", " + message[2]);
        MusicElement note = musicRepresentation.getMelodyElement(index + 1);
	if (note != null) {
          for(int i=0; i<11; i++)
	    System.out.print(note.getLabel(i) + ":" + note.getProb(i) + ", ");
        }
	System.out.print(note.getLabel(11) + ":" + note.getProb(11));
        System.out.println();
        MusicElement chord = musicRepresentation.getChordElement((index/musicRepresentation.getDivision() + 1) * musicRepresentation.getDivision());
	if (chord != null) {
          for(int i=0; i<6; i++)
            System.out.print(chord.getLabel(i) + ":" + chord.getProb(i) + ", ");
	  System.out.print(chord.getLabel(6) + ":" + chord.getProb(6));
        }
        System.out.println();
      }
    }
  }

  public int getInputChannels() {
    return 1;
  }

  public int getOutputChannels() {
    // return 1; // tentative
    return 0;
  }

}
