// (c) 2002-2006 Max Edwards - unauthorised reproduction or distribution is prohibited
    function getRefToElement(id) {
        if( document.layers ) { //Netscape layers
            return document.layers[id]; }
        if( document.getElementById ) { //DOM; IE5, NS6, Mozilla, Opera
            return document.getElementById(id); }
        if( document.all ) { //Proprietary DOM; IE4
            return document.all[id]; }
        if( document[id] ) { //Netscape alternative
            return document[id]; }
        return false;
    }

function setHTML(id, htm) {
    setHTMLobj(getRefToElement(id), htm);
}
function setHTMLobj(o, htm) {
    o.innerHTML = htm;
    if (serverName == '127.0.0.1' && document.location.toString().toLowerCase().indexOf('show' + o.id.toLowerCase()) > 0) {
        var w = window.open('', o.id);
        w.document.write(htm);
    }
}
    
var myMusicObject = new Music();

var numfrets = 6;
var dir = 1;
var doSearch = true;

var instruments = new Array(
	[[40,45,50,55,59,64], 'Guitar', 0, 24],
	[[38,45,50,55,59,64], 'Guitar (dropped D)', 0, 24],
	[[38,45,50,54,57,62], 'Guitar (open D)', 0, 24],
	[[40,47,52,56,59,64], 'Guitar (open E)', 0, 24],
	[[38,43,50,55,59,62], 'Guitar (open G)', 0, 24],
	[[36,43,48,55,60,64], 'Guitar (Tom\'s open C)', 0, 24],
	[[64,59,55,50,45,40], 'Left-handed Guitar', 0, 24],
	[[28,33,38,43], '4-string Bass', 0, 33],
	[[23,28,33,38,43], '5-string Bass', 0, 33],
	[[23,28,33,38,43,48], '6-string Bass', 0, 33],
	[[23,28,33,38,42,47], '6-string Bass II', 0, 33],
	[[55,62,69,76], 'Mandolin', 0, 24],
	[[65,58,62,67], 'Ukelele', 0,24]
);

var patterns = new Array(
	[[],'(no chord)'],
	[[0,4,7],'(major)'],
	[[0,7],'-power'],
	[[0,4,7,9],'6'],
	[[0,4,7,10],'7'],	
	[[0,4,7,11],'maj7'],
	[[0,4,7,10,2],'9'],
	[[0,4,7,10,2,5],'13'],
	[[0,4,7,2],'add9'],
	[[0,4,7,11,2],'maj7add9'],
	[[0,4,7,9,2],'6/9'],
	[[0,4,7,10,3],'7<img border=0 src=images/sharpBlack.gif>9'],
	[[0,4,8,10],'7<img border=0 src=images/sharpBlack.gif>5'],
	[[0,3,7],'m'],
	[[0,3,7,9],'m6'],
	[[0,3,7,10],'m7'],	
	[[0,3,7,10,2],'m9'],
	[[0,3,7,10,2,5],'m13'],
	[[0,3,7,2],'madd9'],
	[[0,3,7,9,2],'m6/9'],
	[[0,3,6,10],'m7<img border=0 src=images/flatBlack.gif>5'],
	[[0,5,7],'sus4'],
	[[0,5,7,10],'sus47'],
	[[0,3,6],'o'],
	[[0,3,6,9],'o7'],
	[[0,4,8],'+'],
	[[0,3,5,6,7,9,10],'>> basic blues'],
	[[0,2,4,5,7,9,11],'>> major scale'],
	[[0,2,3,5,7,9,10],'>> dorian minor'],
	[[0,2,4,5,7,9,10],'>> mixolydian major'],
	[[0,2,3,5,7,8,10],'>> aolian minor'],
	[[0,2,3,5,7,8,11],'>> spanish minor']
	);

var dirnames = new Array('Facing left','Facing right','Upright');

var strings = new Array;
var pitches = new Array;
var highlight = new Array('','','','','','','','','','','','','','');

