var currentMode = "";
var ignoreLines = false;
var ignoreSpaces = false;

function mode(m) {
    switch(m) {
        case "ascii"  : document.getElementById("mode").innerHTML = "ASCII -> Hex and binary"; color(true, false, false); break;
        case "hex"    : document.getElementById("mode").innerHTML = "Hex -> ASCII and binary"; color(false, true, false); break;
        case "bin"    : document.getElementById("mode").innerHTML = "Binary -> Hex and ASCII"; color(false, false, true); break;
        default       : return;
    }
    currentMode = m;
}

function convert() {
    if(currentMode == "") { return; }

    var str = new String(document.getElementById(currentMode).value);
    if(ignoreLines)  { str = str.replace(/[\r\n]/g, ""); }
    if(ignoreSpaces) { str = str.replace(/\s/g, ""); }
    if(!str) { return; }

    switch(currentMode) {
        case "ascii" :
            document.getElementById("hex").value = char_to_hex(str);
            document.getElementById("bin").value = char_to_bin(str);
            break;
        case "hex" :
            document.getElementById("ascii").value = hex_to_char(str);
            document.getElementById("bin").value = hex_to_bin(str);
            break;
        case "bin" :
            document.getElementById("ascii").value = bin_to_char(str);
            document.getElementById("hex").value = bin_to_hex(str);
            break;
    }
}

function replaceText() {
    var modeName = ((currentMode == "bin") ? "binary" : ((currentMode == "ascii") ? "ASCII" : currentMode));
    var toReplace = prompt("Select " + modeName + " text to replace:", "");
    if(!toReplace) { return; }
    var replaceWith = prompt("Replace \"" + toReplace + "\" with:\n\n(leaving this blank will erase text)", "");
    if(replaceWith === undefined) { return; }
    if(!confirm("Replace \"" + toReplace + "\" with \"" + replaceWith + "\" in " + modeName + " text?")) { return; }

    var inputBox = document.getElementById(currentMode);
    var toReplaceRegex = RegExp(toReplace.replace(/([\\^$*+?.([{|])/g, "\\$1"), "g");
    inputBox.value = inputBox.value.replace(toReplaceRegex, replaceWith);
}

function char_to_hex(val) {
    var hexStr = "0123456789ABCDEF";
    var hex = "";
    for(var i = 0; i < val.length; ++i) {
        var charCode = val.charCodeAt(i);
        hex += hexStr.charAt(Math.floor(charCode / 16 % 16)) + hexStr.charAt(charCode % 16);
    }
    return hex;
}

function char_to_bin(val) {
    var bin = "";
    for(var i = 0; i < val.length; ++i) {
        var charCode = val.charCodeAt(i);
        for(var j = 7; j >= 0; --j) {
            bin += (charCode >> j) % 2;
        }
    }
    return bin;
}

function hex_to_char(val) {
    if(val.match(/[^0-9A-Fa-f]/)) { val = val.replace(/[^0-9A-Fa-f]/g, ""); }
    if(val.length % 2 != 0) { val = "0" + val; }

    var ascii = "";
    for(var i = 0; i < val.length; i += 2) {
        ascii += String.fromCharCode(parseInt(val.substr(i, 2), 16));
    }
    return ascii;
}

function hex_to_bin(val) {
    if(val.match(/[^0-9A-Fa-f]/)) { val = val.replace(/[^0-9A-Fa-f]/g, ""); }
    if(val.length % 2 != 0) { val = "0" + val; }

    var bin = "";
    for(var i = 0; i < val.length; ++i) {
        bin += hex_char_to_bin(val.charAt(i));
    }
    return bin;
}

function bin_to_char(val) {
    if(val.match(/[^01]/)) { val = val.replace(/[^01]/g, ""); }
    var diff = val.length % 8;
    if(diff != 0) {
        var len = 8 - diff;
        for(var i = 0; i < len; ++i) { val = "0" + val; }
    }

    var ascii = "";
    for(var i = 0; i < val.length; i += 8) {
        ascii += String.fromCharCode(parseInt(val.substr(i, 8), 2));
    }
    return ascii;
}

function bin_to_hex(val) {
    if(val.match(/[^01]/)) { val = val.replace(/[^01]/g, ""); }
    var diff = val.length % 8;
    if(diff != 0) {
        var len = 8 - diff;
        for(var i = 0; i < len; ++i) { val = "0" + val; }
    }

    var hexStr = "0123456789ABCDEF";
    var hex = "";
    for(var i = 0; i < val.length; i += 4) {
        hex += hexStr.charAt(parseInt(val.substr(i, 4), 2));
    }
    return hex;
}


function hex_char_to_bin(val) {
    switch(val) {
        case "0" : return "0000";
        case "1" : return "0001";
        case "2" : return "0010";
        case "3" : return "0011";
        case "4" : return "0100";
        case "5" : return "0101";
        case "6" : return "0110";
        case "7" : return "0111";
        case "8" : return "1000";
        case "9" : return "1001";
        case "A" : return "1010";
        case "B" : return "1011";
        case "C" : return "1100";
        case "D" : return "1101";
        case "E" : return "1110";
        case "F" : return "1111";
        default  : return "0000";
    }
}

function color(a, h, b) {
    if(a) { document.getElementById("ascii").style.backgroundColor = "#FFFF99"; }
    else  { document.getElementById("ascii").style.backgroundColor = "#FFFFFF"; }

    if(h) { document.getElementById("hex").style.backgroundColor = "#FFFF99"; }
    else  { document.getElementById("hex").style.backgroundColor = "#FFFFFF"; }

    if(b) { document.getElementById("bin").style.backgroundColor = "#FFFF99"; }
    else  { document.getElementById("bin").style.backgroundColor = "#FFFFFF"; }
}



function rotConvert(rotArg, rotStr) {
    var el = document.getElementById("rot");
    var rotX = Math.abs((rotArg === undefined) ? parseInt(document.getElementById("rotX").value) : rotArg);
    if(rotX == 47) { rot47(el.value); return; }
    if(rotX >= 26) { rotX %= 26; }
    if(!rotX) { return; }

    var val = ((rotStr === undefined) ? el.value : rotStr);
    var rotVal = "";
    for(var i = 0; i < val.length; ++i) {
        var charCode = val.charCodeAt(i);
        if(charCode > 64 && charCode < 91) {
            charCode = (charCode - 65 + rotX) % 26 + 65;
            rotVal += String.fromCharCode(charCode);
        }
        else if(charCode > 96 && charCode < 123) {
            charCode = (charCode - 97 + rotX) % 26 + 97;
            rotVal += String.fromCharCode(charCode);
        }
        else { rotVal += val.charAt(i); }
    }
    if(rotArg === undefined) { el.value = rotVal; }
    else { el.value += "\r\n" + rotVal; }
}

function rot47(val, nl) {
    var rot = "";
    for(var i = 0; i < val.length; ++i) {
        var charCode = val.charCodeAt(i);
        if(charCode > 32 && charCode < 127) {
            charCode = (charCode - 33 + 47) % 94 + 33;
            rot += String.fromCharCode(charCode);
        }
        else { rot += val.charAt(i); }
    }
    if(nl) { document.getElementById("rot").value += "\r\n" + rot; }
    else { document.getElementById("rot").value = rot; }
}

function rotAll() {
    var val = document.getElementById("rot").value;
    for(var i = 1; i < 26; ++i) { rotConvert(i, val); }
    rot47(val, true);
}