<!--Hide from old browsers
// place your JavaScript code here (// are JavaScript comments, ! is HTML comment

// Copyright © 2007 Ronald Pulcer (Ron Pulcer Music)

// 2007/07/15  This Javascript program is based on mtws_guitar_neck.js (as of 7/10/2007).
// By adding instrument, numStrings, numFrets and other properties, this version attempts
// to generalize the features for guitar, bass guitar, and hopefully other stringed instruments.
// Non-fretted stringed instruments could potentially be accomodated, since the visual presence
// of frets is the responsibility of the HTML.  But for now, the default instrument is guitar.

var instrumentOpt='guitar';
var numStrings=6;
var numFrets=15;
var fretted=true;

var selectOpt='single';
var selectColorOpt='cyan';
var audioOpt='mute';
var infoOpt='yes';
var handPrefOpt='R';			// right handed
var perspectiveOpt='you';	// your guitar resting on your lap
var tuningOpt='gtr_std';
var stringSelectOpt=true;
var fretPosOpt=1;
var fretWidthOpt='to15';
var fretWidth=15;				// Does not count open string markers, since they are always visible.
var openStringOpt=true;
var noteOccurOpt='lowpos';	// Lowest fretboard position

var currFSObj=null;
var prevFSObj=null;
var blinkTimer=500;

// Add 21 to piano key # in order to get equivalent MIDI #
//(piano 0 = MIDI 21; piano 87 = MIDI 108)
var midiOffset=+21

var octaveLen=12;		// Octave = 12 half-steps

// var audioDir="C:\\My Documents\\ron\\Marlboro College\\zonorus_rpulcer\\capstone\\mtws\\design\\audio\\";
// var audioDir="/~rpulcer/capstone/mtws/design/audio/";
var audioDir="/music/mtws/audio/";

// Note: First array entry unused, to allow easy access for strings 1-6
var stringSelected = new Array(7);
stringSelected[0]=0;	// unused entry
stringSelected[1]=true;
stringSelected[2]=true;
stringSelected[3]=true;
stringSelected[4]=true;
stringSelected[5]=true;
stringSelected[6]=true;

// Suffixes for string numbers: 1st, 2nd, 3rd, 4th, 5th, 6th
var numSuffix = new Array(7);
numSuffix[0] = '';
numSuffix[1] = 'st';
numSuffix[2] = 'nd';
numSuffix[3] = 'rd';
numSuffix[4] = 'th';
numSuffix[5] = 'th';
numSuffix[6] = 'th';

var noteName = new Array(12);
noteName[0] = 'A';
noteName[1] = 'A#=Bb';
noteName[2] = 'B';
noteName[3] = 'C';
noteName[4] = 'C#=Db';
noteName[5] = 'D';
noteName[6] = 'D#=Eb';
noteName[7] = 'E';
noteName[8] = 'F';
noteName[9] = 'F#=Gb';
noteName[10] = 'G';
noteName[11] = 'G#=Ab';

// Tuning related vars
var tuning = new Array();

// First entry [0] of any tuning is offset to piano key equivalent (piano key 19 = EE for std tuning).
// The remaining numbers [1] - [6] are the Instrument # (base 0, for lowest Instrument note).

// For example, 19 + 24 = 43 which equates to piano key 42 or 'e' on piano.
// For example, 19 +  5 = 24 which equates to piano key 24 or 'A' on piano.
// For example, 19 +  0 = 19 which equates to piano key 19 or 'EE' on piano.
var gtrStdTuning = new Array(7);
gtrStdTuning[0] = 19;
gtrStdTuning[1] = 24;
gtrStdTuning[2] = 19;
gtrStdTuning[3] = 15;
gtrStdTuning[4] = 10;
gtrStdTuning[5] = 5;
gtrStdTuning[6] = 0;

// Note Bass standard tuning is closely related to Guitar standard tuning
var bassStdTuning = new Array(5);
bassStdTuning[0] = 7;
bassStdTuning[1] = 15;
bassStdTuning[2] = 10;
bassStdTuning[3] = 5;
bassStdTuning[4] = 0;

// For example, 17 + 26 = 43 which equates to piano key 42 or 'e' on piano.
// For example, 17 +  7 = 24 which equates to piano key 24 or 'A' on piano.
// For example, 17 +  0 = 17 which equates to piano key 17 or 'DD' on piano.
var gtrDropDTuning = new Array(7);
gtrDropDTuning[0] = 17;
gtrDropDTuning[1] = 26;
gtrDropDTuning[2] = 21;
gtrDropDTuning[3] = 17;
gtrDropDTuning[4] = 12;
gtrDropDTuning[5] = 7;
gtrDropDTuning[6] = 0;

var gtrDropCTuning = new Array(7);
gtrDropCTuning[0] = 15;
gtrDropCTuning[1] = 28;
gtrDropCTuning[2] = 23;
gtrDropCTuning[3] = 19;
gtrDropCTuning[4] = 14;
gtrDropCTuning[5] = 9;
gtrDropCTuning[6] = 0;

