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

import data.IHanson;
import data.INote;
import data.IPhrase;
import hanson.HansonStatics.DIRECTION;
import hanson.HansonStatics.NOTE_INTERVAL;
import hanson.HansonStatics.OCTAVE_INERVAL;
import java.text.DecimalFormat;

/**
 *
 * @author smuRf
 */
public class HansonParser {

    public static IHanson[] convertToHansonRepresentation(IPhrase iPhrase)
    {
        IHanson iHanson[] = new IHanson[2];
        iHanson[0] = new IHanson();
        iHanson[1] = new IHanson();
        
        INote prevNote = null;
        iHanson[1].addInterval(-3);
        for(INote iNote:iPhrase.getINotes())
        {
            if(prevNote == null)
            {
                prevNote = iNote;
                continue;
            }
            
            int diff = Math.abs(prevNote.getPitch()-iNote.getPitch());
            
            if(prevNote.getPitch() == 0 || iNote.getPitch() == 0)
            {
                iHanson[0].addInterval(-2*10-iNote.getRhythmValue()-prevNote.getRhythmValue());
                iHanson[1].addInterval(-2*10-iNote.getRhythmValue()-prevNote.getRhythmValue());
            }
            else
            {
                if(diff > 0)
                {
                    int interval = (diff-1)%6;
                    int octave = ((diff-1)/6)%5;

                    NOTE_INTERVAL i = NOTE_INTERVAL.values()[interval];
                    OCTAVE_INERVAL o = OCTAVE_INERVAL.values()[octave];
                    DIRECTION d = iNote.getPitch()>prevNote.getPitch()?DIRECTION.r:DIRECTION.l;

                    iHanson[0].addInterval(i.ordinal()*1000+o.ordinal()*100+d.ordinal()*10+iNote.getRhythmValue()+prevNote.getRhythmValue());
                    iHanson[1].addInterval(i.ordinal()*1000+o.ordinal()*100+d.ordinal()*10+iNote.getRhythmValue()+prevNote.getRhythmValue());
                }
                if(diff == 0)
                {
                    iHanson[0].addInterval(-1*10-iNote.getRhythmValue()-prevNote.getRhythmValue());
                    iHanson[1].addInterval(-1*10-iNote.getRhythmValue()-prevNote.getRhythmValue());
                }
            }
            
            prevNote = iNote;
        }
        
        return iHanson;
    }
    
    public static double getDoubleForString(String str)
    {
        if(str.startsWith("loo"))
        {
            double duration = Double.parseDouble(str.replace("loo", ""));
            return (duration*-1)-10;
        }
        else if(str.startsWith("rest"))
        {
            double duration = Double.parseDouble(str.replace("rest", ""));
            return (duration*-1)-20;
        }
        else
        {
            char i = str.charAt(0);
            char o = str.charAt(1);
            char d = str.charAt(2);
            String duration = str.substring(3);
            
            double value = 0;
            
            //interval
            {
                switch(i)
                {
                    case 'd':
                        value += 0*1000;
                        break;
                    case 's':
                        value += 1*1000;
                        break;
                    case 'n':
                        value += 2*1000;
                        break;
                    case 'm':
                        value += 3*1000;
                        break;
                    case 'p':
                        value += 4*1000;
                        break;
                    case 't':
                        value += 5*1000;
                        break;
                }
            }
            
            //octave
            {
                switch(o)
                {
                    case 'a':
                        value += 0*100;
                        break;
                    case 'e':
                        value += 1*100;
                        break;
                    case 'i':
                        value += 2*100;
                        break;
                    case 'o':
                        value += 3*100;
                        break;
                    case 'u':
                        value += 4*100;
                        break;
                }
            }
            
            //direction
            {
                switch(d)
                {
                    case 'r':
                        value += 0*10;
                        break;
                    case 'l':
                        value += 1*10;
                        break;
                }
            }
            
            //duration
            {
                value += Double.parseDouble(duration);
            }
            
            return value;
        }
    }
    
    public static String getStringForValue(double value)
    {
        DecimalFormat roundDuration = new DecimalFormat("#.##"); 
        String strHanson = "";
        
        if((int)(value/10) == -1)
        {
            double duration = Double.valueOf(roundDuration.format((value+10.0)*-1).replace(",", "."));
            strHanson += "loo"+Math.abs(duration)+"\n";
        }
        else if((int)value/10 <= -2)
        {
            double duration = Double.valueOf(roundDuration.format(value+20.0).replace(",", "."));
            strHanson += "rest"+Math.abs(duration)+"\n";
        }
        else
        {
            NOTE_INTERVAL i = NOTE_INTERVAL.values()[(int)value/1000];
            OCTAVE_INERVAL o = OCTAVE_INERVAL.values()[(int)((value-(i.ordinal()*1000))/100)];
            DIRECTION d = DIRECTION.values()[(int)((value-i.ordinal()*1000 - o.ordinal()*100)/10)];
            double duration = Double.valueOf(roundDuration.format((value-i.ordinal()*1000 - o.ordinal()*100 - d.ordinal()*10)).replace(",", "."));
            
            switch(i)
            {
                case d:
                    strHanson += "d";
                    break;
                case s:
                    strHanson += "s";
                    break;
                case n:
                    strHanson += "n";
                    break;
                case m:
                    strHanson += "m";
                    break;
                case p:
                    strHanson += "p";
                    break;
                case t:
                    strHanson += "t";
                    break;
            }
            switch(o)
            {
                case a:
                    strHanson += "a";
                    break;
                case e:
                    strHanson += "e";
                    break;
                case i:
                    strHanson += "i";
                    break;
                case o:
                    strHanson += "o";
                    break;
                case u:
                    strHanson += "u";
                    break;
            }
            switch(d)
            {
                case r:
                    strHanson += "r";
                    break;
                case l:
                    strHanson += "l";
                    break;
            }
            
            strHanson += Math.abs(duration);
        }
        
        return strHanson;
    }
}
