function mapLoops(bf_string) {
    var retVal = new Array();
    var openIndex = new Array();

    for (var i = 0; i < bf_string.length; i++) {
        if (bf_string.charAt(i) == "[") {
            openIndex.push(i);
        } else if (bf_string.charAt(i) == "]") {
            retVal.push(openIndex[openIndex.length - 1].toString() + "|" + i.toString());
            openIndex.pop();
        }
    }

    return retVal;
}

function getLoopEndIndex(loopMap, startIdx) {
    var retVal = -1;

    for (var i = 0; i < loopMap.length; i++) {
        if (loopMap[i].split("|")[0] == startIdx.toString()) {
            retVal = parseInt(loopMap[i].split("|")[1]);
        }
    }

    return retVal == -1 ? startIdx + 1 : retVal;
}

function getLoopStartIndex(loopMap, endIdx) {
    var retVal = -1;

    for (var i = 0; i < loopMap.length; i++) {
        if (loopMap[i].split("|")[1] == endIdx.toString()) {
            retVal = parseInt(loopMap[i].split("|")[0]);
        }
    }

    return retVal == -1 ? endIdx + 1 : retVal;
}

function brainfuck(bf_string) {
    var byteVal = new Array();
    var currIdx = 0;
    var output = "";
    var userImput = "";
    var loopMap = mapLoops(bf_string);
    byteVal.push(0);
    for (var i = 0; i < bf_string.length;) {
        switch (bf_string.charAt(i)) {
            case "+":
                byteVal[currIdx]++;
                i++;
                break;

            case "-":
                byteVal[currIdx]--;
                i++;
                break;

            case ">":
                currIdx++;
                if (byteVal.length < currIdx + 1) {
                    byteVal.push(0);
                }
                i++;
                break;

            case "<":
                currIdx--;
                i++;
                break;
            case "[":
                if (byteVal[currIdx] == 0) {
                    i = getLoopEndIndex(loopMap, i);
                } else {
                    i++;
                }
                break;

            case "]":
                if (byteVal[currIdx] > 0) {
                    i = getLoopStartIndex(loopMap, i);
                } else {
                    i++;
                }
                break;

            case ".":
                output += String.fromCharCode(byteVal[currIdx]);
                i++;
                break;

            case ",":
                userImput = prompt("Enter a char. If you enter a string only the first char will be taken");
                if (userImput == null || userImput.length == 0) {
                    byteVal[currIdx] = 0;
                } else {
                    byteVal[currIdx] = userImput.charCodeAt(0);
                }
                i++;
                break;

            default:
                i++;
                break;
        }
    }
    return output;
}