var gtrDropATuning = new Array(7);
gtrDropATuning[0] = 12;
gtrDropATuning[1] = 31;
gtrDropATuning[2] = 26;
gtrDropATuning[3] = 22;
gtrDropATuning[4] = 17;
gtrDropATuning[5] = 12;
gtrDropATuning[6] = 0;

var gtrOpenATuning = new Array(7);
gtrOpenATuning[0] = 19;
gtrOpenATuning[1] = 24;
gtrOpenATuning[2] = 21;
gtrOpenATuning[3] = 17;
gtrOpenATuning[4] = 12;
gtrOpenATuning[5] = 5;
gtrOpenATuning[6] = 0;

var gtrOpenCTuning = new Array(7);
gtrOpenCTuning[0] = 15;
gtrOpenCTuning[1] = 28;
gtrOpenCTuning[2] = 24;
gtrOpenCTuning[3] = 19;
gtrOpenCTuning[4] = 16;
gtrOpenCTuning[5] = 7;
gtrOpenCTuning[6] = 0;

var gtrOpenDTuning = new Array(7);
gtrOpenDTuning[0] = 17;
gtrOpenDTuning[1] = 24;
gtrOpenDTuning[2] = 19;
gtrOpenDTuning[3] = 16;
gtrOpenDTuning[4] = 12;
gtrOpenDTuning[5] = 7;
gtrOpenDTuning[6] = 0;

var gtrOpenETuning = new Array(7);
gtrOpenETuning[0] = 19;
gtrOpenETuning[1] = 24;
gtrOpenETuning[2] = 19;
gtrOpenETuning[3] = 16;
gtrOpenETuning[4] = 12;
gtrOpenETuning[5] = 7;
gtrOpenETuning[6] = 0;

var gtrOpenGTuning = new Array(7);
gtrOpenGTuning[0] = 17;
gtrOpenGTuning[1] = 24;
gtrOpenGTuning[2] = 21;
gtrOpenGTuning[3] = 17;
gtrOpenGTuning[4] = 12;
gtrOpenGTuning[5] = 5;
gtrOpenGTuning[6] = 0;

var gtrDadgadTuning = new Array(7);
gtrDadgadTuning[0] = 17;
gtrDadgadTuning[1] = 24;
gtrDadgadTuning[2] = 19;
gtrDadgadTuning[3] = 17;
gtrDadgadTuning[4] = 12;
gtrDadgadTuning[5] = 7;
gtrDadgadTuning[6] = 0;


tuning['gtr_std']    = gtrStdTuning;
tuning['bass_std']   = bassStdTuning;
tuning['gtr_dropD']  = gtrDropDTuning;
tuning['gtr_dropC']  = gtrDropCTuning;
tuning['gtr_dropA']  = gtrDropATuning;
tuning['gtr_openA']  = gtrOpenATuning;
tuning['gtr_openC']  = gtrOpenCTuning;
tuning['gtr_openD']  = gtrOpenDTuning;
tuning['gtr_openE']  = gtrOpenETuning;
tuning['gtr_openG']  = gtrOpenGTuning;
tuning['gtr_dadgad'] = gtrDadgadTuning;


// Default/Stub functions (in case function is not defined in web page)
function onclick_fretboard(obj) {
	stringFretClick(obj);
}



function setInstrumentOpt(opt)
{
	instrumentOpt = opt.toLowerCase();		// alert(instrumentOpt);

	if(instrumentOpt=='guitar') {
		numStrings =  6;
//		numFrets   = 15;
		fretted    = true;
		tuningOpt='gtr_std';

		// Note: First array entry unused, to allow easy access for strings 1-6
		stringSelected = new Array(7);
	}
	else if(instrumentOpt=='bass') {
		numStrings =  4;
//		numFrets   = 15;
		fretted    = true;
		tuningOpt='bass_std';

		// Note: First array entry unused, to allow easy access for strings 1-4
		stringSelected = new Array(5);
	}
	else {
		alert("Instrument type of " + instrumentOpt + " is either not available or an invalid type.");
		return;
	}

	// Note: First array entry unused, to allow easy access for strings 1 - numStrings
	stringSelected[0]=0;	// unused entry
	for(var strg=1; strg<=numStrings; strg++) {
		stringSelected[strg]=true;
	}
}


function getPianoOffsetNum() {

	// The piano offset depends on the particular tuning (standard or alternate tuning)
	// The first entry [0] in each tuning definition array is reserved for Piano Offset number.
	var currentTuning = tuning[tuningOpt];
	return currentTuning[0];
}


function setSelectOpt(opt)
{
	selectOpt = opt;		// alert(selectOpt);
	resetFretboard();
	var sz;

	if(selectOpt=='single')     { sz = '10'; }
	else if(selectOpt=='multi') { sz = '30'; }
	else if(selectOpt=='blink') { sz = '100'; }

	var noteNameSelectObj = document.getElementById('note_name_selected');
	var noteNumSelectObj  = document.getElementById('note_num_selected');
	var pianoNumSelectObj = document.getElementById('piano_num_selected');

	if(noteNameSelectObj!=null) { noteNameSelectObj.size = sz; }
	if(noteNumSelectObj!=null)  { noteNumSelectObj.size  = sz; }
	if(pianoNumSelectObj!=null) { pianoNumSelectObj.size = sz; }
}


