package ac.essex.ooechs.music.util.midi;

import javax.sound.midi.InvalidMidiDataException;
import javax.sound.midi.MidiSystem;
import javax.sound.midi.MidiUnavailableException;
import javax.sound.midi.Receiver;
import javax.sound.midi.ShortMessage;

/**
 * Plays a sequence of notes using the default Midi Player on your system.
 */
public class Player {

    int channel;

    Receiver receiver = null;

    public Player() {

        channel = 0;

        // We retrieve a Receiver for the default MidiDevice.
        try {
            receiver = MidiSystem.getReceiver();
        } catch (MidiUnavailableException e) {
            System.err.println(e);
            System.exit(1);
        }

    }

    public void play(Note n) {
        new NotePlayer(n).start();
    }

    class NotePlayer extends Thread {

        Note n;

        public NotePlayer(Note n) {
            this.n = n;
        }

        public void run() {

            ShortMessage onMessage = null;
            ShortMessage offMessage = null;

            try {
                onMessage = new ShortMessage();
                offMessage = new ShortMessage();
                onMessage.setMessage(ShortMessage.NOTE_ON, channel, n.key, n.volume);
                offMessage.setMessage(ShortMessage.NOTE_OFF, channel, n.key, 0);
            } catch (InvalidMidiDataException e) {
                System.err.println(e);
            }

            // Turn the note on
            receiver.send(onMessage, -1);

            // Wait, then turn the note off
            try {
                Thread.sleep(n.duration);
            } catch (InterruptedException e) {
                // Should not happen
            }

            // Turn the note off
            receiver.send(offMessage, -1);
        }

    }

    public void stop() {

        // Clean up
        receiver.close();

    }

}

