// Global variables
var gameOn=0;						// Which game is in progress (0=none, 1=Strings & Frets, 2=Notes)
var fretLimit=8;					// How far up the fretboard to quiz on
var stringCount=6;					// The number of strings to quiz on (size of the stringList array)
var stringList = [ 1,2,3,4,5,6 ];	// The list of strings to quiz on
var rightCount=[0,0,0,0,0,0,0];		// How many right anwsers on each string this game
var wrongCount=[0,0,0,0,0,0,0];		// How many wrong answers on each string this game
var thinkTime=[0,0,0,0,0,0,0];		// Total time to answer this game
var currentThinkTime=0				// Think time for this question
var currentThinkTimeTimerId=0;		// The Timer ID (returned by setInterval) for the current timer
var currentString;					// The current string
var currentFret;					// The current fret
var currentNote;					// The current note (derived from currentString and currentFret)
var currentAskedNote				// If currentNote is a black key, which name was asked for (# or b)
var questionAskedTime				// The time the current question was asked
var scaleNotes=[ "E","F","F#/Gb","G","G#/Ab","A","A#/Bb","B","C","C#/Db","D","D#/Eb" ];
var openStrings=[ -1,0,7,3,10,5,0 ];



function ToggleString(stringNumber)
{
	// Switch the string's state
	var string = document.getElementById("stringLabel"+stringNumber);
	if (string.className == "stringLabel set")
	{
		if (stringCount > 1) 
		{
			string.className = "stringLabel clear";
		}
		else
		{
			alert("You have to leave at least one string selected !");
			return;
		}
	}
	else
	{
		string.className = "stringLabel set";
	}
	
	// Refresh the list of selected strings
	stringCount = 0;
	stringList = [];
	for (i=1 ; i <= 6 ; ++i)
	{
		if (document.getElementById("stringLabel"+i).className == "stringLabel set") stringList[stringCount++] = i;
	}
}



function SelectFret(n)
{
	if (n < 5) n=5;		// Don't allow fewer than 5 frets
	for (i=5 ; i <= 15 ; ++i)
	{
		if (fret = document.getElementById("fretLabel"+i))
		{
			fret.className = (i<=n)?"fretLabel set":"fretLabel clear";
		}
	}
	fretLimit = n;
}




function PlaceStringMarker(string,fret)
{
	var marker=document.getElementById("stringMarker");
	if ((string==0) || (fret==0))
	{
		marker.style.visibility="hidden";
		return;
	}
	marker.style.left = (40+32+(fret-1)*64-15)+"px";	// StringLabel width=40, 1/2 fret width=32, 1/2 marker width=15
	marker.style.top =  (17+(6-string)*35-15)+"px";	// 1/2 string height=17, 1/2 marker height=15
	marker.style.visibility="visible";
}





function StartGame(game)
{
	// Enable the "Finish Game" button
	document.getElementById("finishGame").disabled=false;
	
	// Vamoose the instructions (using JQuery method)
	$("div#instructions").hide("slow");
	$("div#question").show("slow");
	
	if (game == 1)
	{
		// Set the pointer for the keyboard keys to be a pointer
		$("div.key").css("cursor","pointer");
	}
	else if (game == 2)
	{
		$("img.fret").css("cursor","pointer");
	}
	// Start a game
	gameOn=game;
	questionNumber=0;
	rightCount=[0,0,0,0,0,0,0];
	wrongCount=[0,0,0,0,0,0,0];
	thinkTime=[0,0,0,0,0,0,0];
	UpdateScoreboard();
	PopQuestion();
}



function FinishGame()
{
	var statistics = document.getElementById("statistics");
	gameOn=0;
	clearInterval(currentThinkTimeTimerId);
	currentThinkTimeTimerId = 0;
	document.getElementById("finishGame").disabled=true;
	PlaceStringMarker(0,0);
	$("div.key").css("cursor","default");
	$("img.fret").css("cursor","default");
	UpdateStatistics();
}