function setSelectColorOpt(opt)
{
	selectColorOpt = opt;		// alert(selectColorOpt);
}


function resetFretboard()
{

	var noteNameSelectObj=document.getElementById('note_name_selected');
	if(noteNameSelectObj!=null) { noteNameSelectObj.value = ''; }

	var noteNumSelectObj=document.getElementById('note_num_selected');
	if(noteNumSelectObj!=null) { noteNumSelectObj.value = ''; }

	var pianoNumSelectObj=document.getElementById('piano_num_selected');
	if(pianoNumSelectObj!=null) { pianoNumSelectObj.value = ''; }

	var selectNoteNumObj=document.getElementById('select_note_num');
	if(selectNoteNumObj!=null) { selectNoteNumObj.value = ''; }

	// Only toggle previously highlighted notes
	for(var fret=0; fret<=numFrets; fret++) {

		for(var strg=1; strg<=numStrings; strg++) {		// alert('Fret = ' + fret + '  String = ' + strg);

			sfObj=document.getElementById('img_fret' + fret + '_strg' + strg);
			if(sfObj != null) {									// alert('id = ' + sfObj.id);

				if(sfObj.src.indexOf('_play')>=0 || sfObj.src.indexOf('_mute')>=0) {
					toggleNote(sfObj);
				}
			}
		}
	}

	// Clear out optional table of note info, if it exists on page
	var noteSpanObj = document.getElementById('span_note_name_freq');
	if(noteSpanObj!= null) { noteSpanObj.innerHTML = ''; }
}


function resetRBOptions(opt, defaultValue)
{
	var rbObjs = document.getElementsByName(opt);
	//alert(rbObjs.length);

	for(var r=0; r<rbObjs.length; r++) {
		if(rbObjs[r]!=null) {
			if(rbObjs[r].value==defaultValue) {
				rbObjs[r].checked=true;
			}
			else {
				rbObjs[r].checked=false;
			}
		}
	}

}


function resetOptions()
{
	var docObj;

	if(instrumentOpt=='guitar') {
		tuningOpt='gtr_std';
	}
	else if(instrumentOpt=='bass') {
		tuningOpt='bass_std';
	}
	else {
		alert("Instrument type of " + instrumentOpt + " is either not available or an invalid type.");
		return;
	}

	resetRBOptions('select_opt', 'single');
	resetRBOptions('audio_opt',  'mute');
	resetRBOptions('info_opt',   'yes');
	resetRBOptions('hand_pref_opt',   'R');
	resetRBOptions('perspective_opt', 'you');

	//docObj = document.getElementById('note_range_low');
	//if(docObj!=null) { docObj.value='0'; }
	//docObj = document.getElementById('note_range_high');
	//if(docObj!=null) { docObj.value='39'; }

	docObj = document.getElementById('select_color_opt');
	if(docObj!=null) { docObj.value = 'cyan'; }
	docObj = document.getElementById('tuning_opt');
	if(docObj!=null) { docObj.value = tuningOpt; }
	docObj = document.getElementById('fret_pos_opt');
	if(docObj!=null) { docObj.value = '1'; }
	docObj = document.getElementById('fret_width_opt');
//	if(docObj!=null) { docObj.value = 'to15'; }
	if(docObj!=null) { docObj.value = 'to' + numFrets; }
	docObj = document.getElementById('open_string_opt');
	if(docObj!=null) { docObj.checked = true; }

	docObj = document.getElementById('string_select_opt');
	if(docObj!=null) { docObj.checked = true; }


	for(var strg=1; strg<=numStrings; strg++) {
		docObj = document.getElementById('cbx_string' + strg);
		if(docObj!=null) { docObj.checked = true; }
	}

	docObj = document.getElementById('note_occur');
	if(docObj!=null) { docObj.value = 'lowpos'; }

	selectOpt      = 'single';
	selectColorOpt = 'cyan';
	audioOpt       = 'mute';
	infoOpt        = 'yes';

	setHandPrefOpt('R');
	setPerspectiveOpt('you');

	setTuningOpt(tuningOpt);
	setStringSelectOpt(true);
	fretPosOpt      = 1;
//	fretWidthOpt    = 'to15';
	fretWidthOpt    = 'to' + numFrets;
	setFretWidth();
	openStringOpt   = true;
	setNoteOccurOpt('lowpos');

	// setSelectOpt calls resetFretboard();
	setSelectOpt(selectOpt);
}


function setAudioOpt(opt)
{
	audioOpt = opt;		// alert(audioOpt);
}


function setInfoOpt(opt)
{
	infoOpt = opt;			// alert(infoOpt);
	resetFretboard();
}


function setHandPrefOpt(opt)
{
	handPrefOpt = opt;	// alert(handPrefOpt);

//	if(handPrefOpt!='R') {
//		alert("Left handed option not developed yet.\n\nThank you for your patience.");
//		resetRBOptions('hand_pref_opt', 'R');
//		handPrefOpt = 'R';
//	}

	var dir = 'ltr';
	if(handPrefOpt=='L') { dir = 'rtl'; }

	tblObj = document.getElementById('fretboard_inner_table');
	if(tblObj!=null) { tblObj.dir = dir; }

	var tblObj = document.getElementById('fretboard_outer_table');
	if(tblObj!=null) { tblObj.dir = dir; }
}


