// Joseph Colton
// CIS 510 - Cryptography
// Final Project - Encryption/Decryption Program

// Global Variables
var AJAX_UNINITIALIZED = 0;
var AJAX_LOADING       = 1;
var AJAX_LOADED        = 2;
var AJAX_INTERACTIVE   = 3;
var AJAX_COMPLETE      = 4;

var DEFAULT_WIDTH      = 800;
var DEFAULT_HEIGHT     = 800;
var navTabs = null;
var navTabIDs = new Array();

var baseURL = "decrypt.cgi";

function Element(elementId) {
    return document.getElementById(elementId);
}

function Exists(elementId) {
    var ref = Element(elementId);
    if (ref == null) {
	return false;
    }
    return true;
}

function Disable(elementId) {
    // Determine the element type, then disable it
    if (Exists(elementId)) {
	var elementType = Element(elementId).type;
	switch(elementType) {
	case 'button':
	case 'checkbox':
	case 'file':
	case 'radio':
	case 'submit':
	    Element(elementId).disabled = true;
	    break;    
	case 'password':
	case 'text':
	    Element(elementId).readOnly = true;
	    break;
	}
    }
}

function Enable(elementId) {
    // Determine the element type, then disable it
    if (Exists(elementId)) {
	var elementType = Element(elementId).type;
	switch(elementType) {
	case 'button':
	case 'checkbox':
	case 'file':
	case 'radio':
	case 'submit':
	    Element(elementId).disabled = false;
	    break;    
	case 'password':
	case 'text':
	    Element(elementId).readOnly = false;
	    break;
	}
    }
}

function getWindowWidth() {
    if (parseInt(navigator.appVersion)>3) {
	if (navigator.appName=="Netscape") {
	    return window.innerWidth;
	}
	if (navigator.appName.indexOf("Microsoft")!=-1) {
	    return document.body.offsetWidth;
	}
    }
    return DEFAULT_WIDTH;
}

function getWindowHeight() {
    if (parseInt(navigator.appVersion)>3) {
	if (navigator.appName=="Netscape") {
	    return window.innerHeight;
	}
	if (navigator.appName.indexOf("Microsoft")!=-1) {
	    return document.body.offsetHeight;
	}
    }
    return DEFAULT_HEIGHT;
}

function requestDataExec(requestURL, targetID, postVars, execScript) {
    if (typeof(postVars) == 'undefined') {
        postVars = '';
    }

    // Start by creating a request
    var request;
    if (window.ActiveXObject) {
        // IE
        request = new ActiveXObject("Microsoft.XMLHTTP");
    } else if (window.XMLHttpRequest) {
        // Mozilla, Firefix, Safari, etc.
        request = new XMLHttpRequest();
        request.overrideMimeType('text/xml');
    }

    // Once we get the request, we want to process it
    request.onreadystatechange = function() {
        if (request.readyState == AJAX_COMPLETE) {
            var data = request.responseText;
            // Put the output in a nice place if it exists
            if (Exists(targetID)) {
                Element(targetID).innerHTML = data;
            }
            // Execute code if any was passed in
            if (execScript) {
                setTimeout(execScript, 500);
            }
        }
    }

    // Actually make the request
    request.open('POST', requestURL, true);
    request.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
    request.setRequestHeader("Content-length", postVars.length);
    request.setRequestHeader("Connection", "close");
    request.send(postVars);
}

function cleanUpper(phrase) {
    valA = 65;
    valZ = 90;

    phrase = phrase.toUpperCase();
    newPhrase = "";

    for (i=0; i < phrase.length; i++) {
	ch = phrase[i];
	chVal = ch.charCodeAt();
	if (chVal >= 65 && chVal <= valZ) {
	    newPhrase+=ch;
	}
    }
    return newPhrase;
}

// Caesar Cipher variables and functions
function caesarGuess() {
    sourceText = Element("caesarsource").innerHTML;
    if (sourceText == "") {
	alert("Source text is currently blank.  Go to the text tab and save or select some text.");
    } else {
	freqList = Element("langfreqA").value + " ";
	freqList += Element("langfreqB").value + " ";
	freqList += Element("langfreqC").value + " ";
	freqList += Element("langfreqD").value + " ";
	freqList += Element("langfreqE").value + " ";
	freqList += Element("langfreqF").value + " ";
	freqList += Element("langfreqG").value + " ";
	freqList += Element("langfreqH").value + " ";
	freqList += Element("langfreqI").value + " ";
	freqList += Element("langfreqJ").value + " ";
	freqList += Element("langfreqK").value + " ";
	freqList += Element("langfreqL").value + " ";
	freqList += Element("langfreqM").value + " ";
	freqList += Element("langfreqN").value + " ";
	freqList += Element("langfreqO").value + " ";
	freqList += Element("langfreqP").value + " ";
	freqList += Element("langfreqQ").value + " ";
	freqList += Element("langfreqR").value + " ";
	freqList += Element("langfreqS").value + " ";
	freqList += Element("langfreqT").value + " ";
	freqList += Element("langfreqU").value + " ";
	freqList += Element("langfreqV").value + " ";
	freqList += Element("langfreqW").value + " ";
	freqList += Element("langfreqX").value + " ";
	freqList += Element("langfreqY").value + " ";
	freqList += Element("langfreqZ").value;

	// Encode text for transmit
	encSourceText = encodeURIComponent(sourceText);
	encFreqList = encodeURIComponent(freqList);

	// Create variables list
	postVars = "sourceText=" + encSourceText;
	postVars += "&freqList=" + encFreqList;

	// Get the rest of the variables
	requestURL = baseURL + "?s=caesarguess";
	execScript = "caesarGuessResponse();";
	requestDataExec(requestURL, "ajaxreply", postVars, execScript);
    }

}

function caesarGuessResponse() {
    guessText = Element("ajaxreply").innerHTML;
    guess = parseInt(guessText);
    Element("caesarshift").value = guess;
    alert("Guessing Caesar Shift of " + guess);
}

function caesarEncrypt() {
    sourceText = Element("caesarsource").innerHTML;
    shift = parseInt(Element("caesarshift").value);
    if (sourceText == "") {
	alert("Source text is currently blank.  Go to the text tab and save or select some text.");
    } else {
	sourceText = sourceText.toUpperCase();
	targetText = "";
	for(i=0; i < sourceText.length; i++) {
	    ch = sourceText[i];
	    newCh = caesarLetterShift(ch, shift);
	    targetText += newCh;
	}
	Element("caesartarget").innerHTML = targetText;
    }
}