var notesused = new Array(-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1);
var notes = new Array('C','C<img border=0 src=images/sharpBlack.gif>','D','D<img border=0 src=images/sharpBlack.gif>','E','F','F<img border=0 src=images/sharpBlack.gif>','G','G<img border=0 src=images/sharpBlack.gif>','A','A<img border=0 src=images/sharpBlack.gif>','B');

var showflats = false;

var alldivs = '';
function makePage(base, pattern, lowfret, instrument,di,nf)
{	
	numfrets=nf;
	dir=di;
	strings = new Array;	
	pitches = instruments[instrument][0];
	strings.length = pitches.length;
	var mmm = '';
	for (var i=1;i<=pitches.length;i++) {
		strings[i-1]=(pitches[pitches.length-i])%12;
		myMusicObject.setProgram(i,instruments[instrument][3]);
		mmm += 'Set channel ' + i + ' to instrument ' + instruments[instrument][3] + '\n';
		myMusicObject.setChannelSolo(i,true);
		}
	//alert(mmm);
	alldivs = '';
	var hasFlat=hasCF=false;
	var chord = new Array;
	for (var i = 0; i<patterns[pattern][0].length; i++) {
		chord[i] = (parseInt(patterns[pattern][0][i])+parseInt(base)) % 12;
		if (chord[i]==6 || chord[i]==11) showflats = false;
		if (chord[i]==5 || chord[i]==0) hasCF=true;
		if (chord[i]==3 || chord[i]==10) hasFlat=true;
	}
	newstring = new Array(true,true,true,true,true,true,true,true,true,true,true,true,true);
	//alert(chord);
	//alert(lowfret);
	showflats = showflats || (hasCF && hasFlat);
	if (showflats)
		notes = new Array('C','D<img border=0 src=images/flatBlack.gif>','D','E<img border=0 src=images/flatBlack.gif>','E','F','G<img border=0 src=images/flatBlack.gif>','G','A<img border=0 src=images/flatBlack.gif>','A','B<img border=0 src=images/flatBlack.gif>','B');
	else
		notes = new Array('C','C<img border=0 src=images/sharpBlack.gif>','D','D<img border=0 src=images/sharpBlack.gif>','E','F','F<img border=0 src=images/sharpBlack.gif>','G','G<img border=0 src=images/sharpBlack.gif>','A','A<img border=0 src=images/sharpBlack.gif>','B');
	var htm = '';
	
	if (false) {
	    htm += '<h2>'
	    if (chord.length >0) {
		    htm += notes[base] + patterns[pattern][1].replace('>>','') + ' on ';
		    //alert(strings.length);
		    if (newlights) {highlight.length=strings.length; for (var i=0; i<strings.length; i++) {highlight[i]='';}}
	    } else {
		    if (newlights) for (var i=0; i<strings.length; i++) {highlight[i]='s'+i+'f0';}
	    }
	    htm += 'the ' + instruments[instrument][1] + '</h2>';
	}
	
	htm += '<table border=0 cellpadding=0 cellspacing=0>';
	
	if (dir==2)
	{
		for (var f=-1; f<numfrets; f++)
		{
			htm += '<tr>';
			for (var s=strings.length-1; s>=0; s--)
			{
				htm+='<td';
				if (f>=0) {if (fretmarker(f,s)) htm+=' background=images/vempty2.gif'; else htm+=' background=images/vempty3.gif';}						
				w = Math.round(40-f*20/12,0);
				htm += ' align=center valign=center height=' + w + '>';
				
				htm += boldnote(s,f,chord,f>=lowfret-1) + '</td>';
			}
			htm += '<td align=center valign=center>&nbsp;<a href="javascript:newlights=true;getRefToElement(\'cform\').lowfret.selectedIndex = ' + (f+1) + '; showChord();">' + (f+1) + '</a></td>';
			htm += '</tr>';
			
			htm += '<tr>';
			if (f<0) space='nut'; else space='fret';
			for (var s=0; s<strings.length; s++) htm += '<td><img border=0 src=images/v' + space + '.gif></td>';
			htm += '</tr>';
		}
		//alert(htm);
	} else {
		for (var s2=0; s2<strings.length; s2++)
		{
			if (dir==0) s=s2; else s=strings.length-s2-1;
			
			htm += '<tr>';
			
			for (var f2=-1; f2<numfrets; f2++)
			{
				if (dir==0) f=f2; else f=numfrets-f2-2;
				fhtm='';
				if (f>=0) {
					space='fret';
					if (fretmarker(f,s)) fhtm+='<td background=images/empty2.gif'; else fhtm+='<td background=images/empty3.gif';
				} else {
					space = 'nut';
					if (dir==1) space = 'rnut';
					fhtm += '<td';
				}
				ghtm = '<td><img border=0 src=images/' + space + '.gif></td>';
				
				w = (70-f*35/12);
				fhtm += ' align=center valign=center width=' + w + '>';
				
				fhtm += boldnote(s,f,chord,f>=lowfret-1) + '</td>';
				
				if (dir==0) htm += fhtm + ghtm; else htm += ghtm + fhtm;
			}
			htm += '</tr>';
		}
		htm += '<tr>';
		for (var i2 = 0; i2<numfrets+1; i2++)
		{
			if (dir==0) i=i2; else i=numfrets-i2;
			if (dir==1) htm += '<td></td>';
			htm += '<td align=center><a href="javascript:getRefToElement(\'cform\').lowfret.selectedIndex = ' + i + '; newlights=true; showChord();">' + i + '</a></td>';
			if (dir==0) htm += '<td></td>';
		}
		htm += '</tr>';
	}
	htm += '</table>';
	setHTML('display', htm);
	
	///////////////////////////////////////////////////////////////
	htm='';
	htm += '<form id=cform action="" method=POST><nobr>';
	
	htm += '<select name=base onChange="newlights=true;showChord()">';
	for (var i = 0;i<12;i++)
	{
		htm += '<option value=' + i;
		if (i==base) htm += ' selected';
		htm += '>' + notes[i].replace('<img border=0 src=images/flatBlack.gif>','b').replace('<img border=0 src=images/sharpBlack.gif>','#') + '</option>';
	}
	htm += '</select>';
	
	htm += '<select name=pattern onChange="newlights=true;showChord()">';
	for (var i = 0; i<patterns.length; i++)
	{
		htm += '<option value=' + i;
		if (i==pattern) htm += ' selected';
		htm += '>' + patterns[i][1] + '</option>';
	}
	htm += '</select> on the ';
	
	htm += '<select name=instrument onChange="newlights=true;showChord()">';
	for (var i = 0; i<instruments.length; i++)
	{
		htm += '<option value=' + i;
		if (i==instrument) htm += ' selected';
		htm += '>' + instruments[i][1] + '</option>';
	}
	htm += '</select>';
	
	
	htm += ' Auto-finger from fret position <select name=lowfret onChange="newlights=true;showChord()">';
	for (var i = 0; i<=numfrets; i++)
	{
		htm += '<option value=' + i;
		if (i==lowfret) htm += ' selected';
		htm += '>' + i + '</option>';
	}
	htm += '</select>';
	
	
	htm += '</nobr><br /><nobr>';
	

	
	htm += 'Display direction:<select name=dir onChange="showChord()">';
	for (var i = 0; i<=2; i++)
	{
		htm += '<option value=' + i;
		if (i==dir) htm += ' selected';
		htm += '>' + dirnames[i] + '</option>';
	}
	htm += '</select>';
	
	htm += '  No. frets to display: <select name=numfrets onChange="showChord()">';
	for (var i = 3; i<=17; i++)
	{
		htm += '<option value=' + i;
		if (i==numfrets) htm += ' selected';
		htm += '>' + i + '</option>';
	}
	htm += '</select>';
	
		
	htm += '... Sharp/Flat mode:<select name=showflats onChange="showChord()">';
	htm += '<option'; if (!showflats) htm += ' selected'; htm += '>######</option>';
	htm += '<option'; if (showflats) htm += ' selected'; htm += '>bbbbbb</option>';
	htm += '</select>';
	
	htm += ' ... <input type=checkbox name=showdud value=yes';
	if (showdud) htm += ' checked';
	htm += ' onClick="showChord()"> Show intermediate notes';	
	
	htm += '</nobr><br />';
	if (chord.length>0) htm+= '<a href="javascript:hideUnused();">Hide unused notes</a> | ';
	htm+= '<a href="javascript:newlights=true;showChord();">Refresh</a> | <a href="javascript:strum(true,100);">strum1</a> | <a href="javascript:strum(true,40);">strum2</a> | <a href="javascript:strum(true,0);">strum3</a>';
	
	//if (dir==2) getRefToElement('control').innerHTML = htm; else {getRefToElement('finder2').innerHTML = htm;getRefToElement('control').innerHTML = '';}
	setHTML('control', htm);
	//getRefToElement('finder1').innerHTML = '';
	//getRefToElement('finder2').innerHTML = '';
	setHTML('finder', '');
	for (var i=0; i<strings.length; i++) {notesused[i]=-1; makeBig(highlight[i]);}
	doFind();
	newlights=false;
	strum(true,4);
}