function setPerspectiveOpt(opt)
{
	perspectiveOpt = opt;	// alert(perspectiveOpt);

	if(perspectiveOpt=='you') {
		perspectiveOpt = 'you';
		if(numFrets==15) {
			htmlFile = '/music/mtws/input_controls/' + instrumentOpt + '_fretboard_fullneck.html';
		}
		else {
			htmlFile = '/music/mtws/input_controls/' + instrumentOpt + '_fretboard_' + numFrets + 'frets.html';
		}
	}
	else if(perspectiveOpt=='other') {
		perspectiveOpt = 'other';
		if(numFrets==15) {
			htmlFile = '/music/mtws/input_controls/' + instrumentOpt + '_fretboard_fullneck_mirror.html';
		}
		else {
			htmlFile = '/music/mtws/input_controls/' + instrumentOpt + '_fretboard_' + numFrets + 'frets_mirror.html';
		}
	}

	ajaxGetFile(htmlFile, perspectiveOptStateChanged);
}

function perspectiveOptStateChanged()
{
	var divObj = null;
	if(instrumentOpt=='guitar') {
		divObj=document.getElementById('guitar_fretboard');
	}
	else if(instrumentOpt=='bass') {
		divObj=document.getElementById('bass_fretboard');
	}

	if(xmlHttp.readyState==1) {
		if(divObj!=null) { divObj.innerHTML = ''; }
	}
	else if(xmlHttp.readyState==4) {
		if(divObj!=null) { divObj.innerHTML = xmlHttp.responseText; }
		// After new HTML set, set visible options again, to maintain previous user selections
		setHandPrefOpt(handPrefOpt);
		setFretPosOpt(fretPosOpt);
		setFretWidthOpt(fretWidthOpt);
		setTuningOpt(tuningOpt);
		for(var strg=1; strg<=numStrings; strg++) {
			selectString(strg, stringSelected[strg]);
		}
	}

	// Update status for all status values
	updateAjaxStatus();
}


function setTuningOpt(opt)
{
	tuningOpt = opt;			// alert(tuningOpt);

	var currentTuning = tuning[tuningOpt];

	resetFretboard();

	// Fret Position (set to 0 to include low string open note when Open String option selected).
	var lowNote  = 0;
//	if( ! openStringOpt) { lowNote = fretPosOpt; }

	// Fret Position + Open String 1 Instrument # + Fret Width
	var highNote = fretPosOpt + currentTuning[1] + fretWidth - 1;

	var lowObj = document.getElementById('note_range_low');
	if(lowObj!=null) { lowObj.value = lowNote; }
	var highObj = document.getElementById('note_range_high');
	if(highObj!=null) { highObj.value = highNote; }

	// alert ("lowNote = " + lowNote + "\nhighNote = " + highNote);

	var nonBRString = numStrings;
	if(perspectiveOpt=='other') { nonBRString = 1; }

	for(var s=1; s<=numStrings; s++) {										// alert('Strg = ' + s);

		var openNote = currentTuning[s] + currentTuning[0];			// alert('openNote = ' + openNote);
		spanObj = document.getElementById("note_string" + s);
		if(spanObj!=null) {
			var brtag = '<br />'
			if(s==nonBRString) { brtag = ''; }
			spanObj.innerHTML = 
				" " + s + numSuffix[s] + ": <b>" + noteName[openNote % octaveLen] + "</b> " + brtag;
		}

		for(var f=0; f<=numFrets; f++) {										// alert('Fret = ' + f);
			var thisNote = (openNote + f) % octaveLen;					// alert('thisNote = ' + thisNote);
			var objName  = 'img_fret' + f + '_strg' + s;					// alert('objName = ' + objName);
			imgObj = document.getElementById(objName);
			// 2011/01/11: Added title attribute, since alt attribute no longer shows tooltips in IE8 and Firefox
			if(imgObj!=null) { imgObj.alt   = noteName[thisNote]; }		// alert('imgObj.alt = ' + imgObj.alt);
			if(imgObj!=null) { imgObj.title = noteName[thisNote]; }		// alert('imgObj.title = ' + imgObj.title);
		}
	}

}

function setStringSelectOpt(opt)
{
	stringSelectOpt = opt;		// alert(stringSelectOpt);

	for(var strg=1; strg<=numStrings; strg++) {
		cbxObj = document.getElementById('cbx_string' + strg);
		if(cbxObj!=null) {
			// If disabled, then set all strings back to checked
			if( ! opt) {
				cbxObj.checked       = true;
				stringSelected[strg] = true;
			}
			cbxObj.disabled = ! opt;
		}
	}
}


function setStringSelected(cbxObj)
{
	if(stringSelectOpt) {

		// Checkbox ID in the format: cbx_string#
		if(cbxObj!=null && cbxObj.id.indexOf('cbx_string')==0) {
			var strg = cbxObj.id.substring(10);
			stringSelected[Number(strg)] = cbxObj.checked;
			// alert('S: ' + strg + ' ' + stringSelected[Number(strg)]);
		}
	}
}