function caesarDecrypt() {
    sourceText = Element("caesarsource").innerHTML;
    shift = parseInt(Element("caesarshift").value);
    shift = 26 - shift;
    if (sourceText == "") {
	alert("Source text is currently blank.  Go to the text tab and save or select some text.");
    } else {
	sourceText = sourceText.toUpperCase();
	targetText = "";
	for(i=0; i < sourceText.length; i++) {
	    ch = sourceText[i];
	    newCh = caesarLetterShift(ch, shift);
	    targetText += newCh;
	}
	Element("caesartarget").innerHTML = targetText;
    }
}

function caesarLetterShift(letter, shift) {
    valA = 65;
    valZ = 90;
    letter = letter.toUpperCase();

    if (shift == 0) {
	// We only shift when there is a shift
	return letter;
    } else {
	letterValue = letter.charCodeAt();
	if (letterValue >= 65 && letterValue <= valZ) {
	    letterValue -= valA;
	    letterValue += shift;
	    letterValue = letterValue % 26;
	    letterValue += valA;
	    return String.fromCharCode(letterValue);
	} else {
	    // Do not translate letters out of range.
	    return letter;
	}
    }
}

function caesarSave() {
    targetValue = Element("caesartarget").innerHTML;
    if (targetValue == "") {
	alert("There is no target value to save");
    } else {
	// Create new entry
	textSelectElem = Element("textselect");
	var newEntryText = 'Text' + textNextIndex++;
	var newEntry = document.createElement('option');
	newEntry.text=newEntryText
	try {
	    textSelectElem.add(newEntry,null); // Standards compliant
	} catch(ex) {
	    textSelectElem.add(newEntry); // IE only
	}
	// Save the value
	textData[newEntryText] = targetValue;
	// Switch to the newEntry
	textSelectElem.selectedIndex = textSelectElem.length - 1;
	textSelect();
    }
}

// Playfair Cipher Variables/Functions
function playfairGenerate() {
    valA = 65;
    valZ = 90;
    alphabetAll = "ABCDEFGHIKLMNOPQRSTUVWXYZ";
    var alphabet = new Array();
    keyword = Element("playfairkeyword").value;
    // Make sure we have something to work with.
    if (keyword == "") {
	alert("You must set the keyword");
	return;
    }

    // Update keyword
    keyword = keyword.toUpperCase();
    keyword = keyword.replace(/J/g,"I");
    newkeyword = "";
    for (i=0; i < keyword.length; i++) {
	ch = keyword[i];
	chVal = ch.charCodeAt();
	if (ch == alphabet[ch]) continue;
	if (chVal >= valA && chVal <= valZ) {
	    alphabet[ch] = ch;
	    newkeyword+=ch;
	}
    }
    keyword = newkeyword;
    Element("playfairkeyword").value = keyword;

    // Fill in matrix
    nextIndex = 0;
    for (i=0; i < keyword.length; i++) {
	row = parseInt(i / 5) + 1;
	col = (i % 5) + 1;
	id = "playfair" + row + "x" + col;
	Element(id).value = keyword[i];
	nextIndex = i;
    }
    nextIndex++;
    for (i=0; i < alphabetAll.length; i++) {
	// Determine unused letters
	ch = alphabetAll[i];
	if (alphabet[ch] != ch) {
	    // Use this character
	    alphabet[ch] = ch;
	    row = parseInt(nextIndex / 5) + 1;
	    col = (nextIndex % 5) + 1;
	    id = "playfair" + row + "x" + col;
	    Element(id).value = ch;
	    nextIndex++;
	}
    }
}

function playfairEncrypt() {
    valA = 65;
    valZ = 90;
    var lookupRow = new Array();
    var lookupCol = new Array();
    var lookup = new Array();
    sourceText = Element("playfairsource").innerHTML;
    if (sourceText == "") {
	alert("Source text is currently blank.  Go to the text tab and save or select some text.");
	return;
    }

    // Prepare sourceText
    sourceText = sourceText.toUpperCase();
    sourceText = sourceText.replace(/J/g,"I");
    newSourceText = "";
    pCh = "";
    for(i=0; i < sourceText.length; i++) {
	ch = sourceText[i];
	chVal = ch.charCodeAt();
	if (chVal >= valA && chVal <= valZ) {
	    if (pCh == ch && newSourceText.length % 2 == 1) {
		newSourceText+='X';
	    }
	    newSourceText+=ch;
	    pCh = ch;
	}
    }
    if (newSourceText.length % 2 != 0) {
	newSourceText += "X";
    }
    sourceText = newSourceText;

    // Read in matrix
    for (i=0; i < 25; i++) {
	row = parseInt(i / 5) + 1;
	col = (i % 5) + 1;
	id = "playfair" + row + "x" + col;
	letter = Element(id).value;
	if (letter == "") {
	    alert("Missing value in matrix at row="+row+" column="+col);
	    return;
	}
	lookupRow[letter] = row;
	lookupCol[letter] = col;
	lookup[row+"x"+col] = letter;
    }

    // Examine pairs of 2
    targetText = "";
    for(i=0; i < sourceText.length; i+=2) {
	ch1 = sourceText[i];
	ch2 = sourceText[i+1];
	ch1col = lookupCol[ch1];
	ch1row = lookupRow[ch1];
	ch2col = lookupCol[ch2];
	ch2row = lookupRow[ch2];

	// See if they are in different columns and rows
	if (ch1col != ch2col && ch1row != ch2row) {
	    // First character
	    targetText+=lookup[ch1row+"x"+ch2col];
	    // Second character
	    targetText+=lookup[ch2row+"x"+ch1col];
	    // Add space
	    targetText+=" ";
	    continue;
	}

	// See if they are in the same row, might be both X
	if (ch1row == ch2row) {
	    // First character
	    newCol = (ch1col % 5) + 1;
	    targetText+=lookup[ch1row+"x"+newCol];
	    // Second character
	    newCol = (ch2col % 5) + 1;
	    targetText+=lookup[ch2row+"x"+newCol];
	    // Add space
	    targetText+=" ";
	    continue;
	}

	// See if they are in the same column
	if (ch1col == ch2col) {
	    // First character
	    newRow = (ch1row % 5) + 1;
	    targetText+=lookup[newRow+"x"+ch1col];
	    // Second character
	    newRow = (ch2row % 5) + 1;
	    targetText+=lookup[newRow+"x"+ch2col];
	    // Add space
	    targetText+=" ";
	    continue;
	}
    }

    Element("playfairtarget").innerHTML = targetText;
}

