import java.awt.*;
import javax.sound.midi.*;
import javax.sound.midi.Sequencer;
import java.util.*;
import java.io.*;

public class MidiPlayer extends Panel
{
	public static void main(String arg[])
	{
		Frame f=new Frame("MidiPlayer");
		f.add(new MidiPlayerVisual());
		f.setSize(640,480);
		f.setVisible(true);
		f.addWindowListener(new Raamikuular());
	}
	
	public static String analyysi(String fail) throws Exception
	{
		String analyys="";
		Sequence sekvents=MidiSystem.getSequence(new java.io.File(fail));
    	analyys=analyys.concat("Faili "+fail +" pikkus on "+sekvents.getMicrosecondLength()/1000000.0+ " sekundit, ehk siis "+sekvents.getTickLength()+" tiksu "+"\n");
    	Track[] rajad=sekvents.getTracks();
    	analyys=analyys.concat("MIDI failis on "+rajad.length+" rada \n");
    	for(int nr=0; nr<rajad.length; nr++){
    		analyys=analyys.concat("Rada "+nr+" : \n");
      		for(int t=0; t<rajad[nr].size(); t++){
      			MidiEvent me=rajad[nr].get(t);
        		long tiks=me.getTick();
        		MidiMessage teade=me.getMessage();
        		if(teade instanceof ShortMessage){
          			ShortMessage sm=(ShortMessage)teade;
          			analyys=analyys.concat("Tiks nr: "+tiks+" teate tüüp - ShortMessage " + "kanal: "+sm.getChannel()+" teade: "+sm.getCommand()+" helikõrgus: "+sm.getData1()+" helitugevus: "+sm.getData2()+" \n");
        		}
        		if(teade instanceof MetaMessage){
          			MetaMessage mm=(MetaMessage)teade;
          			analyys=analyys.concat("Tiks nr: "+tiks+" teate tüüp - MetaMessage"+" tüübi nr: "+mm.getType() +" \n");
          			byte[] b=mm.getData();
          			for(int i=0; i<b.length; i++)analyys=analyys.concat(" "+b[i] +" \n");
        		}
      		}	
    	}
		return analyys;	
	}
	
	public static void mangi(String fail, int bpm) throws Exception
	{
	    Sequencer sekventser=MidiSystem.getSequencer();
    	sekventser.open();
    	sekventser.setSequence(MidiSystem.getSequence(new java.io.File(fail)));
    	sekventser.start();
    	if(bpm!=-1)
    	{
    		System.out.println("bpm="+bpm);
    		sekventser.setTempoInBPM(40);	
    	}
    		
	}
	
	public static String instrumendid() throws Exception
	{
		Synthesizer synthesizer=MidiSystem.getSynthesizer();
		synthesizer.open();
		Instrument[] pillid=synthesizer.getDefaultSoundbank().getInstruments();
		String str="";
		for(int i=0; i<pillid.length; i++)
		{
			str=str.concat(i+": "+pillid[i]+"\n");
		}
		return str;		
	} 	
	
	public static void salvesta(String fail1, String fail2, boolean tagurpidi, int instrument) throws Exception
	{
		Sequence sekvents=MidiSystem.getSequence(new File(fail1));
    	Track algrada=sekvents.getTracks()[sekvents.getTracks().length-1]; 
    	if(instrument!=-1)
    	{
    		System.out.println("instrument="+instrument);
    	
    		ShortMessage algus = new ShortMessage();
         	algus.setMessage(ShortMessage.PROGRAM_CHANGE, 0, instrument, 0);
         	MidiEvent me=new MidiEvent(algus, 0);
         	algrada.add(new MidiEvent(algus, 0));	
    	}
    	if(tagurpidi){
    		System.out.println("tagurpidi="+tagurpidi);
    		Track uusrada=sekvents.createTrack();
    		for(int nr=algrada.size()-1; nr>0; nr--)
    		{
    			System.out.println(nr+"");
      			MidiEvent me=algrada.get(nr);
      			if(me.getMessage() instanceof ShortMessage)
      			{
        			ShortMessage sm=(ShortMessage)me.getMessage();
        			ShortMessage sm2=new ShortMessage();
        			sm2=(ShortMessage)sm.clone();
        			uusrada.add(new MidiEvent(sm2, sekvents.getTickLength()-me.getTick()));
      			}else{
        			uusrada.add(me);
      			}
    		}
    		sekvents.deleteTrack(algrada);
    	}
    	MidiSystem.write(sekvents, 1, new FileOutputStream(fail2));
  	}
}