function selectString(strg, opt)
{
	if(stringSelectOpt) {

		// Checkbox ID in the format: cbx_string#
		cbxObj = document.getElementById('cbx_string' + strg);
		if(cbxObj!=null) {
			cbxObj.checked = opt;
			stringSelected[strg] = opt;
		}
	}
}


function setFretPosOpt(opt)
{
	fretPosOpt = Number(opt);			// alert(fretPosOpt);	alert(fretWidthOpt);
	setFretWidth();

}


function setFretWidthOpt(opt)
{
	fretWidthOpt = opt;		// alert(fretPosOpt);	alert(fretWidthOpt);
	setFretWidth();

}


function setNumFretsOpt(opt)
{
	numFrets = opt;		// alert(numFrets);
}


function setFretWidth() {

	var startFret = fretPosOpt;
	if(fretWidthOpt=='to15') {
		fretWidth = 15 - startFret + 1;
	}
	else if(fretWidthOpt=='to12') {
		fretWidth = 12 - startFret + 1;
	}
	else if(fretWidthOpt=='to5') {
		fretWidth = 5 - startFret + 1;
	}
	else if(fretWidthOpt=='to3') {
		fretWidth = 3 - startFret + 1;
	}
	else {
		fretWidth = Number(fretWidthOpt);
	}

	// alert("Fret Width = " +  fretWidth);

	var endFret = startFret + fretWidth - 1;

	if(endFret>numFrets) {
		alert('Adjusting Fret Width to fit valid range.');
		selObj = document.getElementById("fret_width_opt");
//		if(selObj!=null) { selObj.value='to15'; }
//		setFretWidthOpt('to15');
		if(selObj!=null) { selObj.value='to' + numFrets; }
		setFretWidthOpt('to' + numFrets);
	}
	else {

		for(var fret=1; fret<=numFrets; fret++) {
			var docObj = document.getElementById('fret_num' + fret);
			if(docObj!=null) {
//				if(startFret==1 && fretWidthOpt=='to15') {		// Check for default case
//					if(fret>12) { docObj.bgColor='#FF8800'; }		// Guitar body color
//					else {        docObj.bgColor=''; }
//				}
//				else if(fret>=startFret && fret<=endFret) {
				if(fret>=startFret && fret<=endFret) {
					docObj.bgColor='tan';								// Highlight subset of guitar neck
				}
				else {
					if(fret>12) { docObj.bgColor='#FF8800'; }		// Guitar body color
					else {        docObj.bgColor=''; }
				}
			}
		}
	}
}


function setOpenStringOpt(opt)
{
	openStringOpt = opt;		// alert(openStringOpt);
}


function setNoteOccurOpt(opt)
{
	noteOccurOpt = opt;		// alert(noteOccurOpt);
}


function stringFretClick(fsObj)
{
	if(fsObj!=null) {

		fsID = fsObj.id;
		imgID = 'img_' + fsID;
		imgObj = document.getElementById(imgID);

		if(imgObj!=null) {
			var strg = Number(getStrgNum(imgObj));
			var fret = Number(getFretNum(imgObj));
			var endFret = fretPosOpt + fretWidth - 1;

			if(stringSelected[strg]) {

				if( (fret==0 && openStringOpt) ||
					 (fret>=fretPosOpt && fret<=endFret) ) {

					selectFretString(imgObj);

					if(imgObj.src.indexOf('_play')>=0) {
						if(audioOpt=='play') {
							playGuitarNote(imgObj);
						}
					}

					if(infoOpt=='yes') {
						setNoteNameSelect(imgObj);
						setNoteNumSelect(imgObj);
						setPianoNumSelect(imgObj);
						// displayInfo(imgObj);
					}
				}
			}
		}
	}
}


function setNoteNameSelect(fsObj)
{
	var noteSelectObj=document.getElementById('note_name_selected');

	if(noteSelectObj!=null) {

		if(fsObj.src.indexOf('_play')>=0) {
			if(selectOpt=='single') {
				noteSelectObj.value = fsObj.alt;
			}
			else {
				if(noteSelectObj.value=='') {
					noteSelectObj.value = fsObj.alt;
				}
				else {
					noteSelectObj.value += ', ' + fsObj.alt;
				}
			}
		}
		else {
			var withComma = fsObj.alt + ', ';

			if(noteSelectObj.value.indexOf(withComma)>=0) {
				noteSelectObj.value = noteSelectObj.value.replace(withComma, '');
			}
			else {
				noteSelectObj.value = noteSelectObj.value.replace(fsObj.alt, '');
			}
			noteSelectObj.value = noteSelectObj.value.replace(/, $/, '');
		}
	}
}