function playfairDecrypt() {
    valA = 65;
    valZ = 90;
    var lookupRow = new Array();
    var lookupCol = new Array();
    var lookup = new Array();
    sourceText = Element("playfairsource").innerHTML;
    if (sourceText == "") {
	alert("Source text is currently blank.  Go to the text tab and save or select some text.");
	return;
    }

    // Prepare sourceText
    sourceText = sourceText.toUpperCase();
    sourceText = sourceText.replace(/J/g,"I");
    newSourceText = "";
    for(i=0; i < sourceText.length; i++) {
	ch = sourceText[i];
	chVal = ch.charCodeAt();
	if (chVal >= valA && chVal <= valZ) {
	    newSourceText+=ch;
	}
    }
    if (newSourceText.length % 2 != 0) {
	alert("Cannot be Playfair: length is not even");
	return;
    }
    sourceText = newSourceText;

    // Read in matrix
    for (i=0; i < 25; i++) {
	row = parseInt(i / 5) + 1;
	col = (i % 5) + 1;
	id = "playfair" + row + "x" + col;
	letter = Element(id).value;
	if (letter == "") {
	    alert("Missing value in matrix at row="+row+" column="+col);
	    return;
	}
	lookupRow[letter] = row;
	lookupCol[letter] = col;
	lookup[row+"x"+col] = letter;
    }

    // Examine pairs of 2
    targetText = "";
    for(i=0; i < sourceText.length; i+=2) {
	ch1 = sourceText[i];
	ch2 = sourceText[i+1];
	ch1col = lookupCol[ch1];
	ch1row = lookupRow[ch1];
	ch2col = lookupCol[ch2];
	ch2row = lookupRow[ch2];

	// See if they are in different columns and rows
	if (ch1col != ch2col && ch1row != ch2row) {
	    // First character
	    targetText+=lookup[ch1row+"x"+ch2col];
	    // Second character
	    targetText+=lookup[ch2row+"x"+ch1col];
	    // Add space
	    targetText+=" ";
	    continue;
	}

	// See if they are in the same row, might be both X
	if (ch1row == ch2row) {
	    // First character
	    newCol = ((ch1col + 3) % 5) + 1;
	    targetText+=lookup[ch1row+"x"+newCol];
	    // Second character
	    newCol = ((ch2col + 3) % 5) + 1;
	    targetText+=lookup[ch2row+"x"+newCol];
	    // Add space
	    targetText+=" ";
	    continue;
	}

	// See if they are in the same column
	if (ch1col == ch2col) {
	    // First character
	    newRow = ((ch1row + 3) % 5) + 1;
	    targetText+=lookup[newRow+"x"+ch1col];
	    // Second character
	    newRow = ((ch2row + 3) % 5) + 1;
	    targetText+=lookup[newRow+"x"+ch2col];
	    // Add space
	    targetText+=" ";
	    continue;
	}
    }

    Element("playfairtarget").innerHTML = targetText;
}

function playfairSave() {
    targetValue = Element("playfairtarget").innerHTML;
    if (targetValue == "") {
	alert("There is no target value to save");
    } else {
	// Create new entry
	textSelectElem = Element("textselect");
	var newEntryText = 'Text' + textNextIndex++;
	var newEntry = document.createElement('option');
	newEntry.text=newEntryText
	try {
	    textSelectElem.add(newEntry,null); // Standards compliant
	} catch(ex) {
	    textSelectElem.add(newEntry); // IE only
	}
	// Save the value
	textData[newEntryText] = targetValue;
	// Switch to the newEntry
	textSelectElem.selectedIndex = textSelectElem.length - 1;
	textSelect();
    }
}

// ADFGX Cipher Variables/Functions
function adfgxLookup(index) {
    switch(index) {
    case 1: return 'A';
    case 2: return 'D';
    case 3: return 'F';
    case 4: return 'G';
    case 5: return 'X';
    default: return 'X';
    }
    return 'X';
}

function adfgxEncrypt() {
    valA = 65;
    valZ = 90;
    var lookup = new Array();
    sourceText = Element("adfgxsource").innerHTML;
    adfgxKeyword = Element("adfgxkeyword").value;
    adfgxKeyword = cleanUpper(adfgxKeyword);
    if (sourceText == "") {
	alert("Source text is currently blank.  Go to the text tab and save or select some text.");
	return;
    }
    if (adfgxKeyword == "") {
	alert("ADFGX Keyword Missing");
	return;
    }
    // Update keyword
    Element("adfgxkeyword").value = adfgxKeyword;

    // Prepare sourceText
    sourceText = sourceText.toUpperCase();
    sourceText = sourceText.replace(/J/g,"I");
    newSourceText = "";
    for(i=0; i < sourceText.length; i++) {
	ch = sourceText[i];
	chVal = ch.charCodeAt();
	if (chVal >= valA && chVal <= valZ) {
	    newSourceText+=ch;
	}
    }
    sourceText = newSourceText;

    // Read in matrix
    for (i=0; i < 25; i++) {
	row = parseInt(i / 5) + 1;
	col = (i % 5) + 1;
	id = "adfgx" + row + "x" + col;
	letter = Element(id).value;
	if (letter == "") {
	    alert("Missing value in matrix at row="+row+" column="+col);
	    return;
	}

	is1 = adfgxLookup(row);
	is2 = adfgxLookup(col);
	lookup[letter] = is1+is2;
    }

    // Initial Step
    stepTextDisplay = "";
    stepText = "";
    for(i=0; i < sourceText.length; i++) {
	// For display on page
	stepTextDisplay += lookup[sourceText[i]];
	stepTextDisplay += " ";
	// For further processing
	stepText += lookup[sourceText[i]];
    }
    Element("adfgxstep").innerHTML = stepTextDisplay;

    // Target Step
    targetText = "";
    var colLetters = new Array();
    var colNextIndex = new Array();
    var colCodes = new Array();
    cols = adfgxKeyword.length;
    for (i=0; i < cols; i++) {
	ch = adfgxKeyword[i];
	colKey = ch + i;
	colLetters[colKey] = "";
	// Gather all of the letters from this column
	for(j=0; j < stepText.length; j++) {
	    if (j % cols == i) {
		colLetters[colKey]+=stepText[j];
	    }
	}
	// Add the colKey to the array of column codes
	colCodes[i] = colKey;
	colNextIndex[i] = 0;
    }
    // Sort the column keys
    colCodes.sort();
    // Create the mixed targetText sentence
    targetLetter = 0;
    for(i=0; i < stepText.length + cols; i++) {
	// Determine the column to look in
	sIndex = i % cols;
	// Determine the index of the character to look at
	cIndex = colNextIndex[sIndex];
	if (cIndex < colLetters[colCodes[sIndex]].length) {
	    colLine = colLetters[colCodes[sIndex]];
	    targetText += colLine[cIndex];
	    targetLetter++;
	    if (targetLetter % 5 == 0) {
		targetText += " ";
	    }
	    colNextIndex[sIndex]++;
	}
    }
    Element("adfgxtarget").innerHTML = targetText;
}

