// You can find the Turtle API reference here: https://turtletoy.net/syntax
Canvas.setpenopacity(1);

const size = 90;        //min = 10, max = 100, step = 5
const grid = 30;         // min = 3, max = 80, step = 1

// Global code will be evaluated once.
const turtle = new Turtle();

let cells = [];

let vWalls = [];
let hWalls = [];

let stack = [];

let maxIndex = grid**2;

class Cell{
    constructor(i, j){
        this.i = i;
        this.j = j;
        this.visited = false;
//        this.twice = false;
        this.list = [];

        if(this.i > 0) this.list.push([-1, 0]);
        if(this.j > 0) this.list.push([0, -1]);
        if(this.i < grid - 1) this.list.push([1, 0]);
        if(this.j < grid - 1) this.list.push([0, 1]);
    }
    
    getNeighbor(){
        this.visited = true;
        
        for(let i = this.list.length - 1; i >= 0; i--){
            const index = this.list[i];
            const x = this.i + index[0];
            const y = this.j + index[1];
            
            const cell = cells[x][y];

            if(cell.visited){
                const tmp = this.list.slice(0, i);

                this.list = this.list.slice(i);
                this.list.shift();
                
                this.list = tmp.concat(this.list);
            }
        }
        const length = this.list.length;
        if(length){
//            this.twice = 1;
            
            const index = this.list[Math.floor(Math.random() * length)];
            let x = this.i;
            let y = this.j;
            
            if(index[0] != 0){
                // deplacing left or right
                if(index[0] > 0) vWalls[x + 1][y] = 0;
                else vWalls[x][y] = 0;
            } else if(index[1] != 0){
                // deplacing up or down
                if(index[1] > 0) hWalls[x][y + 1] = 0;
                else hWalls[x][y] = 0;
            }
            
//            console.log(this.i, this.j, index, hWalls[x][y], vWalls[x + 1][y], hWalls[x][y + 1], vWalls[x][y])
            
            x +=  + index[0];
            y +=  + index[1];
            
            return cells[x][y];
        } else {
            return null;
        }
    }
    
    draw(){
        const cellSize = (size * 2) / grid;
        const posx = this.i * cellSize - cellSize * grid / 2;
        const posy = this.j * cellSize - cellSize * grid / 2;
        turtle.jump(posx, posy);
        turtle.seth(0);
        for(let i = 0; i < 4; i++){
            turtle.forward(cellSize);
            turtle.right(90);
        }
/*        
        if(this.twice){
            turtle.jump(posx + 1, posy + 1);
            
            for(let i = 0; i < 4; i++){
                turtle.forward(cellSize - 2);
                turtle.right(90);
            }
        }
*/
    }
}

for(let j = 0; j < grid; j++){
    let row = [];
    for(let i = 0; i < grid; i++){
        row.push(new Cell(j, i));
//        console.log(i, j);
    }
    cells.push(row);
}

for(let j = 0; j <= grid; j++){
    let row = [];
    for(let i = 0; i < grid; i++){
        row.push(1);
    }
    vWalls.push(row);
}

for(let j = 0; j < grid; j++){
    let row = [];
    for(let i = 0; i <= grid; i++){
        row.push(1);
    }
    hWalls.push(row);
}

function drawWalls(){
    const cellSize = (size * 2) / grid;

    for(let j = 0; j <= grid; j++){
        for(let i = 0; i < grid; i++){
//            console.log(i, j);
            const posx = i * cellSize - cellSize * grid / 2;
            const posy = j * cellSize - cellSize * grid / 2;
            if(vWalls[i][j]){
                turtle.jump(posx, posy);
                turtle.goto(posx, posy + cellSize);
            }
            
            if(hWalls[i][j]){
                turtle.jump(posx, posy);
                turtle.goto(posx + cellSize, posy);
            }
            
        }
    }

    for(let i = 0; i < grid; i++){
        const posx = grid * cellSize - cellSize * grid / 2;
        const posy = i * cellSize - cellSize * grid / 2;
        if(vWalls[grid][i]){
            turtle.jump(posx, posy);
            turtle.goto(posx, posy + cellSize);
        }
    }
}

function drawPad(cell){
    const cellSize = (size * 2) / grid;
    const posx = cell.i * cellSize - cellSize * grid / 2 + cellSize / 2;
    const posy = cell.j * cellSize - cellSize * grid / 2 + cellSize / 2;
    
    const radius = cellSize / 5;
    
    for(let i = radius; i > 0; i -= 0.2){
        turtle.jump(posx, posy - i);
        turtle.seth(0);
        turtle.circle(i);
    }
}

function drawRoute(start, end){
    const cellSize = (size * 2) / grid;
    let posx = start.i * cellSize - cellSize * grid / 2  + cellSize / 2;
    let posy = start.j * cellSize - cellSize * grid / 2  + cellSize / 2;
    turtle.jump(posx, posy);
}


stack.push(cells[Math.floor(Math.random() * grid)][Math.floor(Math.random() * grid)]);
drawPad(stack[stack.length - 1]);

let lastTime = Date.now();
let farthestCell;
let biggestStackSize = 0;

const firstCell = stack[0];

// The walk function will be called until it returns false.
function walk(i) {
    
    const length = stack.length;
    
    if(!length){
        drawWalls();
        drawPad(farthestCell);
        drawRoute(firstCell, farthestCell);
        return false;
    }
    
    let cell = stack.pop();
    lastCell = cell;


    if(length > biggestStackSize){
        biggestStackSize = length;
        farthestCell = cell;
    }
    
    let newCell = cell.getNeighbor();
    
    if(newCell != null){
        stack.push(cell);
        stack.push(newCell);
    }
    
/*
    while(lastTime >= Date.now());
    lastTime = Date.now() + 50;
*/
    
    return true;
}