
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').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);
			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);
	}

	//expose public API
    return {
        'init':init
    };
}();