function adfgxDecrypt() {
    var lookup = new Array();
    sourceText = Element("adfgxsource").innerHTML;
    sourceText = cleanUpper(sourceText);
    adfgxKeyword = Element("adfgxkeyword").value;
    adfgxKeyword = cleanUpper(adfgxKeyword);
    if (sourceText == "") {
	alert("Source text is currently blank.  Go to the text tab and save or select some text.");
	return;
    }
    if (adfgxKeyword == "") {
	alert("ADFGX Keyword Missing");
	return;
    }
    // Update keyword
    Element("adfgxkeyword").value = adfgxKeyword;

    // Read in matrix
    for (i=0; i < 25; i++) {
	row = parseInt(i / 5) + 1;
	col = (i % 5) + 1;
	id = "adfgx" + row + "x" + col;
	letter = Element(id).value;
	if (letter == "") {
	    alert("Missing value in matrix at row="+row+" column="+col);
	    return;
	}

	is1 = adfgxLookup(row);
	is2 = adfgxLookup(col);
	lookup[is1+is2] = letter;
    }

    // Reverse to Initial Decrypt Step
    stepText = "";
    var colLetters = new Array();
    var colCodes = new Array();
    var colCodesUnsorted = new Array();
    cols = adfgxKeyword.length;
    for (i=0; i < cols; i++) {
	ch = adfgxKeyword[i];
	colKey = ch + i;
	colLetters[colKey] = "";
	// Gather all of the letters from this column
	for(j=0; j < stepText.length; j++) {
	    if (j % cols == i) {
		colLetters[colKey]+=stepText[j];
	    }
	}
	// Add the colKey to the array of column codes
	colCodes[i] = colKey;
	colCodesUnsorted[i] = colKey;
    }
    // Sort the column keys
    colCodes.sort();
    // Create the columns
    for(i=0; i < sourceText.length; i++) {
	sIndex = i % cols;
	colKey = colCodes[sIndex];
	colLetters[colKey]+=sourceText[i];
    }
    // Use unsorted list to get the original text.
    // Note: the last few letters might be still mixed.
    stepText = "";
    stepTextDisplay = "";
    stepLetter = 0;
    Element("adfgxstep").innerHTML = stepText;
    for(i=0; i < sourceText.length + cols; i++) {
	// Determine the column to look in
	sIndex = i % cols;
	// Determine the index of the character to look at
	cIndex = parseInt(i / cols);
	if (cIndex < colLetters[colCodesUnsorted[sIndex]].length) {
	    colLine = colLetters[colCodesUnsorted[sIndex]];
	    stepText += colLine[cIndex];
	    stepTextDisplay += colLine[cIndex];
	    stepLetter++;
	    if (stepLetter % 2 == 0) {
		stepTextDisplay += ' ';
	    }
	    Element("adfgxstep").innerHTML = stepTextDisplay;
	}
    }

    // From initial step, convert to letters in matrix;
    targetText = "";
    targetLetter = 0;
    for(i=0; i < stepText.length; i+=2) {
	rCh = stepText[i];
	cCh = stepText[i+1];
	targetText += lookup[rCh+cCh];
	targetLetter++;
	if (targetLetter % 5 == 0) {
	    targetText += " ";
	}
    }
    Element("adfgxtarget").innerHTML = targetText;

}

function adfgxSave() {
    targetValue = Element("adfgxtarget").innerHTML;
    if (targetValue == "") {
	alert("There is no target value to save");
    } else {
	// Create new entry
	textSelectElem = Element("textselect");
	var newEntryText = 'Text' + textNextIndex++;
	var newEntry = document.createElement('option');
	newEntry.text=newEntryText
	try {
	    textSelectElem.add(newEntry,null); // Standards compliant
	} catch(ex) {
	    textSelectElem.add(newEntry); // IE only
	}
	// Save the value
	textData[newEntryText] = targetValue;
	// Switch to the newEntry
	textSelectElem.selectedIndex = textSelectElem.length - 1;
	textSelect();
    }
}


// Vigenere Cipher Variables/Functions
function vigenereGuess() {
    sourceText = Element("vigeneresource").innerHTML;
    if (sourceText == "") {
	alert("Source text is currently blank.  Go to the text tab and save or select some text.");
    } else {
	freqList = Element("langfreqA").value + " ";
	freqList += Element("langfreqB").value + " ";
	freqList += Element("langfreqC").value + " ";
	freqList += Element("langfreqD").value + " ";
	freqList += Element("langfreqE").value + " ";
	freqList += Element("langfreqF").value + " ";
	freqList += Element("langfreqG").value + " ";
	freqList += Element("langfreqH").value + " ";
	freqList += Element("langfreqI").value + " ";
	freqList += Element("langfreqJ").value + " ";
	freqList += Element("langfreqK").value + " ";
	freqList += Element("langfreqL").value + " ";
	freqList += Element("langfreqM").value + " ";
	freqList += Element("langfreqN").value + " ";
	freqList += Element("langfreqO").value + " ";
	freqList += Element("langfreqP").value + " ";
	freqList += Element("langfreqQ").value + " ";
	freqList += Element("langfreqR").value + " ";
	freqList += Element("langfreqS").value + " ";
	freqList += Element("langfreqT").value + " ";
	freqList += Element("langfreqU").value + " ";
	freqList += Element("langfreqV").value + " ";
	freqList += Element("langfreqW").value + " ";
	freqList += Element("langfreqX").value + " ";
	freqList += Element("langfreqY").value + " ";
	freqList += Element("langfreqZ").value;

	// Encode text for transmit
	encSourceText = encodeURIComponent(sourceText);
	encFreqList = encodeURIComponent(freqList);

	// Create variables list
	postVars = "sourceText=" + encSourceText;
	postVars += "&freqList=" + encFreqList;

	// Get the rest of the variables
	requestURL = baseURL + "?s=vigenereguess";
	execScript = "vigenereGuessResponse();";
	requestDataExec(requestURL, "ajaxreply", postVars, execScript);
    }

}