var newlights=true;

function fretmarker(f,s){
	var hnum=0;
	if (f%12==2 || f%12==4 || f%12==6 || f%12==8) hnum=1;
	if (f%12==11) hnum=2;
	return (hnum>0 && (s>=((strings.length)/2-hnum) && s<((strings.length)/2+hnum)));
}
function showChord()
{
	showdud = getRefToElement('cform').showdud.checked;
	showflats = (getRefToElement('cform').showflats.selectedIndex > 0);
	makePage(getRefToElement('cform').base.selectedIndex, getRefToElement('cform').pattern.selectedIndex,  getRefToElement('lowfret').selectedIndex,  getRefToElement('instrument').selectedIndex, getRefToElement('dir').selectedIndex, getRefToElement('numfrets').selectedIndex+3);
    refreshAllIframes();    	
}

function makeSmall(oi)
{
	//alert('Making ' + oi + ' small');
	if (oi != '') {
		//alert(oi);
		var o = getRefToElement(oi);
		o.state = 'small';
		if (o.type == 'unused') {
			o.style.fontSize = '10px';
			o.style.fontWeight = 'normal';
			if (!showdud && o.fret>0) setHTMLobj(o, '');}
		else {
			//o.style.backgroundColor = 'f6f6f6';
		        //o.style.fontSize = '12px';
		}
		o.style.backgroundImage = '';
		notesused[o.string] = -1;
		highlight[o.string] = '';
		
	}
}

