package jp.crestmuse.cmx.bayesband.sp;

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

public class MelodyWriter extends SPModule {

  private MusicRepresentation mr;
  private boolean writeLog;

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

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

  /*
    private void updateGui(int index) {
      int nextChordIndex = (index / mr.getDivision() + 1) * mr.getDivision();
      if (nextChordIndex < mr.getDivision() * mr.getMeasureNum()) {
        MusicElement chord = mr.getChordElement(nextChordIndex);
        if (chord.set()) {
          for (int i = 0; i < 7; i++)
            probs[i] = chord.getProb(i);
          GUI.getInstance().keyPressed(probs);
        }
      }
    }
  */

  public void execute(SPElement[] src, TimeSeriesCompatible<SPElement>[] dest)
      throws InterruptedException {
    MidiEventWithTicktime w = (MidiEventWithTicktime)src[0];
    byte[] message = w.getMessage().getMessage();
    if ((message[0] & 0xF0) == MIDIConst.NOTE_ON && message[2] > 0) {
      int index = mr.getIndex(w.music_position);
      // MusicElement me = mr.getMelodyElement(index);
      MusicElement me = mr.getMusicElement("melody", index);
      me.setEvidence(message[1] % 12);
      // mr.update(Type.Melody, me, index);
      mr.update("melody", index);
      // updateGui(index);
      if (writeLog) {
        int nextNoteIndex = index + 1;
        if (nextNoteIndex < mr.getDivision() * mr.getMeasureNum()) {
          System.out.println(w.music_position + ", " + message[1] + ", "
              + message[2]);
          // MusicElement note = mr.getMelodyElement(nextNoteIndex);
          MusicElement note = mr.getMusicElement("melody", nextNoteIndex);
          if (note.set()) {
            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();
          }
        }
        int nextChordIndex = (index / mr.getDivision() + 1) * mr.getDivision();
        if (nextChordIndex < mr.getDivision() * mr.getMeasureNum()) {
          // MusicElement chord = mr.getChordElement(nextChordIndex);
          MusicElement chord = mr.getMusicElement("chord", nextChordIndex);
          if (chord.set()) {
            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 Class<SPElement>[] getInputClasses() {
    return new Class[]{ MidiEventWithTicktime.class };
  }

  public Class<SPElement>[] getOutputClasses() {
    return new Class[0];
  }
}