function vigenereKeyGuess() {
    sourceText = Element("vigeneresource").innerHTML;
    period = Element("vigenereperiod").value;
    if (sourceText == "") {
	alert("Source text is currently blank.  Go to the text tab and save or select some text.");
    } else {
	freqList = Element("langfreqA").value + " ";
	freqList += Element("langfreqB").value + " ";
	freqList += Element("langfreqC").value + " ";
	freqList += Element("langfreqD").value + " ";
	freqList += Element("langfreqE").value + " ";
	freqList += Element("langfreqF").value + " ";
	freqList += Element("langfreqG").value + " ";
	freqList += Element("langfreqH").value + " ";
	freqList += Element("langfreqI").value + " ";
	freqList += Element("langfreqJ").value + " ";
	freqList += Element("langfreqK").value + " ";
	freqList += Element("langfreqL").value + " ";
	freqList += Element("langfreqM").value + " ";
	freqList += Element("langfreqN").value + " ";
	freqList += Element("langfreqO").value + " ";
	freqList += Element("langfreqP").value + " ";
	freqList += Element("langfreqQ").value + " ";
	freqList += Element("langfreqR").value + " ";
	freqList += Element("langfreqS").value + " ";
	freqList += Element("langfreqT").value + " ";
	freqList += Element("langfreqU").value + " ";
	freqList += Element("langfreqV").value + " ";
	freqList += Element("langfreqW").value + " ";
	freqList += Element("langfreqX").value + " ";
	freqList += Element("langfreqY").value + " ";
	freqList += Element("langfreqZ").value;

	// Encode text for transmit
	encSourceText = encodeURIComponent(sourceText);
	encFreqList = encodeURIComponent(freqList);
	encPeriod = encodeURIComponent(period);

	// Create variables list
	postVars = "sourceText=" + encSourceText;
	postVars += "&freqList=" + encFreqList;
	postVars += "&period=" + encPeriod;

	// Get the rest of the variables
	requestURL = baseURL + "?s=vigenerekeyguess";
	execScript = "vigenereKeyGuessResponse();";
	requestDataExec(requestURL, "ajaxreply", postVars, execScript);
    }

}

function vigenereGuessResponse() {
    guessText = Element("ajaxreply").innerHTML;
    guess = parseInt(guessText);
    Element("vigenereperiod").value = guess;
    alert("Guessing Vigenere Period of " + guess);
}

function vigenereKeyGuessResponse() {
    guessText = Element("ajaxreply").innerHTML;
    Element("vigenerekeyword").value = guessText;
    alert("Guessing Vigenere Keyword of " + guessText);
}


function vigenereEncrypt() {
    sourceText = Element("vigeneresource").innerHTML;
    vigenereKey = Element("vigenerekeyword").value;
    vigenereKey = vigenereKey.toUpperCase();
    period = vigenereKey.length;
    valA = 65;
    valZ = 90;

    // Make sure we have what we need for encryption
    if (sourceText == "") {
	alert("Source text is currently blank.  Go to the text tab and save or select some text.");
	return;
    }
    if (period <= 1) {
	// A length of 1 indicates a standard Caesar Shift Cipher
	alert("Vigenere Keyword is too short");
	return;
    }

    sourceText = sourceText.toUpperCase();
    targetText = "";
    encIndex = 0;
    for(i=0; i < sourceText.length; i++) {
	ch = sourceText[i];
	letterValue = ch.charCodeAt();
	if (letterValue >= valA && letterValue <= valZ) {
	    shift = vigenereKey.charCodeAt(encIndex) - valA;
	    newCh = caesarLetterShift(ch, shift);
	    encIndex = (encIndex + 1) % period;
	} else {
	    // Preserve non-alpha.
	    newCh = ch;
	}
	targetText += newCh;
    }
    Element("vigeneretarget").innerHTML = targetText;
}

function vigenereDecrypt() {
    sourceText = Element("vigeneresource").innerHTML;
    vigenereKey = Element("vigenerekeyword").value;
    vigenereKey = vigenereKey.toUpperCase();
    period = vigenereKey.length;
    valA = 65;
    valZ = 90;

    // Make sure we have what we need for encryption
    if (sourceText == "") {
	alert("Source text is currently blank.  Go to the text tab and save or select some text.");
	return;
    }
    if (period <= 1) {
	// A length of 1 indicates a standard Caesar Shift Cipher
	alert("Vigenere Keyword is too short");
	return;
    }

    sourceText = sourceText.toUpperCase();
    targetText = "";
    encIndex = 0;
    for(i=0; i < sourceText.length; i++) {
	ch = sourceText[i];
	letterValue = ch.charCodeAt();
	if (letterValue >= valA && letterValue <= valZ) {
	    shift = (26 - (vigenereKey.charCodeAt(encIndex) - valA)) % 26;
	    newCh = caesarLetterShift(ch, shift);
	    encIndex = (encIndex + 1) % period;
	} else {
	    // Preserve non-alpha.
	    newCh = ch;
	}
	targetText += newCh;
    }
    Element("vigeneretarget").innerHTML = targetText;
}

function vigenereSave() {
    targetValue = Element("vigeneretarget").innerHTML;
    if (targetValue == "") {
	alert("There is no target value to save");
    } else {
	// Create new entry
	textSelectElem = Element("textselect");
	var newEntryText = 'Text' + textNextIndex++;
	var newEntry = document.createElement('option');
	newEntry.text=newEntryText
	try {
	    textSelectElem.add(newEntry,null); // Standards compliant
	} catch(ex) {
	    textSelectElem.add(newEntry); // IE only
	}
	// Save the value
	textData[newEntryText] = targetValue;
	// Switch to the newEntry
	textSelectElem.selectedIndex = textSelectElem.length - 1;
	textSelect();
    }
}


// Letter Substitutions
function subSub() {
    sourceText = Element("subsource").innerHTML;
    if (sourceText == "") {
	alert("Source text is currently blank.  Go to the text tab and save or select some text.");
    } else {
	sourceText = sourceText.toUpperCase();
	targetText = "";
	for(i=0; i < sourceText.length; i++) {
	    ch = sourceText[i];
	    newCh = subLetter(ch);
	    targetText += newCh;
	}
	Element("subtarget").innerHTML = targetText;
    }
}

