const turtle = new Turtle();
const mazeSize = 8; // min=3, max=30, step=1
const plusSize = 0.15; // min=0.00, max=0.5, step=0.01 
const minSize = 0.15; // min=0.00, max=0.5, step=0.01
const pipeSize = 0.55; // min=0.00, max=1, step=0.01
const mazeLines = display(maze(mazeSize,mazeSize));
const scale = 75 / mazeSize;

function jump(x,y) { turtle.jump((-mazeSize+x)*scale,(-mazeSize+y)*scale); }
function goto(x,y) { turtle.goto((-mazeSize+x)*scale,(-mazeSize+y)*scale); }

function walk(i) {
    let x = 0;
    const y = i;
    
    if (i === 0) {
        // entry arrow
        jump(x+1,y-1);
        goto(x+1,y);
        jump(x+1-0.2,y-0.2);
        goto(x+1,y);
        goto(x+1+0.2,y-0.2);
    }
    
    for(let char of mazeLines[i]) {
        if (plusSize && char == "+") {
            jump(x-plusSize,y);
            goto(x+plusSize,y);
            jump(x,y-plusSize);
            goto(x,y+plusSize);
        } else if (minSize && char == "-") {
            jump(x-minSize,y);
            goto(x+minSize,y);
        } else if (pipeSize && char == "|") {
            jump(x,y-pipeSize);
            goto(x,y+pipeSize);
        }
        x += 0.5;
    }
    if (i === mazeSize*2-1) {
        // exit arrow
        x+=0.5
        jump(x-1,y);
        goto(x,y);
        jump(x-0.2,y-0.2,);
        goto(x,y);
        goto(x-0.2,y+0.2);
    }
    return i < mazeSize*2;
}

/** 
 Sources 
 - <https://stackoverflow.com/questions/15981271/implement-maze-generation-algorithm-in-javascript> 
 - <https://rosettacode.org/wiki/Maze_generation#JavaScript>
**/
function maze(x,y) {
    var n=x*y-1;
    var horiz = []; for (var j= 0; j<x+1; j++) horiz[j] = [];
    var verti = []; for (var j= 0; j<y+1; j++) verti[j] = [];
    var here = [Math.random()*x|0, Math.random()*y|0];
    var path = [here];
    var unvisited= [];
    for (var j= 0; j<x+2; j++) {
        unvisited[j]= [];
        for (var k= 0; k<y+1; k++)
            unvisited[j].push(j>0 && j<x+1 && k>0 && (j != here[0]+1 || k != here[1]+1));
    }
    while (0<n) {
        var potential= [[here[0]+1, here[1]], [here[0],here[1]+1],
            [here[0]-1, here[1]], [here[0],here[1]-1]];
        var neighbors= [];
        for (var j= 0; j < 4; j++)
            if (unvisited[potential[j][0]+1][potential[j][1]+1])
                neighbors.push(potential[j]);
        if (neighbors.length) {
            n= n-1;
            next= neighbors[Math.floor(Math.random()*neighbors.length)];
            unvisited[next[0]+1][next[1]+1]= false;
            if (next[0] == here[0])
                horiz[next[0]][(next[1]+here[1]-1)/2]= true;
            else 
                verti[(next[0]+here[0]-1)/2][next[1]]= true;
            path.push(here = next);
        } else 
            here = path.pop();
    }
    return ({x: x, y: y, horiz: horiz, verti: verti});
}

function display(m) {
    let text = [];
    for (let j= 0; j<m.x*2+1; j++) {
        let line= [];
        if (j%2 === 0)
            for (let k=0; k<m.y*4+1; k++)
                if (k%4 === 0)  line[k] = '+';
                else
                    if (j>0 && m.verti[j/2-1][k/4|0]) line[k] = ' ';
                    else line[k]= '-';
        else
            for (let k=0; k<m.y*4+1; k++)
                if (k%4 === 0)
                    if (k>0 && m.horiz[(j-1)/2][k/4-1])  line[k] = ' ';
                    else line[k]= '|';
                else line[k]= ' ';
        if (j === 0) line[1] = line[2] = line[3] = ' ';
        if (m.x*2-1 === j) line[4*m.y] = ' ';
        text.push(line.join(''));
    }
    return text;
}