function makeBig(oi)
{
	//alert('Making ' + oi + ' big');
	if (oi != '') {
		var o = getRefToElement(oi);
		
		o.state = 'big';
		setHTMLobj(o, o.nname);
		//o.style.border = '';//o.bord;
		if (o.type == 'unused') {
			//o.style.fontSize = '17px';
			o.style.fontWeight = 'bold';
			
		} else {
			//o.style.backgroundColor = 'b0b0b0';
		        //o.style.fontSize = '15px';
		}
		o.style.backgroundImage = 'url(images/circle-pink.gif)';
		o.style.backgroundRepeat = 'no-repeat';
		if (notesused[o.string]>=0) {
			//alert(o.string + ' string was playing ' + notesused[o.string]);
			makeSmall(highlight[o.string]);
		}
		notesused[o.string] = o.note;
		//alert(o.string + ' string is now playing ' + o.note);
		highlight[o.string] = o.id;
		
	}
}
var showdud = false;

var tooSoon=false;
function startWait() {tooSoon=true; setTimeout('tooSoon=false;',600);}

function hideUnused()
{
	//alert(alldivs);
	var ad = alldivs.split(',');
	for (var i =0; i<ad.length; i++) if (getRefToElement(ad[i]).state != 'big') hide(ad[i]);
}
function hide(oi)
{
	var o = getRefToElement(oi);
	if (!showdud && o.fret>0) setHTMLobj(o, '');
	//o.style.fontSize = '10px';
	//o.style.fontWeight = 'normal';
	o.style.border='';
	o.style.background='';
	o.state = 'small';
	for (var i = 0; i<strings.length; i++) if (highlight[i]==oi) {highlight[i]='';notesused[i]=-1;}
}
function strum(dir,speed)
{
	var pit = '';
	var i2=0;
	for (var i = 0; i<highlight.length; i++)
	{
		if (!dir) i2=highlight.length-1-i; else i2=i;
		if (highlight[i2]!='') {
			if (pit!='') pit+=',';
			pit += getRefToElement(highlight[i2]).midi;
			}
	}
	nplaying = pit.split(',');
	doStrum(speed);
}
var nplaying = new Array;

