//global variables
var lang;
var conjugations = new Array(); //an array of all the Conjugation objects
//define 2 associate array to keep track of which verbs and tenses are enabled
//the key is the name of the verb or tense and the value is true or false
//var verbEnabled = new Array(), tenseEnabled = new Array(); 
//var verbId, tenseId;
var alwaysShowSymbols = false;

var retry = false; //this is true if the user is retrying a missed question (retries do not affect stats)

var verbs = new Array();
var tenses = new Array();

var total_correct = 0; //total number of correct
var total_incorrect = 0; //total number of incorrect

function SpecialCharButtonSet(inputFieldId, containerDivId, specialChars)
{
    //create buttons html
    var html = "";
    for (var i=0; i<specialChars.length; i++){
        var code = "&#" + specialChars.charCodeAt(i) + ";";
        html += "<input class='special_button' id='special_button_" + specialChars.charCodeAt(i) + "' type='button' value='" + code + "' />";
    }
    $("#" + containerDivId).html(html);
    //assign event handlers
    for (var i=0; i<specialChars.length; i++){
        $("#special_button_" + specialChars.charCodeAt(i)).click(function(event){
            var oldVal = $("#" + inputFieldId).val();
            var newChar = String.fromCharCode(parseInt(event.target.id.substr(15))); //chop off "special_button_" to get specialChar index
            $("#" + inputFieldId).val(oldVal + newChar);
            $("#" + inputFieldId).focus();
        });
    }
}

function Conjugation(verb, tense, pronoun, gender, value, sensitive)
{
	this.verb = verb;
	this.tense = tense;
	this.pronoun = pronoun;
	this.gender = gender;
	this.value = value;
	this.number = false;
	this.sensitive = sensitive;
}

function Verb(name)
{
	this.enabled = true;
	this.name = name;
	this.correct = 0;
	this.incorrect = 0;
}

function Tense(name)
{
	this.enabled = true;
	this.name = name;
	this.correct = 0;
	this.incorrect = 0;
}

//chooses a random conjugation from the the enabled Verbs and Tenses
function nextQuestion(){
	//choose conjugation
	//build list of all candidate conjugations, that is those whose verb is enabled and tense is enabled
	var candidates = new Array();
	for (var i=0; i<conjugations.length; i++){
		var verbIndex = findName(verbs,conjugations[i].verb);
		var tenseIndex = findName(tenses,conjugations[i].tense);
		if (verbIndex == -1)
			alert("ERROR: conjugation has a verb not found in verb list.");
		if (tenseIndex == -1)
			alert("ERROR: conjugation has a tense not found in tense list.");
		if (verbs[verbIndex].enabled && tenses[tenseIndex].enabled)
			candidates.push(conjugations[i]);
	}
	if (candidates.length == 0){
		alert("None found. You may need to enable more verbs or tenses.\nCorrect the problem, then type your previous answer again.");
	}else{
		//pick a random conjugation from the candidates list
		currentConjugation = candidates[randInt(candidates.length)];

		$("#english_prompt_span").hide();
		$("#prompt_span").show();
		$("#pronoun_span").text(currentConjugation.pronoun);
		$("#tense_span").text(currentConjugation.tense);
		$("#verb_span").text(currentConjugation.verb);
		
		updateSymbols();
	}
}

function checkResponse(){
    var response = $("#response_field").val();
    $("#response_field").val(""); //clear response field
    if (response == currentConjugation.value){
        $("#feedback_span").text("Correct");
        $("#feedback_span").css("color","#cccccc");
		//only update correct if response was not a retry
		if (!retry){
			verbs[findName(verbs,currentConjugation.verb)].correct++;
			tenses[findName(tenses,currentConjugation.tense)].correct++;
			total_correct++;
		}
		retry = false; //if user is correct, they will not have to retry
        setTimeout("clearFeedback();",1000);
        nextQuestion();
    }else{
        $("#feedback_span").text("Incorrect, please type the correct conjugation: " + currentConjugation.value);
        $("#feedback_span").css("color","#ff0000");
		//only update incorrect if response was not a retry
		if (!retry){
			verbs[findName(verbs,currentConjugation.verb)].incorrect++;
			tenses[findName(tenses,currentConjugation.tense)].incorrect++;
			total_incorrect++;
		}
		retry = true; //if question is missed, user must retry until they get it right
    }
	updateStats();
}

function clearFeedback(){
    $("#feedback_span").text("");
}

function updateStats(){
	for (var i=0; i<tenses.length; i++){
		$("#tense_correct_"+i).text(tenses[i].correct);
		$("#tense_incorrect_"+i).text(tenses[i].incorrect);
		var total = tenses[i].correct + tenses[i].incorrect;
		var percent = (total == 0) ? "" : Math.round((tenses[i].correct / parseFloat(total)) * 100);
		$("#tense_percent_"+i).text(percent); 
	}
	for (var i=0; i<verbs.length; i++){
		$("#verb_correct_"+i).text(verbs[i].correct);
		$("#verb_incorrect_"+i).text(verbs[i].incorrect);
		var total = verbs[i].correct + verbs[i].incorrect;
		var percent = (total == 0) ? "" : Math.round((verbs[i].correct / parseFloat(total)) * 100);
		$("#verb_percent_"+i).text(percent); 
	}
	$("#total_correct").text(total_correct);
	$("#total_incorrect").text(total_incorrect);
	var total = total_correct + total_incorrect;
	var percent = (total == 0) ? "" : Math.round((total_correct / parseFloat(total)) * 100);
	$("#total_percent").text(percent);
}