function setNoteNumSelect(fsObj)
{
	var noteSelectObj=document.getElementById('note_num_selected');
	var fretNum = getFretNum(fsObj);
	var strgNum = getStrgNum(fsObj);

	var currentTuning = tuning[tuningOpt];
	var instrumentNoteNum = currentTuning[Number(strgNum)] + Number(fretNum);

	if(noteSelectObj!=null) {

		if(fsObj.src.indexOf('_play')>=0) {
			if(selectOpt=='single') {
				noteSelectObj.value = instrumentNoteNum;
			}
			else {
				if(noteSelectObj.value=='') {
					noteSelectObj.value = instrumentNoteNum;
				}
				else {
					noteSelectObj.value += ', ' + instrumentNoteNum;
				}
			}
		}
		else {
			var withComma = instrumentNoteNum + ', ';
			if(noteSelectObj.value.indexOf(withComma)>=0) {
				noteSelectObj.value = noteSelectObj.value.replace(withComma, '');
			}
			else {
				noteSelectObj.value = noteSelectObj.value.replace(instrumentNoteNum, '');
			}
			noteSelectObj.value = noteSelectObj.value.replace(/, $/, '');
		}
	}
}


function setPianoNumSelect(fsObj)
{
	var noteSelectObj=document.getElementById('piano_num_selected');
	var fretNum = getFretNum(fsObj);
	var strgNum = getStrgNum(fsObj);

	var currentTuning = tuning[tuningOpt];
	var pianoNoteNum = currentTuning[Number(strgNum)] + Number(fretNum) + currentTuning[0];

	if(noteSelectObj!=null) {

		if(fsObj.src.indexOf('_play')>=0) {
			if(selectOpt=='single') {
				noteSelectObj.value = pianoNoteNum;
			}
			else {
				if(noteSelectObj.value=='') {
					noteSelectObj.value = pianoNoteNum;
				}
				else {
					noteSelectObj.value += ', ' + pianoNoteNum
				}
			}
		}
		else {
			var withComma = pianoNoteNum + ', ';
			if(noteSelectObj.value.indexOf(withComma)>=0) {
				noteSelectObj.value = noteSelectObj.value.replace(withComma, '');
			}
			else {
				noteSelectObj.value = noteSelectObj.value.replace(pianoNoteNum, '');
			}
			noteSelectObj.value = noteSelectObj.value.replace(/, $/, '');
		}
	}
}


function isNoteNatural(noteNum) {

	var baseOctaveNum = noteNum % 12;

	if(baseOctaveNum == 0 || baseOctaveNum == 2 || baseOctaveNum == 3 || baseOctaveNum == 5 || 
	   baseOctaveNum == 7 || baseOctaveNum == 8 || baseOctaveNum == 10) {

		// alert("Natural note");
	   return true;
	}
	else {
		// alert("Sharp/Flat note");
		return false;
	}
}


function getFretNum(fsObj) {

	// Note: img src ids are assumed to be in the format of img_fret#_strg#.
	// Note: td ids are assumed to be in the format of fret#_strg#.
	var fsID = fsObj.id;		// alert(fsID);
	var idxStrg=fsID.indexOf('_strg');
	var imgid = fsID.indexOf('img');
	var startPos = 8;
	if(imgid==-1) { startPos = 4; }
	var fretNum=fsID.substring(startPos, idxStrg);
	// alert('fretNum = ' + fretNum);
	return fretNum;
}


function getStrgNum(fsObj) {

	// Note: img src ids are assumed to be in the format of img_fret#_strg#.
	// Note: td ids are assumed to be in the format of fret#_strg#.
	var fsID = fsObj.id;
	var idxStrg=fsID.indexOf('strg');
	var strgNum=fsID.substring(idxStrg+4);
	// alert('strgNum = ' + strgNum);
	return strgNum;
}


function selectFretString(fsObj)
{
	var fretNum = getFretNum(fsObj);
	var strgNum = getStrgNum(fsObj);

	currFSObj   = fsObj

	if(selectOpt=='single') {

		// Toggle previous note first, unless null
		if(prevFSObj != null) {
			// Exception for case of clicking same note more than once
			if(fsObj.id == prevFSObj.id) {
				prevFSObj=null;
			}
			else {
				// Only toggle previous note when highlighted
				if(prevFSObj.src.indexOf('_play')>=0) {
					toggleNote(prevFSObj);
				}
			}
		}

		// Toggle the selected note
		toggleNote(fsObj);
	}

	else if(selectOpt=='multi') {

		toggleNote(fsObj);
	}

	else if(selectOpt=='blink') {

		toggleNote(fsObj);

		// The second half of blink happens in another function
		setTimeout("sleeper_toggle()", blinkTimer);

	}

	prevFSObj = fsObj;

}

function sleeper_toggle() {
	toggleNote(currFSObj);
}


function toggleNote(fsObj)
{
	fsSrc = fsObj.src;
	var idx=fsSrc.indexOf('_play');

	if(idx>=0) {
		fsSrc = fsSrc.substring(0, idx) + '_noplay.gif';
	}
	else {
		idx=fsSrc.indexOf('_noplay');
		if(idx>=0) {

			if(selectColorOpt == 'piano') {
				var fret = getFretNum(fsObj);
				var strg = getStrgNum(fsObj);
				var currentTuning = tuning[tuningOpt];
				// Add piano offset + open string offset + fret #
				var pianoNoteNum = currentTuning[0] + currentTuning[Number(strg)] + Number(fret);

				var noteColor = 'black';
				if(isNoteNatural(pianoNoteNum)) {
					noteColor = 'white';
				}
				fsSrc = fsSrc.substring(0, idx) + '_play_' + noteColor + '.gif';
			}
			else {
				fsSrc = fsSrc.substring(0, idx) + '_play_' + selectColorOpt + '.gif';
			}
		}
		else {
			// Handle case for open strings
			idx=fsSrc.indexOf('_mute');
			if(idx>=0) {
				fsSrc = fsSrc.substring(0, idx) + '_noplay.gif';
			}
		}
	}

	fsObj.src = fsSrc;
}