function doStrum(d)
{
	//alert(nplaying);
	if (nplaying.length>0) playString(nplaying.length,parseInt(nplaying[nplaying.length-1]));
	nplaying.length-=1;
	if (nplaying.length>0) setTimeout('doStrum(' + d + ')', d);
}
function showNotes(m)
{
	var ad = alldivs.split(',');
	var o;
	for (var i =0; i<ad.length; i++) 
	{
		//o = eval('document.all.' + ad[i]);
		//if (parseInt(o.midi) == m) o.style.backgroundImage = 'url(images/circle-hollow.gif)';
	}
}
function boldnote(s,f,c,inposition)
{
	//if (f<0) alert('string ' + s + ' has pitch ' + strings[s]);
	var n = (strings[s] + f + 1 + 36) % 12;
	var mpit = (pitches[pitches.length-s-1]+f+1);
	
	var click = ' midi="' + mpit + '" fret="'+(f+1)+'" string="'+s+'" note="'+n+'" id="s' + s + 'f' + (f+1) + '" onmouseover="playString('+(s+1)+',' + mpit +');  showNotes(' + mpit + ');" onmouseout="//restoreNotes(' + mpit + ');" onclick="playString('+(s+1)+',' + mpit +'); {if (this.state == \'big\') {makeSmall(this.id)} else {makeBig(this.id);}} doFind();"';
	
	//if (f<0) alert(click);
	var r = '';
	for (var i = 0; i<c.length; i++)
	{
		if (c[i]==n) {
			if (alldivs!='') alldivs+=',';
			alldivs+='s' + s + 'f' + (f+1);
			//if (c.length>5)
				nnam = '<span class=nname>' + (i+1) + '</span><span class=nname2>'+ notes[n] + '</span>';
			//else
			//	nnam = '<img border=0 width=6 height=13 src=images/' + (i+1) + 'of'+c.length+'.gif>'+ notes[n] + '';
			r = '<div nname="' + nnam + '" type="used"' + click + ' style="cursor:pointer; width:22px; height:21px; color:blue; font-family:verdana;';
			if (i==0) bord= 'font-weight:bold;'; else bord= '';
			r += bord;
			highthis = (((newstring[s] || (dir==1)) && inposition) && newlights);
			if (highthis) {
				//r+= '; font-size:16px; background-color:#b0b0b0" state="big">';
				newstring[s] = false;
				highlight[s] = 's' + s + 'f' + (f+1);
				notesused[s]=n;}
			//else 
			r+= '; font-size:12px;" state="small" bord="'+bord+'">';
			r+=nnam;
			r += '</div>';		
		}
	}
	if (r=='') {
		r='<div nname="'+notes[n]+'" state="small" type="unused"' + click + ' style="cursor:pointer; width:22px; height:21px; color:#903030; font-size:10px; font-family:verdana">';
		if (showdud || f<0) r+= notes[n];
		r += '</div>';
	}
	return r;
	
}
document.onselectstart = doSelectStart;
function doSelectStart()
{
	var wid = window.event.srcElement.id.toString().toLowerCase();
	if (wid != 'textarea' && wid != 'firstname' && wid != 'lastname' && wid != 'manager')
	{
		window.event.returnValue = false;
		window.event.cancelBubble = true;
	}
}
function inChord(n,base,chord)
{
	if (n<0 || chord.length<1) return -1;
	for (var i = 0; i<chord.length; i++)
		{if (chord[i]>=0 & n%12 == (chord[i]+base)%12) return i;}
	return -1;
}
function doFind() {
	var htm = 'Clickable chord display: ';
	var mychord = new Array(-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1);
	var notesfound = 0;
	for (var i = strings.length-1; i>=0; i--)
	{
		if (notesused[i]<0) 
			htm += ' x';
		else {
			htm += ' ' + notes[notesused[i]];
			
			if (parseInt(inChord(notesused[i],0,mychord)) < 0) {
				notesfound++;
				mychord[notesfound-1]=parseInt(notesused[i]);}
		}
	}
	setHTML('title1', htm);
	
	mychord.length=notesfound;
	//alert(mychord);
	
	htm = '';
	var tit2 = '';
	if (doSearch && notesfound>0)
	{
		tit2 = 'Chords &amp; scales that include all ' + notesfound + ' notes';
		
		//htm += '<table id=scaleTable cellpadding=1 cellspacing=0 width=100% ><tr>';
		var numInCol=0;
		var sep = '';
		for (var b=0;b<12;b++) 
		{	
		    sep = '<div class=chordLabel>' + notes[b] + '</div>';
			for (var c=0;c<patterns.length;c++)
			if (patterns[c][0].length > 1)
			{
				inThis=true;
				for (var i = 0; i<mychord.length; i++)
					inThis = inThis && (inChord(mychord[i],b,patterns[c][0])>=0);
				if (inThis) 
				{
				    //if (numInCol >= 7) {htm+= '</td>'; numInCol=0;}
					//if (numInCol == 0) {htm+='<td valign=top style="font-size:9px">';}
					//else 
					{htm += sep; sep = '';}
					htm += '<span class=chordItem';
					if (mychord.length == patterns[c][0].length) htm += 'HI';
					htm += '>';
					href = '"javascript:getRefToElement(\'base\').selectedIndex = ' + b + '; getRefToElement(\'pattern\').selectedIndex = ' + c + '; showChord();"';
					htm += '<a href=' + href + '>' + notes[b] + patterns[c][1].replace('>>','') + '</a>';
					htm += '<br>(';
					for (var i =0; i<patterns[c][0].length; i++)
					{
						if (i>0) htm+= ',';
						n=(patterns[c][0][i] + b)%12;
						embold = (inChord(n,0,mychord)>=0);
						if (embold) htm+= '<b>';
						htm += notes[n];
						if (embold) htm+= '</b>';
						
					}
					htm += ')</span>';
					numInCol ++;
				}
			}
		}
		//if (numInCol > 0) htm+= '</td>';
		//htm += '</tr></table>';
	}
	//if (dir==2) getRefToElement('finder2').innerHTML = htm; else getRefToElement('finder1').innerHTML = htm;	
    setHTML('finder', htm);	
    setHTML('title2', tit2);	
}

var newstring = new Array(true,true,true,true,true,true,true,true,true,true,true,true,true);

function playString(s,n)
{
	myMusicObject.noteOn(s, -1,-1, n,127,127,1127,1127,1127);
	window.status = 'c'+s+', n'+n;
}

function refreshAllIframes() {
                return;
                // seems to refresh the whole document! WHY?!!! OUT OF USE
                var x = document.getElementsByTagName("iframe");
	            if (typeof x == "undefined") {
		            if (dbug && serverName == '127.0.0.1') alert('Cannot get list of IFRAMEs');
		            return;
		        }
		        if (x.length ==0) {
		            if (dbug && serverName == '127.0.0.1') alert('Page contains zero IFRAMEs');
		            return;
		        }
		        for (iframeNo=0; iframeNo<x.length; iframeNo++) {
		        	//alert('Reloading ' + x[iframeNo].src);
		            x[iframeNo].src += '?';
		        }
}

function refreshTDiframe() {
    var v = getRefToElement('TDiframe');
    if (v) v.src += '?';
}