function createOptions(){
    //create checkbox html
	html = "<br/><table><tr><th rowspan='2'>Total&nbsp;</th>"
		+ "<th><img src='img/correct.png' /></th>"
		+ "<th><img src='img/incorrect.png' /></th>"
		+ "<th>%</th></tr>"
		+ "<tr><td><span id='total_correct'></span></td>"
		+ "<td><span id='total_incorrect'></span></td>"
		+ "<td><span id='total_percent'></span></td>"
		+ "</tr></table>"
    	+ "<br/><table><tr><th>Tense</th>"
		+ "<th><img src='img/correct.png' /></th>"
		+ "<th><img src='img/incorrect.png' /></th>"
		+ "<th>%</th></tr>";
    for (var i=0; i<tenses.length; i++){
        html += "<tr><td><input type='checkbox' checked='checked' id='tense_checkbox_"+i+"'>"+tenses[i].name+"</input></td>"
			+ "<td><span id='tense_correct_"+i+"'></span></td>"
			+ "<td><span id='tense_incorrect_"+i+"'></span></td>"
			+ "<td><span id='tense_percent_"+i+"'></span></td></tr>";
	}
	html += "</table><br/><table><tr><th>Verb</th>"
		+ "<th><img src='img/correct.png' /></th>"
		+ "<th><img src='img/incorrect.png' /></th>"
		+ "<th>%</th></tr>";
    for (var i=0; i<verbs.length; i++){
        html += "<tr><td><input type='checkbox' checked='checked' id='verb_checkbox_"+i+"'>"+verbs[i].name+"</input></td>"
			+ "<td><span id='verb_correct_"+i+"'></span></td>"
			+ "<td><span id='verb_incorrect_"+i+"'></span></td>"
			+ "<td><span id='verb_percent_"+i+"'></span></td></tr>";
	}
	html += "</table>";
    $("#options_div").html(html);
    //assign event handlers
    for (var i=0; i<verbs.length; i++){
        $("#verb_checkbox_"+i).change(function(event){
			var id = parseInt(event.target.id.substr(14));
            verbs[id].enabled = this.checked;
        });
    }
    for (var i=0; i<tenses.length; i++){
        $("#tense_checkbox_"+i).change(function(event){
			var id = parseInt(event.target.id.substr(15));
			tenses[id].enabled = this.checked;
        });
    }
}

//this is called when a new prompt is generated or when user changes symbol show preferences
function updateSymbols(){
	//set gender span
	if (alwaysShowSymbols || currentConjugation.sensitive){
		if (currentConjugation.gender == "m"){
			$("#gender_span").css("color","#6699FF");
			$("#gender_span").text("\u2642");
		}else if (currentConjugation.gender == "f"){
			$("#gender_span").css("color","#FF6666");
			$("#gender_span").text("\u2640");
		}else
			$("#gender_span").text("");
	
		//set number span
		if (currentConjugation.number == false)
			$("#number_span").text("")
		else
			$("#number_span").text("(" + currentConjugation.number + ")");
	}else{
		$("#number_span").text("");
		$("#gender_span").text("");
	}
}

$(document).ready(function(){

    //assign event handlers
    $("#response_field").keyup(function(event){
        if (event.keyCode == 13)
            checkResponse();
    });

	$("input[name=show_symbols]").change(function(event){
		alwaysShowSymbols = ($(this).val() == "always");
		updateSymbols();
	});
    
    //get lang from hidden input field, which was set by php from $_GET["lang"]
    lang = $("#lang").val();
    
    //create special buttons
    new SpecialCharButtonSet("response_field", "special_buttons_div", 
        "\u00E0\u00E2\u00E4\u00E9\u00E8\u00EA\u00EB\u00EE\u00EF\u00F4\u00F6\u00F9\u00FB\u00FC\u00FF\u00E6\u0153\u00E7");
        
    $.get("fra4.xml", {}, function(xml){
        //parse each Verb tag
        $("Verb",xml).each(function(){
            var verb = $(this).attr("name");
			//add verb to verbs
			verbs.push(new Verb(verb));
            //parse each Tense tag
            $("Tense",this).each(function(){
                var tense = $(this).attr("name");
				//add tense to tenses if it hasn't already been added
				if (findName(tenses,tense) == -1)
					tenses.push(new Tense(tense));
                //parse each Pronoun tag
                $("Pronoun",this).each(function(){
                    var pronoun = $(this).attr("name");
                    var value = $("Conjugation",this).text();
                    var gender = $("Gender",this).text();
					var sensitive = ($("Sensitive",this).text() == "true");
                    var c = new Conjugation(verb, tense, pronoun, gender, value, sensitive);
                    if ($(this).find("Number").length > 0)
                        c.number = $("Number",this).text();
                    conjugations.push(c);
                });
            });
        });
        nextQuestion(); //generate first question
        createOptions(); //create options / stats tables
		updateStats();
    });
});

//returns a random integer >= 0 and less than limit
function randInt(limit){
	return Math.floor(Math.random() * limit);
}

//searches through a collection of objects, returns the index of the first
//object with a name property equal to tgt or -1 if not found
function findName(collection, tgt){
	var index = -1;
	for (var i=0; i<collection.length; i++){
		if (collection[i].name == tgt){
			index = i;
			break;
		}
	}
	return index;
}
