//
//  MyMIDIController.java
//  Skeleton MIDI controller
//
//  Created by Marius Wolf on Mon Oct 25 2004.
//  Modified by Jan Buchholz on Mon Oct 31 2005.

import com.apple.audio.midi.*;
import com.apple.audio.util.*;

public class MyMIDIController implements MIDIReadProc
{
	private MIDIOutputPort output_;
	private MIDIEndpoint synth_;
	private MIDIInputPort input_;
	private MIDIEndpoint keyboard_; // assuming you using a keyboard for input
	private boolean isInitialized_ = false;

	// Initialize MIDI Connection; must be called before using the class
	public void initMIDI() 
	{
	  if (!isInitialized_) 
	  {
		 try 
		 {
			MIDIClient client = new MIDIClient(new CAFString("MyMIDIController"), null);
			
			// creating the input port and connecting it to a source (e.g., keyboard)
			input_		= client.inputPortCreate(new CAFString("Input"), this);
			keyboard_	= MIDISetup.getSource(0);// <- try to find the right source here
			input_.connectSource( keyboard_ );
			
			// creating the output Port
			output_ = client.outputPortCreate(new CAFString("Output"));
			synth_	= MIDISetup.getDestination(0);// <- try to find the right destination here 
		 }
		 catch (Exception e)
		 {
		 }
		 isInitialized_ = true;
	  }
	}

	// Plays the note specified by the parameter byte on channel 0 
	public void playNote(byte note) 
	{
	  if (isInitialized_) 
	  {
		 try 
		 {
			// Compose note on-event
			MIDIData noteOnEvent = MIDIData.newMIDIRawData(length);
			byte[] noteOn = new byte[length];
			// ... compose MIDI packet here ...
			noteOnEvent.addRawData(noteOn);

			// Compose a note off-event
			MIDIData noteOffEvent = MIDIData.newMIDIRawData(3);
			byte[] noteOff = new byte[3];
			// ... compose MIDI packet here ...
			noteOffEvent.addRawData(noteOff);

			// Add event to packet list and send it.
			MIDIPacketList list = new MIDIPacketList();
			list.add(0, noteOnEvent); // the timestamp 0 stands for immediately
			list.add(HostTime.getCurrentHostTime() + HostTime.convertNanosToHostTime(1000000000), noteOffEvent);
			
			output_.send(synth_, list);
		 }
		 catch (Exception e)
		 {
		 }
	  }
	}

	public void programChange(byte program) 
	{
	  // insert code here
	}

	public void execute( MIDIInputPort port , MIDIEndpoint srcEndPoint , MIDIPacketList list ) {
		MIDIPacket currentPacket;
		MIDIData currentDataset;		
		int dataPosition;
		int currentDate;
		
		// going through the packets one by one
		for(int i=0; i<list.numPackets(); ++i) {
			currentPacket	= list.getPacket(i);
			currentDataset	= currentPacket.getData();
			dataPosition	= 0;			

			// going through the package contents
			while(dataPosition < currentDataset.getMIDIDataLength()){
				// first byte shows the type of the current message
				currentDate = currentDataset.getUByteAt(dataPosition++);
				
				// Now filter out NoteOn messages.
				// NoteOns with a velocity of 0 are often used instead of NoteOffs.
				// Be sure to take care of this...
				
			}
		}
		
	}

}