function subLetter(letter) {
    switch(letter) {
    case 'A': return Element("subA").value;
    case 'B': return Element("subB").value;
    case 'C': return Element("subC").value;
    case 'D': return Element("subD").value;
    case 'E': return Element("subE").value;
    case 'F': return Element("subF").value;
    case 'G': return Element("subG").value;
    case 'H': return Element("subH").value;
    case 'I': return Element("subI").value;
    case 'J': return Element("subJ").value;
    case 'K': return Element("subK").value;
    case 'L': return Element("subL").value;
    case 'M': return Element("subM").value;
    case 'N': return Element("subN").value;
    case 'O': return Element("subO").value;
    case 'P': return Element("subP").value;
    case 'Q': return Element("subQ").value;
    case 'R': return Element("subR").value;
    case 'S': return Element("subS").value;
    case 'T': return Element("subT").value;
    case 'U': return Element("subU").value;
    case 'V': return Element("subV").value;
    case 'W': return Element("subW").value;
    case 'X': return Element("subX").value;
    case 'Y': return Element("subY").value;
    case 'Z': return Element("subZ").value;
    case ' ': return Element("subSPACE").value;
    default: return letter;
    }
    return letter;
}

function subGuess() {
    sourceText = Element("subsource").innerHTML;
    if (sourceText == "") {
	alert("Source text is currently blank.  Go to the text tab and save or select some text.");
    } else {
	freqList = Element("langfreqA").value + " ";
	freqList += Element("langfreqB").value + " ";
	freqList += Element("langfreqC").value + " ";
	freqList += Element("langfreqD").value + " ";
	freqList += Element("langfreqE").value + " ";
	freqList += Element("langfreqF").value + " ";
	freqList += Element("langfreqG").value + " ";
	freqList += Element("langfreqH").value + " ";
	freqList += Element("langfreqI").value + " ";
	freqList += Element("langfreqJ").value + " ";
	freqList += Element("langfreqK").value + " ";
	freqList += Element("langfreqL").value + " ";
	freqList += Element("langfreqM").value + " ";
	freqList += Element("langfreqN").value + " ";
	freqList += Element("langfreqO").value + " ";
	freqList += Element("langfreqP").value + " ";
	freqList += Element("langfreqQ").value + " ";
	freqList += Element("langfreqR").value + " ";
	freqList += Element("langfreqS").value + " ";
	freqList += Element("langfreqT").value + " ";
	freqList += Element("langfreqU").value + " ";
	freqList += Element("langfreqV").value + " ";
	freqList += Element("langfreqW").value + " ";
	freqList += Element("langfreqX").value + " ";
	freqList += Element("langfreqY").value + " ";
	freqList += Element("langfreqZ").value;

	// Encode text for transmit
	encSourceText = encodeURIComponent(sourceText);
	encFreqList = encodeURIComponent(freqList);

	// Create variables list
	postVars = "sourceText=" + encSourceText;
	postVars += "&freqList=" + encFreqList;

	// Get the rest of the variables
	requestURL = baseURL + "?s=subguess";
	execScript = "subGuessResponse();";
	requestDataExec(requestURL, "ajaxreply", postVars, execScript);
    }
}

function subGuessResponse() {
    guessText = Element("ajaxreply").innerHTML;
    for(i=0; i < 26; i++) {
	chVal = 65 + i;
	ch = String.fromCharCode(chVal);
	id = "sub"+ch;
	Element(id).value = guessText[i];
    }
}

function subSave() {
    targetValue = Element("subtarget").innerHTML;
    if (targetValue == "") {
	alert("There is no target value to save");
    } else {
	// Create new entry
	textSelectElem = Element("textselect");
	var newEntryText = 'Text' + textNextIndex++;
	var newEntry = document.createElement('option');
	newEntry.text=newEntryText
	try {
	    textSelectElem.add(newEntry,null); // Standards compliant
	} catch(ex) {
	    textSelectElem.add(newEntry); // IE only
	}
	// Save the value
	textData[newEntryText] = targetValue;
	// Switch to the newEntry
	textSelectElem.selectedIndex = textSelectElem.length - 1;
	textSelect();
    }
}

// Language Management Variables/Functions
var langFreqData = new Array();

// Insert the English language frequencies
langFreqData["ENG"] = "ENG";
langFreqData["ENG A"] = "0.082";
langFreqData["ENG B"] = "0.015";
langFreqData["ENG C"] = "0.028";
langFreqData["ENG D"] = "0.043";
langFreqData["ENG E"] = "0.127";
langFreqData["ENG F"] = "0.022";
langFreqData["ENG G"] = "0.020";
langFreqData["ENG H"] = "0.061";
langFreqData["ENG I"] = "0.070";
langFreqData["ENG J"] = "0.002";
langFreqData["ENG K"] = "0.008";
langFreqData["ENG L"] = "0.040";
langFreqData["ENG M"] = "0.024";
langFreqData["ENG N"] = "0.067";
langFreqData["ENG O"] = "0.075";
langFreqData["ENG P"] = "0.019";
langFreqData["ENG Q"] = "0.001";
langFreqData["ENG R"] = "0.060";
langFreqData["ENG S"] = "0.063";
langFreqData["ENG T"] = "0.091";
langFreqData["ENG U"] = "0.028";
langFreqData["ENG V"] = "0.010";
langFreqData["ENG W"] = "0.023";
langFreqData["ENG X"] = "0.001";
langFreqData["ENG Y"] = "0.020";
langFreqData["ENG Z"] = "0.001";


function langSelect() {
    // If language is set to the Save As, then we can save, otherwise the
    // save option is diabled.
    langSelectElem = Element("langselect");
    index = langSelectElem.selectedIndex;
    optionText = langSelectElem.options[index].text;

    if (index == 0) {
	// Save As is selected, enable lang code field
	Enable('langcode');
	Element("langcode").value = "";
    } else {
	// Save As is not selected, disable lang code field, load freqs
	Disable('langcode');
	Element("langcode").value = optionText;
	// Load Frequencies
	Element("langfreqA").value = langFreqData[optionText+" "+"A"];
	Element("langfreqB").value = langFreqData[optionText+" "+"B"];
	Element("langfreqC").value = langFreqData[optionText+" "+"C"];
	Element("langfreqD").value = langFreqData[optionText+" "+"D"];
	Element("langfreqE").value = langFreqData[optionText+" "+"E"];
	Element("langfreqF").value = langFreqData[optionText+" "+"F"];
	Element("langfreqG").value = langFreqData[optionText+" "+"G"];
	Element("langfreqH").value = langFreqData[optionText+" "+"H"];
	Element("langfreqI").value = langFreqData[optionText+" "+"I"];
	Element("langfreqJ").value = langFreqData[optionText+" "+"J"];
	Element("langfreqK").value = langFreqData[optionText+" "+"K"];
	Element("langfreqL").value = langFreqData[optionText+" "+"L"];
	Element("langfreqM").value = langFreqData[optionText+" "+"M"];
	Element("langfreqN").value = langFreqData[optionText+" "+"N"];
	Element("langfreqO").value = langFreqData[optionText+" "+"O"];
	Element("langfreqP").value = langFreqData[optionText+" "+"P"];
	Element("langfreqQ").value = langFreqData[optionText+" "+"Q"];
	Element("langfreqR").value = langFreqData[optionText+" "+"R"];
	Element("langfreqS").value = langFreqData[optionText+" "+"S"];
	Element("langfreqT").value = langFreqData[optionText+" "+"T"];
	Element("langfreqU").value = langFreqData[optionText+" "+"U"];
	Element("langfreqV").value = langFreqData[optionText+" "+"V"];
	Element("langfreqW").value = langFreqData[optionText+" "+"W"];
	Element("langfreqX").value = langFreqData[optionText+" "+"X"];
	Element("langfreqY").value = langFreqData[optionText+" "+"Y"];
	Element("langfreqZ").value = langFreqData[optionText+" "+"Z"];
    }

}

