

$(document).ready(function()
{
	var typeIDs = [1];

	$('#menu ol li').click(menu.click);

	if($.cookie('typeIDs') != null)
		typeIDs = $.cookie('typeIDs').split(',');
	else
		showAlert('You can select different practice problems by clicking the "Settings" link below', 10000);
	
	question.setDefaultTypeIDs(typeIDs); // this doesn't work if the events aren't attached
	menu.save();
	question.get(); // needs typeIDs to be set
	stats.startTimer();
	
	// this also runs for stupid IE
	// <body onfocus="question.focus()">
});

var question = {
	
	answer : [],
	typeIDs : [],
	
	// watch for slow HTTP requests
	timeoutID : 0, 
	error : false,
	wait_time : 5000,
	busy : false,
	
	get : function()
	{
		this.timeoutID = setTimeout(function()
		{
			showAlert('The connection is slower than normal. <a href="#" onclick="question.get()">Click here</a> to retry.', -1);
			question.error = true;
		}, this.wait_time);
			
		var typeID = question.getTypeID(); // find a random typeID
		// fetch the problem
		$.get('/categories/' + urls[typeID] + '&no_cache=' + Math.random(500), function(data)
		{
			// the data is split up on a semi colon
			var parts = question.decode(data);
			
			question.answer = parts[0];
			$('#problem').html(parts[1]).show();
			question.focus();
			
			// stop the error message from slowing because of bad connection
			clearTimeout(question.timeoutID);
			
			// if there was an error, hide it now
			if(question.error)
				hideAlert();
			question.error = false;
			
			// the question has been graded, so unlock the grade function
			question.busy = false;

		});
	},

	grade : function()
	{
		// no answer
		if($('#input').val().length == 0 || this.busy)
			return false;
		
		// prevent the answer from being submitted multiple times
		this.busy = true;
		
		// don't want to see the problem box anymore
		$('#problem').hide();
		
		var correct = this.isCorrect();
		if(correct) // show correct box, and get new question
		{		
			$('#correct').fadeIn(350, function()
			{
				question.get();
				$('#correct').hide();
			});
		}
		else // tell them they're wrong
		{
			$('#correct-answer').text(this.answer[0]); // set the correct answer
			$('#incorrect').fadeIn(1500, function() // show message
			{
				$('#incorrect').hide();
				question.get();
			});
		}
		
		stats.updateScore(correct);
		
		return false; // so the form doesn't submit
	},
	
	isCorrect : function()
	{
		var user_answer = $('#problem input').val();
		for(var i = 0; i < this.answer.length; i++)
		{
			if(this.answer[i] == user_answer)
				return true;
		}
		return false;
//		return (this.answer.indexOf(parseInt($('#problem input').val())) != -1);
	},
	
	// no longer useful
	toggleTypeID : function(value)
	{
		var index = question.typeIDs.indexOf(value);
		if(index == -1)
		{
			// put in typeIDs
			question.typeIDs.push(value);
		}
		else
		{
			question.typeIDs.splice(index);
		}
		
		return index;
	},
	
	addTypeID : function(value)
	{
		question.typeIDs.push(value);
	},
	
	getTypeID : function()
	{
		// this should never happen
		if(question.typeIDs.length == 0)
			alert('You need to select some categories!');
		
		// get a random typeID
		return this.typeIDs[Math.floor(Math.random() * this.typeIDs.length)];
	},
	
	// the data is seperated on colon
	decode : function(data)
	{
		//var parts = data.split(':', 2);
		//alert(parts);
		//return [eval('(' + parts[0] + ')'), parts[1]];
		var i = data.indexOf(":");
		return [eval(data.substring(0, i)), data.substring(i + 1)];
	},
	
	// mark all the defaults
	setDefaultTypeIDs : function(typeIDs)
	{
		for(var i = 0; i < typeIDs.length; i++)
		{
			$('#t-' + typeIDs[i]).click();
		}
	},
	
	focus : function()
	{
		$('#input').focus();
		$('#input').select();		
	}
}

