var memoryCells = 20;

var memory = new Array();
var currentMemoryPos = 0;
var currentCodePos = 0;
var running = false;
var stopRunning = false;

var memoryTable = document.getElementById("memorytable");
var memoryTableData = "";

for(var i = 0; i < memoryCells; i++)
{
    memory[i] = 0;
    memoryTableData += "<div id='memorycell" + i + "' class='memorycell'>0</div>";
}

memoryTable.innerHTML = memoryTableData;

document.getElementById("memorycell0").classList.add("active_cell");

function reset()
{
    if(running === true)
    {
        return;
    }
    
    currentMemoryPos = 0;
    currentCodePos = 0;
    
    var cell = null;
    for(var i = 0; i < memoryCells; i++)
    {
        memory[i] = 0;
        cell = document.getElementById("memorycell" + i);
        cell.innerHTML = "0";
        cell.classList.remove("active_cell");
    }
    
    document.getElementById("memorycell0").classList.add("active_cell");
    document.getElementById("outputcode").innerHTML = "";
    document.getElementById("output").innerHTML = "";
}

function start()
{
    if(running === true)
    {
        stopRunning = true;
        return;
    }
    var length = document.getElementById("input").value.length;
    if(currentCodePos >= length && length !== 0)
    {
        reset();
    }
    document.getElementById("start").innerHTML = "Halt";
    running = true;
    setTimeout(execute, 200);
}


function execute()
{
    var code = document.getElementById("input").value;
    
    var output = code.substring(0, currentCodePos) + "<span class='active_code'>" + 
            code.substring(currentCodePos, currentCodePos + 1) + "</span>" + code.substring(currentCodePos + 1, code.length);
    output = output.replace(new RegExp("\n", 'g'), "<br>");
    document.getElementById("outputcode").innerHTML = output;
    
    switch(code[currentCodePos])
    {
        case '>':
            document.getElementById("memorycell" + currentMemoryPos).classList.remove("active_cell");
            currentMemoryPos = (currentMemoryPos + 1) % memoryCells;
            document.getElementById("memorycell" + currentMemoryPos).classList.add("active_cell");
            break;
        case '<':
            document.getElementById("memorycell" + currentMemoryPos).classList.remove("active_cell");
            currentMemoryPos = (currentMemoryPos + memoryCells - 1) % memoryCells;
            document.getElementById("memorycell" + currentMemoryPos).classList.add("active_cell");
            break;
        case '+':
            memory[currentMemoryPos] = (memory[currentMemoryPos] + 1) % 256;
            document.getElementById("memorycell" + currentMemoryPos).innerHTML = memory[currentMemoryPos];
            break;
        case '-':
            memory[currentMemoryPos] = (memory[currentMemoryPos] + 255) % 256;
            document.getElementById("memorycell" + currentMemoryPos).innerHTML = memory[currentMemoryPos];
            break;
        case '.':
            var out = document.getElementById("output");
            out.innerHTML = out.innerHTML + String.fromCharCode(memory[currentMemoryPos]);
            break;
        case ',':
            break;
        case '[':
            if(memory[currentMemoryPos] === 0)
            {
                while(currentCodePos < code.length && code[currentCodePos] !== ']')
                {
                    currentCodePos++;
                }
            }
            break;
        case ']':
            if(memory[currentMemoryPos] !== 0)
            {
                while(currentCodePos >= 0 && code[currentCodePos] !== '[')
                {
                    currentCodePos--;
                }
            }
            break;
    }
    currentCodePos++;
    
    if(currentCodePos < code.length && !stopRunning)
    {
        setTimeout(execute, document.getElementById("delay").value);
    }
    else
    {
        running = false;
        stopRunning = false;
        document.getElementById("start").innerHTML = "Start";
    }
}