function toggleNoteByNum(instrumentNoteNum) {

	var currentTuning = tuning[tuningOpt];
	var fret;
	var strg;
	var fretFrom = fretPosOpt;
	var fretTo   = fretFrom + fretWidth - 1;
	var noteOccur = new Array();
	var occur = -1;

	// Fret Position (set to 0 to include low string open note when Open String option selected).
	var lowNote  = 0;
//	if( ! openStringOpt) { lowNote = fretPosOpt; }

	// Fret Position + Open String 1 Instrument # + Fret Width
	var highNote = fretPosOpt + currentTuning[1] + fretWidth - 1;

	// alert ("lowNote = " + lowNote + "\nhighNote = " + highNote);

	if(instrumentNoteNum >= lowNote && instrumentNoteNum <= highNote) {

		if(selectOpt=='single') {
			resetFretboard();
		}

		for(strg=1; strg<=numStrings; strg++) {

			if(stringSelected[strg]) {

				// Check open strings first, if option is selected.
				if(openStringOpt) {

					if(currentTuning[strg]==instrumentNoteNum) {
						occur++;
						noteOccur[occur] = 'fret0_strg' + strg;
					}
				}

				for(fret=fretFrom; fret<=fretTo; fret++) {
					if((currentTuning[strg] + fret)==instrumentNoteNum) {
						occur++;
						noteOccur[occur] = 'fret' + fret + '_strg' + strg;
					}
				}
			}
		}

		var fsObj;
		var numOccur = noteOccur.length;
		if(numOccur>0) {
			if(noteOccurOpt=='lowpos') {
				fsObj = document.getElementById(noteOccur[0]);
				if(fsObj!=null) { stringFretClick(fsObj); }
			}
			else if(noteOccurOpt=='highpos') {
				fsObj = document.getElementById(noteOccur[numOccur-1]);
				if(fsObj!=null) { stringFretClick(fsObj); }
			}
			else if(noteOccurOpt=='1' && numOccur>=1) {
				fsObj = document.getElementById(noteOccur[0]);
				if(fsObj!=null) { stringFretClick(fsObj); }
			}
			else if(noteOccurOpt=='2' && numOccur>=2) {
				fsObj = document.getElementById(noteOccur[1]);
				if(fsObj!=null) { stringFretClick(fsObj); }
			}
			else if(noteOccurOpt=='3' && numOccur>=3) {
				fsObj = document.getElementById(noteOccur[2]);
				if(fsObj!=null) { stringFretClick(fsObj); }
			}
			else if(noteOccurOpt=='4' && numOccur>=4) {
				fsObj = document.getElementById(noteOccur[3]);
				if(fsObj!=null) { stringFretClick(fsObj); }
			}
			else if(noteOccurOpt=='all') {
				// Note: Even if in single note or blink mode, 
				// for purposes of ALL option, switch to multi note mode.
				if(selectOpt!='multi') {
					setSelectOpt('multi');
					resetRBOptions('select_opt', 'multi');
				}

				for(var occ=0; occ<numOccur; occ++) {
					fsObj = document.getElementById(noteOccur[occ]);
					if(fsObj!=null) { stringFretClick(fsObj); }
				}
			}
		}
	}
	else {
		var nnObj = document.getElementById('select_note_num');
		if(nnObj!=null) {
			alert("Please select an Instrument Note # between " + lowNote + " and " + highNote);
			nnObj.focus();
		}
	}
}


function toggleNotesByTab(tab) {

	resetFretboard();

	// Note: Even if in single note or blink mode, 
	// for purposes of ALL option, switch to multi note mode.
	if(selectOpt!='multi') {
		setSelectOpt('multi');
		resetRBOptions('select_opt', 'multi');
	}

	// Go through strings as if strumming down (for better display of note names and numbers).
	for(var strg=numStrings; strg>=1; strg--) {

		// Guitar Tab is read from string 6 to 1, so subtract string # from 6 to get matching tab value.
		var tabNote = tab.substring(numStrings-strg, numStrings-strg+1);
		// alert('strg: ' + strg + '\ntab: ' + tab + '\ntabNote: ' + tabNote);

		// Handle muted strings separately
		if(tabNote == 'x' || tabNote == 'X') {
			var imgObj = document.getElementById('img_fret0' + '_strg' + strg);
			if(imgObj!=null) {
				var idx=imgObj.src.indexOf('_noplay');
				if(idx>=0) {
					imgObj.src = imgObj.src.substring(0, idx) + '_mute_' + selectColorOpt + '.gif';
				}
			}
		}
		else {
			// Convert hex numbers for frets 10 and above.
			if(tabNote == 'a' || tabNote == 'A')      { tabNote = '10'; }
			else if(tabNote == 'b' || tabNote == 'B') { tabNote = '11'; }
			else if(tabNote == 'c' || tabNote == 'C') { tabNote = '12'; }
			else if(tabNote == 'd' || tabNote == 'D') { tabNote = '13'; }
			else if(tabNote == 'e' || tabNote == 'E') { tabNote = '14'; }
			else if(tabNote == 'f' || tabNote == 'F') { tabNote = '15'; }

			var fsObj = document.getElementById('fret' + tabNote + '_strg' + strg);
			// alert('fsObj.id: ' + fsObj.id);
			if(fsObj!=null) { stringFretClick(fsObj); }
		}
	}
}


