
var tester = function () {

    var testSessionId;
	var wordsById;
	
	var currentTestList;//list of word ids
	var numRight;
	var numWrong;
	
    var currentWordId;
    var showingPrompt;
    
    var stats;//shown at the end of the test session
    
    var showStatusInterval = null;

    function init(id, words) {
        testSessionId = id;
		stats = {
			'testSessionId': id,
			'startTime': (new Date()).getTime(), 
			'endTime': null,
			'wordsById': {},
			'numRight': 0,
			'numWrong': 0
		};
		
		wordsById = {};
		currentTestList = [];
		for(var i = 0; i < words.length; i++) {
			stats.wordsById[words[i]['id']] = {'word': words[i]['word'], 'gotWrong':false};
			wordsById[words[i]['id']] = words[i]['word'];
			currentTestList.push(words[i]['id']);
		}
						
        showingPrompt = false;
        
		//unbind anything that was setup from a previous session
        $('#input').unbind('keypress', input_keydown);
        $('#checkword').unbind('click', submitGuess);
		//rebind
        $('#input').bind('keypress', input_keydown);
        $('#checkword').bind('click', submitGuess);
       
		$('#input').val('');
		$('#input').focus();
        nextWord();
        
        showStatusInterval = setInterval(showStatus, 1000);
    }
    
    function nextWord() {
		//if we have more words
        if(currentTestList.length > 0) {
			//get and remove one of the ids from the current list
            currentWordId = currentTestList.splice(Math.floor(Math.random() * currentTestList.length), 1)[0];
            showPrompt();
        } else { //done
			stats.endTime = (new Date()).getTime();
			clearInterval(showStatusInterval);
			showSessionDetails();
			endTestSession(stats);
        }
    }
    
    function showPrompt() {
		var currentWord = wordsById[currentWordId];
		showingPrompt = true;
		
		$('#prompt').html(currentWord);
    }
	
    function hidePrompt() {
        $('#prompt').html('&nbsp;');
        showingPrompt = false;
        $('#input').css('backgroundColor', '#fff');//TODO: remove?
    }
    
    function input_keydown(e) {
		if (e.keyCode == 13 || e.keyCode == 10) {
			if($('#input').val() != "") {
				submitGuess();
			}
		} else if (showingPrompt) {
			showingPrompt = false;
			hidePrompt();
		}
    }
	
	function submitGuess() {
		var guess = $('#input').val();
		guess = jQuery.trim(guess);
		guess = guess.toLowerCase();
		if(guess == wordsById[currentWordId].toLowerCase()) {
			stats.numRight += 1;
			logTestResult(testSessionId, currentWordId, true);
		} else { //got it wrong
			stats.numWrong += 1;
			stats.wordsById[currentWordId].gotWrong = true;
			logTestResult(testSessionId, currentWordId, false, $('#input').val());
		}
		
		showStatus();		
		
		nextWord();
		$('#input').val('');
	}
	
	function showStatus() {
		var now = (new Date()).getTime();
		var sec = Math.round((now - stats.startTime) / 1000);
		$("#test_timer").text(secToHHMMSS(sec));
		$("#test_num_remaining").text(currentTestList.length);
		$("#test_num_right").text(stats.numRight);
		$("#test_num_wrong").text(stats.numWrong);
	}
	
	

	function showSessionDetails() {
		var score = ((stats.numRight / (stats.numRight + stats.numWrong)) * 100);
		$('#test_score').text(score + "%");
	
		var elapsedSec = Math.round((stats.endTime - stats.startTime) / 1000);
		$('#test_time_sec').text(secToHHMMSS(elapsedSec));
		
		var sortedWords = [];
		var wordToId = {};
		for(var id in stats.wordsById) {
			if(typeof id == "string") {
				sortedWords.push(stats.wordsById[id].word);
				wordToId[stats.wordsById[id].word] = id;
			}
		}
		sortedWords.sort();
		
		var correctWords = [];
		var incorrectWords = [];
		for(var i = 0; i < sortedWords.length; i++) {
			var word = sortedWords[i];
			var id = wordToId[word];
			if(stats.wordsById[id].gotWrong) {
				incorrectWords.push(word);
			} else {
				correctWords.push(word);
			}
		}
		
		var wordsTable = "<table border='1' cellspacing='0' cellpadding='2'>";
		wordsTable += "<tr><th> Correct </th><th> Incorrect </th></tr>";
		for(var i = 0; i < correctWords.length || i < incorrectWords.length; i++) {
			wordsTable += "<tr><td>";
			if(i < correctWords.length)
				wordsTable += "<a target=\"dict\" title=\"Define\" href=\"http://www.google.com/dictionary?aq=f&langpair=en|en&q=" + correctWords[i] + "\">" + correctWords[i] + "</a>";
			wordsTable += "</td><td style='color:red'>";
			if(i < incorrectWords.length)
				wordsTable += "<a target=\"dict\" title=\"Define\" href=\"http://www.google.com/dictionary?aq=f&langpair=en|en&q=" + incorrectWords[i] + "\">" + incorrectWords[i] + "</a>";
			wordsTable += "</td></tr>";
		}
		wordsTable += "</table>";
		
		$('#test_words').html(wordsTable);
	}

	//expose public API
    return {
        'init':init
    };
}();