function langSave() {
    // Determine the language to save
    optionText = Element("langcode").value;

    if (optionText != "") {
	// Determine if it is a new language
	testCode = langFreqData[optionText];
	if (testCode == optionText) {
	    // An existing language
	    alert("Saving " + optionText);
	} else {
	    // Create new language
	    var newEntry = document.createElement('option');
	    newEntry.text = optionText;
	    try {
		langSelectElem.add(newEntry,null); // Standards compliant
	    } catch(ex) {
		langSelectElem.add(newEntry); // IE only
	    }
	    langFreqData[optionText] = optionText;
	    alert("Creating " + optionText);
	}

	// Save values
	langFreqData[optionText+" "+"A"] = Element("langfreqA").value;
	langFreqData[optionText+" "+"B"] = Element("langfreqB").value;
	langFreqData[optionText+" "+"C"] = Element("langfreqC").value;
	langFreqData[optionText+" "+"D"] = Element("langfreqD").value;
	langFreqData[optionText+" "+"E"] = Element("langfreqE").value;
	langFreqData[optionText+" "+"F"] = Element("langfreqF").value;
	langFreqData[optionText+" "+"G"] = Element("langfreqG").value;
	langFreqData[optionText+" "+"H"] = Element("langfreqH").value;
	langFreqData[optionText+" "+"I"] = Element("langfreqI").value;
	langFreqData[optionText+" "+"J"] = Element("langfreqJ").value;
	langFreqData[optionText+" "+"K"] = Element("langfreqK").value;
	langFreqData[optionText+" "+"L"] = Element("langfreqL").value;
	langFreqData[optionText+" "+"M"] = Element("langfreqM").value;
	langFreqData[optionText+" "+"N"] = Element("langfreqN").value;
	langFreqData[optionText+" "+"O"] = Element("langfreqO").value;
	langFreqData[optionText+" "+"P"] = Element("langfreqP").value;
	langFreqData[optionText+" "+"Q"] = Element("langfreqQ").value;
	langFreqData[optionText+" "+"R"] = Element("langfreqR").value;
	langFreqData[optionText+" "+"S"] = Element("langfreqS").value;
	langFreqData[optionText+" "+"T"] = Element("langfreqT").value;
	langFreqData[optionText+" "+"U"] = Element("langfreqU").value;
	langFreqData[optionText+" "+"V"] = Element("langfreqV").value;
	langFreqData[optionText+" "+"W"] = Element("langfreqW").value;
	langFreqData[optionText+" "+"X"] = Element("langfreqX").value;
	langFreqData[optionText+" "+"Y"] = Element("langfreqY").value;
	langFreqData[optionText+" "+"Z"] = Element("langfreqZ").value;
    } else {
	alert("Invalid (Missing) Language Code");
    }
}

function langNormal() {
    // Add up sum
    var langFreqSum = 0.0;
    langFreqSum += parseFloat(Element("langfreqA").value);
    langFreqSum += parseFloat(Element("langfreqB").value);
    langFreqSum += parseFloat(Element("langfreqC").value);
    langFreqSum += parseFloat(Element("langfreqD").value);
    langFreqSum += parseFloat(Element("langfreqE").value);
    langFreqSum += parseFloat(Element("langfreqF").value);
    langFreqSum += parseFloat(Element("langfreqG").value);
    langFreqSum += parseFloat(Element("langfreqH").value);
    langFreqSum += parseFloat(Element("langfreqI").value);
    langFreqSum += parseFloat(Element("langfreqJ").value);
    langFreqSum += parseFloat(Element("langfreqK").value);
    langFreqSum += parseFloat(Element("langfreqL").value);
    langFreqSum += parseFloat(Element("langfreqM").value);
    langFreqSum += parseFloat(Element("langfreqN").value);
    langFreqSum += parseFloat(Element("langfreqO").value);
    langFreqSum += parseFloat(Element("langfreqP").value);
    langFreqSum += parseFloat(Element("langfreqQ").value);
    langFreqSum += parseFloat(Element("langfreqR").value);
    langFreqSum += parseFloat(Element("langfreqS").value);
    langFreqSum += parseFloat(Element("langfreqT").value);
    langFreqSum += parseFloat(Element("langfreqU").value);
    langFreqSum += parseFloat(Element("langfreqV").value);
    langFreqSum += parseFloat(Element("langfreqW").value);
    langFreqSum += parseFloat(Element("langfreqX").value);
    langFreqSum += parseFloat(Element("langfreqY").value);
    langFreqSum += parseFloat(Element("langfreqZ").value);

    // Divide out sums, then cap the float to 3 places after the decimal.
    Element("langfreqA").value = (parseFloat(Element("langfreqA").value) / langFreqSum).toFixed(3);
    Element("langfreqB").value = (parseFloat(Element("langfreqB").value) / langFreqSum).toFixed(3);
    Element("langfreqC").value = (parseFloat(Element("langfreqC").value) / langFreqSum).toFixed(3);
    Element("langfreqD").value = (parseFloat(Element("langfreqD").value) / langFreqSum).toFixed(3);
    Element("langfreqE").value = (parseFloat(Element("langfreqE").value) / langFreqSum).toFixed(3);
    Element("langfreqF").value = (parseFloat(Element("langfreqF").value) / langFreqSum).toFixed(3);
    Element("langfreqG").value = (parseFloat(Element("langfreqG").value) / langFreqSum).toFixed(3);
    Element("langfreqH").value = (parseFloat(Element("langfreqH").value) / langFreqSum).toFixed(3);
    Element("langfreqI").value = (parseFloat(Element("langfreqI").value) / langFreqSum).toFixed(3);
    Element("langfreqJ").value = (parseFloat(Element("langfreqJ").value) / langFreqSum).toFixed(3);
    Element("langfreqK").value = (parseFloat(Element("langfreqK").value) / langFreqSum).toFixed(3);
    Element("langfreqL").value = (parseFloat(Element("langfreqL").value) / langFreqSum).toFixed(3);
    Element("langfreqM").value = (parseFloat(Element("langfreqM").value) / langFreqSum).toFixed(3);
    Element("langfreqN").value = (parseFloat(Element("langfreqN").value) / langFreqSum).toFixed(3);
    Element("langfreqO").value = (parseFloat(Element("langfreqO").value) / langFreqSum).toFixed(3);
    Element("langfreqP").value = (parseFloat(Element("langfreqP").value) / langFreqSum).toFixed(3);
    Element("langfreqQ").value = (parseFloat(Element("langfreqQ").value) / langFreqSum).toFixed(3);
    Element("langfreqR").value = (parseFloat(Element("langfreqR").value) / langFreqSum).toFixed(3);
    Element("langfreqS").value = (parseFloat(Element("langfreqS").value) / langFreqSum).toFixed(3);
    Element("langfreqT").value = (parseFloat(Element("langfreqT").value) / langFreqSum).toFixed(3);
    Element("langfreqU").value = (parseFloat(Element("langfreqU").value) / langFreqSum).toFixed(3);
    Element("langfreqV").value = (parseFloat(Element("langfreqV").value) / langFreqSum).toFixed(3);
    Element("langfreqW").value = (parseFloat(Element("langfreqW").value) / langFreqSum).toFixed(3);
    Element("langfreqX").value = (parseFloat(Element("langfreqX").value) / langFreqSum).toFixed(3);
    Element("langfreqY").value = (parseFloat(Element("langfreqY").value) / langFreqSum).toFixed(3);
    Element("langfreqZ").value = (parseFloat(Element("langfreqZ").value) / langFreqSum).toFixed(3);
}