function UpdateStatistics()
{
	var barWidth=150;
	var maxThinkTime=0;
	var statistics = document.getElementById("statistics");
	var s="<h1>Game Statistics</h1>\n";
	s += "<table id='statisticsTable'><tr><th>STRING</th> <th colspan=2>ACCURACY</th> <th colspan=2>AVERAGE TIME</th></tr>\n";

	// Average the thinkTime values
	for (var i=6 ; i >= 0 ; --i)
	{
		if (i > 0)	// Using position 0 in the array to keep the totals
		{
			rightCount[0] += rightCount[i];
			wrongCount[0] += wrongCount[i];
			thinkTime[0] += thinkTime[i];
		}
		if (rightCount[i] + wrongCount[i] > 0)
		{
			thinkTime[i] /= (rightCount[i]+wrongCount[i]);	// Average
			thinkTime[i] = Math.round(thinkTime[i]/10)/100;	// Convert to ms rounded to 2 decimal place
			if (thinkTime[i] > maxThinkTime) maxThinkTime = thinkTime[i];
		}
	}
	
	// Display the statistics
	for (var i=6 ; i >= 0 ; --i)
	{
		if (rightCount[i]+wrongCount[i] == 0) continue;
		s += "<tr><td>"+((i>0)?i:"<b>TOTAL</b>")+"</td> <td>"+rightCount[i]+"/"+(rightCount[i]+wrongCount[i])+"</td>";
		var rightFraction=rightCount[i]/(rightCount[i]+wrongCount[i]);
		s += "<td style='padding-left: 0px;'>";
		if (rightFraction > 0){ s += "<div style='position: relative; height: 1em; width: "+Math.round(barWidth*rightFraction)+"px; background: green; float: left;'></div>"; }
		if (rightFraction < 1){ s += "<div style='position: relative; height: 1em; width: "+Math.round(barWidth*(1-rightFraction))+"px; background: red; float: left;'></div>"; }
		s += "<span style='margin-left: 1em;'>("+Math.round(rightFraction*100)+"%)</span></td>";
		s +="<td>"+thinkTime[i]+"s</td> <td style='padding-left: 0px;'><div style='position: relative; height: 1em; width: "+Math.round(barWidth*thinkTime[i]/maxThinkTime)+"px; background: blue; float: left;'></div><div style='position: relative; height: 1em; width: "+Math.round(barWidth*(maxThinkTime-thinkTime[i])/maxThinkTime)+"px; float: left;'></div></td></tr>\n";
	}
	s += "</table>\n<center><input type='button' value='Play Another Game' onClick='ResetGame();' style='margin: 20px'></center>";
	s += "<center><p><i>If you enjoyed this (or if you just have a music exam coming up !) you might also enjoy the <a href='/IntervalPopQuiz/'>Interval Pop Quiz</a> game</i></p></center>";
	statistics.innerHTML = s;
	$("div#question").hide("slow");
	$("div#keyboard-and-scoreboard").hide("slow");
	$(statistics).show("slow");
}



function ResetGame()
{
	// Clear the current question
	document.getElementById("qnumber").innerHTML="";
	document.getElementById("qtext").innerHTML="";
	document.getElementById("qtime").innerHTML="";

	// Clear the scoreboard
	document.getElementById("right").innerHTML="&nbsp;";
	document.getElementById("wrong").innerHTML="&nbsp;";
	document.getElementById("averageTime").innerHTML="&nbsp;";

	// Hide and clear the statistics
	$("div#statistics").hide("slow",function(){ document.getElementById("statistics").innerHTML=""; }); 

	// Display the instructions and the keyboard
	$("div#keyboard-and-scoreboard").show("slow");
	$("div#instructions").show("slow"); 
}



function PopQuestion()
{
	++questionNumber;
	currentString = stringList[Math.floor(Math.random()*stringCount)];
	if (gameOn == 1)
	{
		currentFret = Math.floor(Math.random()*(fretLimit+1));
	}
	else if (gameOn == 2)
	{
		// Don't ask about the open position (because there is no way to answer it !!)
		currentFret = Math.floor(Math.random()*(fretLimit))+1;
	}
	currentNote = scaleNotes[(currentFret+openStrings[currentString]) % 12];

	// Hide the current question
	document.getElementById("qnumber").style.visibility = "hidden";
	document.getElementById("qtext").style.visibility = "hidden";
	document.getElementById("qtime").style.visibility = "hidden";

	// Set up new question
	document.getElementById("qnumber").innerHTML="Q"+questionNumber;
	if (gameOn == 1)
	{
		// Ask what note is at the chosen string/fret
		if (currentFret == 0)
		{
			document.getElementById("qtext").innerHTML=currentString+NumberSuffix(currentString)+" string, open position";
		}
		else
		{
			document.getElementById("qtext").innerHTML=currentString+NumberSuffix(currentString)+" string, "+currentFret+NumberSuffix(currentFret)+" fret";
		}
		PlaceStringMarker(currentString,currentFret);
	}
	else if (gameOn == 2)
	{
		var notesChoice;
		currentFret = currentFret % 12;		// Handle frets >= 12
		currentAskedNote=currentNote;
		if (notesChoice = currentNote.match(/^([A-G].)\/([A-G].)$/))
		{
			// Black note...decide whether to ask for the # or the b
			currentAskedNote = notesChoice[1+Math.round(Math.random())];
		}
		document.getElementById("qtext").innerHTML=currentAskedNote+" on the "+currentString+NumberSuffix(currentString)+" string";
	}
	document.getElementById("qtime").innerHTML="0s";
	
	// Schedule the new question to appear in 500ms
	setTimeout(function(){
		clearInterval(currentThinkTimeTimerId);
		if (gameOn == 0){ return };	// Incase "Finish Game" button is clicked during the 500ms delay
		document.getElementById("qnumber").style.visibility = "visible";
		document.getElementById("qtext").style.visibility = "visible";
		document.getElementById("qtime").style.visibility = "visible";
		questionPopped = true;
		currentThinkTime = 0;
		currentThinkTimeTimerId = setInterval(function(){ currentThinkTime++; document.getElementById("qtime").innerHTML=currentThinkTime+"s"; },1000);
		questionAskedTime = ((new Date()).getTime()); },500);
}



