clear;

%initialize variables
dur = .75;
fs = 10000;
n = 11;
x = floor(n/2);
y = floor(n/2);
a = 2^(1/12);
grid = zeros(n);
grid(x,y) = 1;

%create grid of rootnotes
notes = zeros(n);
for i = 1:n
    notes(i,1) = 261.626;
    for j = 2:n
            if(mod(j,7) == 4 || mod(j,7) == 1)
                notes(i,j,1) = notes(i,j-1)*a;
            else
                notes(i,j,1) = notes(i,j-1)*a^2;
            end
    end
    notes(i,1,2:3) = [notes(i,1,1)*a^4 notes(i,1,1)*a^7];
    notes(i,2,2:end) = [notes(i,2,1)*a^3 notes(i,2,1)*a^7];
    notes(i,3,2:end) = [notes(i,3,1)*a^3 notes(i,1,1)*a^7];
    notes(i,4,2:end) = [notes(i,4,1)*a^4 notes(i,4,1)*a^7];
    notes(i,5,2:end) = [notes(i,5,1)*a^4 notes(i,5,1)*a^7];
    notes(i,6,2:end) = [notes(i,6,1)*a^3 notes(i,6,1)*a^7];
    notes(i,7,2:end) = [notes(i,7,1)*a^3 notes(i,7,1)*a^7];
    notes(i,8,2:end) = [notes(i,8,1)*a^4 notes(i,8,1)*a^7];
    notes(i,9,2:end) = [notes(i,9,1)*a^3 notes(i,9,1)*a^7];
    notes(i,10,2:end) = [notes(i,10,1)*a^3 notes(i,10,1)*a^7];
    notes(i,11,2:end) = [notes(i,11,1)*a^4 notes(i,11,1)*a^7];
end

%create mapping of characters to probablitities:
alphabet = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '0'];
probs = containers.Map;
for i = 1:size(alphabet,2)
    probs(alphabet(i)) = zeros(1,4);
    probleft = 1;
    toSet = probs(alphabet(i));
    for j = 1:4
        toSet(j) = rand();
    end
    toSet = sort(toSet);
    probs(alphabet(i)) = toSet;
end
    
%get user input
in = input('Please insert a string to turn into a melody\n','s');

%main loop
for k = 1:size(in,2)
    %leave current spot
    grid = grid-1;
    
    %lookup probability distribution
    if ismember(in(k),probs.keys)
        dist = probs(in(k));
    else
        dist = probs('0');
    end
    
    %pick next spot, if hit wall, keep picking
    while 1 == 1
        dir = rand();
        if dir <= dist(1)
            %go up
            y = y+1;
            order = [.85, .10, .05; .05, .85, .10; .05, .10, .85];
            %root_note = root_note * a^2;
        elseif dir <= dist(2)
            %go down
            y = y-1;
            order = [.05, .10, .85; .10, .85, .05; .85, .10, .05;];
            %root_note = root_note / a^2;
        elseif dir <= dist(3)
            %go left
            x = x-1;
            order = [.33, .33, .33; .33, .33, .33; .33, .33, .33];
            dur = max(.1, dur + .05);
        else
            %go right
            x = x+1;
            order = [.33, .33, .33; .33, .33, .33; .33, .33, .33];
            dur = dur - .05; 
        end
        if x>=1 && x<=n && y>=1 && y<=n
            break
        end
    end
    
    %REPLACED WITH ABOVE LOOP
%     %boundary conditions
%     if y > n
%         y = 1;
%     elseif y < 1
%         y = n;
%     end
%     if x < 1
%         x = 1;
%         dur = dur - .05;
%     elseif x > n
%         x = n;
%         dur = dur + .05;
%     end
    
    %visually move on grid
    grid(x,y) = 1;
    imagesc(grid');
    set(gca,'YDir','normal');
    colormap(1-gray);
    axis equal;
    axis tight;
    title('Visual Map of Melody Changes', 'FontSize', 20)
    xlabel('Duration of triad melody', 'FontSize', 15)
    ylabel('Root Note of Triad', 'FontSize', 15)
    
    %play Triad
    root_note = notes(x,y);
    
    
    %SOUNDS TERRIBLE IN MATLAB
%      t = linspace(0,dur,dur*fs);
%      amp = linspace(1,0,size(t,2));
%      s1 = sin(root_note*2*pi*t);
%      s2 = sin(root_note/a^2*2*pi*t);
%      s3 = sin(root_note*a^2*2*pi*t);
%      note = s1+s2+s3;
%      sound(note, fs)

    %Play 3 note melody
    for i = 1:3
        %chance of note not being full note
        r = rand();
        if r < .2
            note_dur = dur*.25;
            played = 4;
        elseif r < .4
            note_dur = dur*.5;
            played = 2;
        else
            note_dur = dur;
            played = 1;
        end
        t = linspace(0,note_dur,note_dur*fs);
        amp = linspace(1,0,size(t,2));
        %randomly decide order in which to play 3 notes
            r = rand();
            if r <= order(i,1)
                freq = notes(x,y,1);
            elseif r <= order(i,1)+order(i,2)
                freq = notes(x,y,2);
            else
                freq = notes(x,y,3);
            end
            note = sin(freq*2*pi*t);
            ampd = note.*amp;
            for j = 1:played
                r = rand();
                if r > .10
                    sound(ampd, fs);
                end
            end
            pause(note_dur);
    end 
end