var stats = {
	
	correct : 0,
	total : 0,
	
	longest_run : 0,
	current_run : 0,
	
	seconds : 0,
	minutes : 0,
	
	formatTime : function(sec, min)
	{
		var padding = "";
		
		if(sec < 10)
			padding = "0";
		
		return min + ":" + padding + sec;
	},
	
	startTimer : function()
	{
		setInterval(function(){ 
			var padding = "";
			if(stats.seconds == 59)
			{
				stats.seconds = 0;
				stats.minutes++;
			}
			else
				stats.seconds++;
				
			if(stats.seconds < 10)
				padding = "0";

			$('#time').text(stats.formatTime(stats.seconds, stats.minutes)) 
		}, 1000);
	},
	
	updateScore : function(is_correct)
	{
		this.total++;
		
		if(is_correct)
		{
			this.correct++;
			this.current_run++;
		}
		else
			this.current_run = 0;
			
		$('#score').text(this.correct + '/' + this.total + " (" + Math.round(this.correct/this.total * 100) + "%)");
		
		if(this.current_run > this.longest_run)
		{
			$('#longest-run').html(this.current_run);
			this.longest_run = this.current_run;
		}
	},
	
	print : function(element)
	{
		var score = stats.correct + "/" + stats.total;
		var time = this.formatTime(stats.seconds, stats.minutes)
		$(element).attr('href', 'print.php?score=' + score + '&time=' + time + "&longest_run=" + stats.longest_run);
		alert($(element).attr('href'));
		return true;
	}
	
	
}

var menu = {

	is_visible : false,
	
	toggle : function()
	{
		help.hide(); // should wait until this transition is complete, oh well
		if(this.is_visible)
		{
			if(menu.save())
			{				
				// slide up
				$('#menu').slideUp('fast', function()
				{
					//question.get();
					$('#content').slideDown('fast', function(){ menu.is_visible = false;});
					question.get();
					//question.focus()					
				});
			}
			else
				alert('Please select at least one category');
		}
		else
		{
			//slide the main content up
			$('#content').slideUp('fast', function()
			{
				$('#menu').slideDown('fast', function() { menu.is_visible = true});	
			});
		}
		
		return false; // so the form doesn't submit
	},
	
	hide : function()
	{
		$('#menu').slideUp('fast', function(){ menu.is_visible = false; });
	},

	save : function()
	{
		question.typeIDs = [];
		$('.active').each(function()
		{	
			var typeID = menu.toTypeID($(this).attr('id'));
			question.addTypeID(typeID);
		});

		$.cookie('typeIDs', question.typeIDs.join(','), {'expires' : 7});
		return (question.typeIDs.length != 0);
	},
	
	click : function(e)
	{
		$(this).toggleClass('active');
	},
	
	// split up a categories id into a typeID
	toTypeID : function(id)
	{
		return parseInt(id.split('-')[1]);
	}
}

var help = {
	is_visible : false,
	
	toggle : function()
	{
		menu.hide();
		if(this.is_visible)
		{
			// slide up
			$('#help').slideUp('fast', function()
			{
				$('#content').slideDown('fast', function(){ help.is_visible = false});
			});
		}
		else
		{
			//slide the main content up
			$('#content').slideUp('fast', function()
			{
				$('#help').slideDown('fast', function() { help.is_visible = true});	
			});
		}
	},
	
	hide : function()
	{
		$('#help').slideUp('fast', function(){ help.is_visible = false; });
	}

}

function showAlert(message, timeout)
{
	$('#alert').slideDown('slow');
	$('#message').html(message);
	if(timeout != -1)
		setTimeout(function(){ $('#alert').slideUp('slow')}, timeout);
}

function hideAlert()
{
	$('#alert').slideUp('slow');	
}

if (!Array.prototype.indexOf)
{
  Array.prototype.indexOf = function(elt /*, from*/)
  {
    var len = this.length >>> 0;

    var from = Number(arguments[1]) || 0;
    from = (from < 0)
         ? Math.ceil(from)
         : Math.floor(from);
    if (from < 0)
      from += len;

    for (; from < len; from++)
    {
      if (from in this &&
          this[from] === elt)
        return from;
    }
    return -1;
  };
}