/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package midi;

import data.INote;
import data.IPart;
import data.IPhrase;
import data.IScore;
import hanson.HansonParser;
import java.io.File;
import java.text.DecimalFormat;
import java.util.Enumeration;
import jm.music.data.Note;
import jm.music.data.Part;
import jm.music.data.Phrase;
import jm.music.data.Score;
import jm.util.Read;

/**
 *
 * @author smuRf
 */
public class MIDIAnalyser {
    private File midiFile;
    
    public MIDIAnalyser()
    {
        
    }
    
    public MIDIAnalyser(File _midiFile)
    {
        midiFile = _midiFile;
    }
    
    public IScore analyse()
    {
        Score score = new Score();
        Read.midi(score, midiFile.getAbsolutePath());
        
        return analyseTask(score);
    }
    
    public IScore analyse(IScore iScore)
    {
        return analyseTask(iScore.getScore());
    }
    
    public IScore analyse(Phrase phrase, int tempo, int instrument)
    {
        IScore iScore = new IScore("newScore", tempo);
        IPart iPart = new IPart("newPart", instrument, 0);
        IPhrase newIPhrase = new IPhrase("newPhrase", 0, phrase);
        
        iScore.addIPart(iPart);
        iPart.addIPhrase(newIPhrase);
        
        return analyseTask(iScore.getMusicStructure());
    }
    
    public IScore analyseTask(Score score)
    {   
        double tempo = ((int) Math.round(score.getTempo()*10.0))/10.0;
        IScore iScore = new IScore("newScore", tempo, score.getNumerator(), score.getDenominator());
        if(score.getPPQN() == 0)
            iScore.setPPQN(480);
        else
            iScore.setPPQN(score.getPPQN());

        Enumeration e = score.getPartList().elements();
        while(e.hasMoreElements())
        {
            Part nextPt = (Part)e.nextElement();
            
            IPart iPart = new IPart(nextPt.getTitle(), nextPt.getInstrument(), nextPt.getChannel());
            iScore.addIPart(iPart);
            
            Enumeration e2 = nextPt.getPhraseList().elements();
            while(e2.hasMoreElements())
            {
                Phrase nextPhr = (Phrase)e2.nextElement();
                
                IPhrase iPhrase = new IPhrase(nextPhr.getTitle(), nextPhr.getStartTime());
                iPhrase.setMute(nextPhr.getMute());
                
                Enumeration e3 = nextPhr.getNoteList().elements();
                while(e3.hasMoreElements())
                {
                    Note nextNote = (Note)e3.nextElement();
                    
                    int dynamic = nextNote.getDynamic();
                    double realDuration = nextNote.getRhythmValue();
                    double duration = nextNote.getRhythmValue()/iScore.getPPQN();
                    DecimalFormat roundDuration = new DecimalFormat("#.##"); 
                    duration = Double.valueOf(roundDuration.format(duration).replace(",", "."));
                    double rhythmValue = duration;
                    int pitch = nextNote.getPitch();
                    String note = nextNote.getNote();
                    
                    INote iNote;
                    if(pitch == Integer.MIN_VALUE) // REST
                        iNote = new INote("REST", duration, realDuration, rhythmValue, dynamic);
                    else
                        iNote = new INote(note, (pitch/12)-1, duration, realDuration, pitch, rhythmValue, dynamic);
                    
                    iPhrase.addINote(iNote);
                }
                iPart.addIPhrase(iPhrase);
                
                iPhrase.addHansonRepresentation(HansonParser.convertToHansonRepresentation(iPhrase));
                iPart.getNormalizedIPhrase(iPart.getOriginalIPhrases().size()-1).addHansonRepresentation(HansonParser.convertToHansonRepresentation(iPart.getNormalizedIPhrase(iPart.getOriginalIPhrases().size()-1)));
            }
        }
        
        return iScore;
    }
}