// Text Management Variables/Functions
var textNextIndex = 1;
var textData = new Array();

function textBlocks() {
    valA = 65;
    valZ = 90;
    text = Element("textedit").value;
    text = text.toUpperCase();
    newText = "";
    letIndex = 0;
    for(i=0; i < text.length; i++) {
	letterValue = text.charCodeAt(i);
	if (letterValue >= valA && letterValue <= valZ) {
	    newText += text[i];
	    letIndex++;
	    if (letIndex % 5 == 0) {
		newText += ' ';
	    }
	}
    }
    Element("textedit").value = newText;
}

function textSave() {
    // Determine which option was selected
    textSelectElem = Element("textselect");
    index = textSelectElem.selectedIndex;

    if (index == 0) {
	// Create new entry if index is 0
	var newEntryText = 'Text' + textNextIndex++;
	var newEntry = document.createElement('option');
	newEntry.text=newEntryText
	try {
	    textSelectElem.add(newEntry,null); // Standards compliant
	} catch(ex) {
	    textSelectElem.add(newEntry); // IE only
	}
	// Save the value
	textData[newEntryText] = Element("textedit").value;
	// Switch to the newEntry
	textSelectElem.selectedIndex = textSelectElem.length - 1;
    } else {
	// Save entry if it is not new
	optionText = textSelectElem.options[index].text;
	// Save the value
	textData[optionText] = Element("textedit").value;
    }
    textSelect();
}

function textDelete() {
    // Determine which option was selected
    textSelectElem = Element("textselect");
    index = textSelectElem.selectedIndex;

    if (index == 0) {
	// Erase the textarea
	Element("textedit").value = "";
    } else {
	// Delete the option and change to index 0
	optionText = textSelectElem.options[index].text;
	textData[optionText] = "";
	Element("textedit").value = "";
	// Remove the index
	textSelectElem.remove(index);
	// Change to option 0
	textSelectElem.selectedIndex = 0;
    }
    textSelect();
}

function textSelect() {
    // Determine which option was selected
    textSelectElem = Element("textselect");
    index = textSelectElem.selectedIndex;

    if (index == 0) {
	// Erase the textarea
	Element("textedit").value = "";
    } else {
	optionText = textSelectElem.options[index].text;
	Element("textedit").value = textData[optionText];
    }

    Element("subsource").innerHTML = Element("textedit").value;
    Element("caesarsource").innerHTML = Element("textedit").value;
    Element("playfairsource").innerHTML = Element("textedit").value;
    Element("adfgxsource").innerHTML = Element("textedit").value;
    Element("vigeneresource").innerHTML = Element("textedit").value;
}

// Load Function
function loadAll() {
    // Navigation tabs at the top of the page
    navTabs = new Ext.TabPanel({
	    renderTo: document.body,
	    activeTab: 0,
	    width: getWindowWidth(),
	    height: getWindowHeight(),
	    plain:true,
	    defaults:{autoScroll: true},
	    items:[{
		    title: 'Text',
		    autoLoad: 'text.html'
		},{
		    title: 'Language',
		    autoLoad: 'language.html'
		},{
		    title: 'Substitution',
		    autoLoad: 'substitution.html'
		},{
		    title: 'Caesar',
		    autoLoad: 'caesar.html'
		},{
		    title: 'Playfair',
		    autoLoad: 'playfair.html'
		},{
		    title: 'ADFGX',
		    autoLoad: 'adfgx.html'
		},{
		    title: 'Vigenere',
		    autoLoad: 'vigenere.html'
		}]
	});

    /// Indexing of tabs for handling by name.  This needs to
    /// be updated whenever tabs are added or removed.
    navTabIDs['text']         = 0;
    navTabIDs['language']     = 1;
    navTabIDs['substitution'] = 2;
    navTabIDs['caesar']       = 3;
    navTabIDs['playfair']     = 4;
    navTabIDs['adfgx']        = 5;
    navTabIDs['vigenere']     = 6;

    ///
    /// Force all of the following tabs to load
    ///
    navTabs.setActiveTab(navTabIDs['language']);
    navTabs.setActiveTab(navTabIDs['substitution']);
    navTabs.setActiveTab(navTabIDs['caesar']);
    navTabs.setActiveTab(navTabIDs['playfair']);
    navTabs.setActiveTab(navTabIDs['adfgx']);
    navTabs.setActiveTab(navTabIDs['vigenere']);

    /// Return to the default page
    navTabs.setActiveTab(navTabIDs['text']);

}

// Load the navigation tabs
Ext.onReady(loadAll);