function NumberSuffix(n)
{
	if (n == 1) return("st");
	if (n == 2) return("nd");
	if (n == 3) return("rd");
	return("th");
}




function PlayKey(ans)
{
	var rightwrong;

	if ((gameOn != 1) || (!questionPopped))
	{
		// Nothing to do if there isn't a "Strings and Frets" game in progress !
		return;
	}
	questionPopped = false;	// Don't accept another answer until the next question is popped
	rightwrong = document.getElementById("rightwrong");
	if (ans == currentNote)
	{
		rightCount[currentString]++;
		if (rightwrong)
		{
			rightwrong.style.color = "green";
			rightwrong.innerHTML = "Correct!";
		}
	}
	else
	{
		wrongCount[currentString]++;
		if (rightwrong)
		{
			rightwrong.style.color = "red";
			rightwrong.innerHTML = "Wrong! The answer was "+currentNote
		}
	}
	document.getElementById("qtime").innerHTML = ((Math.round((((new Date()).getTime()) - questionAskedTime)/10)/100)+"s")
	if (rightwrong)
	{
//			rightwrong.style.visibility = "visible";
			$(rightwrong).fadeIn("fast");
//			setTimeout(function(){ document.getElementById("rightwrong").style.visibility="hidden"; PopQuestion(); },2000);
			setTimeout(function(){ $(rightwrong).fadeOut("fast"); PopQuestion(); },2000);
	}
	clearInterval(currentThinkTimeTimerId);
	thinkTime[currentString] += (((new Date()).getTime()) - questionAskedTime);
	UpdateScoreboard();
}




function PlayFret(fret)
{
	var rightwrong;

	if ((gameOn != 2) || (!questionPopped))
	{
		// Nothing to do if there isn't a "Notes" game in progress !
		return;
	}
	questionPopped = false;	// Don't accept another answer until the next question is popped
	PlaceStringMarker(currentString,fret);
	rightwrong = document.getElementById("rightwrong");
	if ((fret % 12) == currentFret)
	{
		rightCount[currentString]++;
		if (rightwrong)
		{
			rightwrong.style.color = "green";
			rightwrong.innerHTML = "Correct!";
		}
	}
	else
	{
		wrongCount[currentString]++;
		if (rightwrong)
		{
			rightwrong.style.color = "red";
			rightwrong.innerHTML = "Wrong! "+currentAskedNote+" is on the "+currentFret+NumberSuffix(currentFret)+" fret of the "+currentString+NumberSuffix(currentString)+" string";
		}
	}
	document.getElementById("qtime").innerHTML = ((Math.round((((new Date()).getTime()) - questionAskedTime)/10)/100)+"s")
	if (rightwrong)
	{
//			rightwrong.style.visibility = "visible";
			$(rightwrong).fadeIn("fast");
//			setTimeout(function(){ document.getElementById("rightwrong").style.visibility="hidden"; PopQuestion(); },2000);
			setTimeout(function(){ $(rightwrong).fadeOut("fast"); PlaceStringMarker(0,0); PopQuestion(); },2000);
	}
	clearInterval(currentThinkTimeTimerId);
	thinkTime[currentString] += (((new Date()).getTime()) - questionAskedTime);
	UpdateScoreboard();
}




function UpdateScoreboard()
{
	var rightTotal=rightCount[1]+rightCount[2]+rightCount[3]+rightCount[4]+rightCount[5]+rightCount[6];
	var wrongTotal=wrongCount[1]+wrongCount[2]+wrongCount[3]+wrongCount[4]+wrongCount[5]+wrongCount[6];
	var thinkTimeTotal=thinkTime[1]+thinkTime[2]+thinkTime[3]+thinkTime[4]+thinkTime[5]+thinkTime[6];
	document.getElementById("right").innerHTML=rightTotal;
	document.getElementById("wrong").innerHTML=wrongTotal;
	document.getElementById("averageTime").innerHTML=(rightTotal+wrongTotal==0)?"0sec":((Math.round(thinkTimeTotal/10/(rightTotal+wrongTotal))/100)+"sec");
}