function getAbbrevTab() {

	var abbrevTab = '';

	// Go through strings as if strumming down (for better display of note names and numbers).
	for(var strg=numStrings; strg>=1; strg--) {
		var nextTab = '';

		for(var fret=0; fret<=numFrets; fret++) {

			var imgObj = document.getElementById('img_fret' + fret + '_strg' + strg);
			if(imgObj!=null) {

				var fretName = fret;
				if(fret==0) {
					if(imgObj.src.indexOf('_play')>=0) {
						nextTab = '0';
					}
					else if(imgObj.src.indexOf('_mute')>=0) {
						nextTab = 'X';
					}
				
				}
				else {
					if(imgObj.src.indexOf('_play')>=0) {

						if(fret=='10')      { fretName = 'a'; }
						else if(fret=='11') { fretName = 'b'; }
						else if(fret=='12') { fretName = 'c'; }
						else if(fret=='13') { fretName = 'd'; }
						else if(fret=='14') { fretName = 'e'; }
						else if(fret=='15') { fretName = 'f'; }
									
						nextTab = fretName;
					}
				}
			}

		}
		if(nextTab=='') { nextTab = 'X'; }
		abbrevTab += nextTab;
	}

	var atObj = document.getElementById('select_abbrev_tab');
	if(atObj != null) { atObj.value = abbrevTab; }
}


function getMIDINum(pianoNoteNum) {
	var midiNum = pianoNoteNum + midiOffset;
	return midiNum;
}


function getMIDIFileName(midiNum) {
	var fn = audioDir + instrumentOpt + '/' + instrumentOpt + '_midi_num_' + midiNum + '.mid';	// alert(fn);
	return fn;
}

function playGuitarNotePlugin(fsObj) {
	// alert("got here: playGuitarNotePlugin " + fsObj.id);
	var fretNum = getFretNum(fsObj);		// alert(fretNum);
	var strgNum = getStrgNum(fsObj);		// alert(strgNum);

	var currentTuning = tuning[tuningOpt];
	var instrumentNoteNum = currentTuning[Number(strgNum)] + Number(fretNum);
	var pianoNoteNum = instrumentNoteNum + currentTuning[0];

	var midiNum = getMIDINum(pianoNoteNum);

	var embedObjID = 'embed_note_' + midiNum;		// alert(embedObjID);
	playnote(embedObjID);
}


function playnote(objid) {
	// alert(objid);
	playerObj = document.getElementById(objid);
	if(playerObj != null) {
		// alert('got here');
		playerObj.play();
	}
}


function playGuitarNote(fsObj)
{
	// Note: This code depends on method in wmpCodeGen_revised.js

	var fretNum = getFretNum(fsObj);
	var strgNum = getStrgNum(fsObj);

	var currentTuning = tuning[tuningOpt];
	var instrumentNoteNum = currentTuning[Number(strgNum)] + Number(fretNum);
	var pianoNoteNum = instrumentNoteNum + currentTuning[0];

	var midiNum = getMIDINum(pianoNoteNum);
	//alert(midiNum);

	var fn = getMIDIFileName(midiNum);

	newWin=window.open("", "playnote", "height=100,width=225,toolbar=no,resizable=no,menubar=no", false);
	var newHTML = getMediaCode(fn,1,45,200);								// alert(newHTML);
	newWin.document.open('text/html', 'replace');

	newWin.document.write('<html>\n<head>\n<title>Play Note - Guitar Tuning ' + tuningOpt + ': ' + 
		instrumentNoteNum + '</title>\n</head>\n<body>\n' + newHTML + 
		'\n<br /><br />Press F5 to replay note</body>\n</html>\n');
	newWin.blur();
}


function displayInfo(fsObj)
{
	var fretNum = getFretNum(fsObj);
	var strgNum = getStrgNum(fsObj);

	var currentTuning = tuning[tuningOpt];
	var instrumentNoteNum = currentTuning[Number(strgNum)] + Number(fretNum);
	var pianoNoteNum = instrumentNoteNum + currentTuning[0];

	var midiNum = pianoNoteNum + midiOffset;

	alert("Fret #:   " + fretNum + 
			"\nString #: " + strgNum + 
			"\nGuitar #: " + instrumentNoteNum + 
			"\nPiano #:  " + pianoNoteNum + 
			"\nMIDI #: " + midiNum +
			"\nNote:   " + fsObj.alt);
}



// Copyright © 2007 Ronald Pulcer (Ron Pulcer Music)

//-->

