package com.haxademic.core.hardware.midi;

import java.util.List;

import javax.sound.midi.MidiDevice;
import javax.sound.midi.MidiMessage;
import javax.sound.midi.MidiSystem;
import javax.sound.midi.MidiUnavailableException;
import javax.sound.midi.Receiver;
import javax.sound.midi.ShortMessage;
import javax.sound.midi.Transmitter;

import com.haxademic.core.app.P;

public class MidiHandler
implements Runnable {

	// from: http://stackoverflow.com/questions/6937760/java-getting-input-from-midi-keyboard

    public static final int NOTE_ON = 0x90;
    public static final int NOTE_OFF = 0x80;
    public static final String[] NOTE_NAMES = {"C", "C#", "D", "D#", "E", "F", "F#", "G", "G#", "A", "A#", "B"};
	
	public MidiHandler() {
	}
	
    public void run(){
    	MidiDevice device;
    	MidiDevice.Info[] infos = MidiSystem.getMidiDeviceInfo();
    	
    	for (int i = 0; i < infos.length; i++) {
    		try {
    			device = MidiSystem.getMidiDevice(infos[i]);
    			//does the device have any transmitters?
    			//if it does, add it to the device list
    			System.out.println(infos[i]);
    			
    			//get all transmitters
    			List<Transmitter> transmitters = device.getTransmitters();
    			//and for each transmitter
    			
    			for(int j = 0; j < transmitters.size(); j++ ) {
    				//create a new receiver
    				transmitters.get(j).setReceiver(
    						//using my own MidiInputReceiver
    						new MidiInputReceiver(device.getDeviceInfo().toString())
    						);
    			}
    			
    			Transmitter trans = device.getTransmitter();
    			trans.setReceiver(new MidiInputReceiver(device.getDeviceInfo().toString()));
    			
    			//open each device
    			device.open();
    			//if code gets this far without throwing an exception
    			//print a success message
    			System.out.println(device.getDeviceInfo()+" was opened");
    			
    		} catch (MidiUnavailableException e) {}
    	}
    }


	// tried to write my own class. I thought the send method handles an MidiEvents sent to it
	public class MidiInputReceiver implements Receiver {
		public String name;
		public MidiInputReceiver(String name) {
			this.name = name;
		}

		public void send(MidiMessage message, long timeStamp) {
//			System.out.println("midi received");
			if (message instanceof ShortMessage) {
				ShortMessage sm = (ShortMessage) message;
//				P.print("|| "+sm.getCommand()+" ||");
				if (sm.getCommand() == NOTE_ON) {
					int key = sm.getData1();
					int velocity = sm.getData2();
					P.p.noteOn(1, key, velocity);
//					int note = key % 12;
//					String noteName = NOTE_NAMES[note];
//					int octave = (key / 12)-1;
//					P.println("Channel: " + sm.getChannel());
				}
			}
		}

		public void close() {}
	}
}

@@ -1093,33 +1093,40 @@
 fos%5Bi%5D);%0A    %09%09%09
+    %09%09%09
 %0A
-
     %09%09%09//get all
@@ -1866,24 +1866,17 @@
 ened%22);%0A
-    %09%09%09
 %0A
+
     %09%09%7D 
@@ -1932,100 +1932,8 @@
 %7D%0A%0A%0A
-%09// tried to write my own class. I thought the send method handles an MidiEvents sent to it%0A
 %09pub
@@ -2135,26 +2135,17 @@
  %7B%0A//%09%09%09
-System.out
+P
 .println
@@ -2159,17 +2159,27 @@
 received
-%22
+, %22+message
 );%0A%09%09%09if
@@ -2261,18 +2261,16 @@
 essage;%0A
-//
 %09%09%09%09P.pr
@@ -2276,12 +2276,39 @@
 rint
-(%22%7C%7C
+ln(%22ShortMessage.getCommand() =
  %22+s
@@ -2325,14 +2325,8 @@
 nd()
-+%22 %7C%7C%22
 );%0A%09
@@ -2351,16 +2351,29 @@
 nd() == 
+ShortMessage.
 NOTE_ON)
@@ -2633,13 +2633,639 @@
 ));%0A
-
 %09%09%09%09%7D
+ else if (sm.getCommand() == ShortMessage.NOTE_OFF) %7B%0A%09%09%09%09%09int key = sm.getData1();%0A%09%09%09%09%09int velocity = sm.getData2();%0A%09%09%09%09%09P.p.noteOff(1, key, velocity);%0A//%09%09%09%09%09int note = key %25 12;%0A//%09%09%09%09%09String noteName = NOTE_NAMES%5Bnote%5D;%0A//%09%09%09%09%09int octave = (key / 12)-1;%0A//%09%09%09%09%09P.println(%22Channel: %22 + sm.getChannel());%0A%09%09%09%09%7D else if (sm.getCommand() == ShortMessage.CONTROL_CHANGE) %7B%0A%09%09%09%09%09int key = sm.getData1();%0A%09%09%09%09%09int ccValue = sm.getData2();%0A%09%09%09%09%09P.p.controllerChange(sm.getChannel(), sm.getData1(), sm.getData2());%0A//%09%09%09%09%09P.println(%22CONTROL_CHANGE Channel: %22 + sm.getChannel() + %22 %22 + sm.getData1() + %22 %22 + sm.getData2());%0A%09%09%09%09%7D 
 %0A%09%09%09

Add MIDI note off handling and CC test addition