/*** UTILITY FUNCTIONS ***/

//used for inheritance
if (typeof Object.create !== 'function') {
	Object.create = function (o) {
		function F() {}
		F.prototype = o;  
		return new F();  
	};
}

getIEVersion = function(){
	var rv = -1; // Return value assumes failure.
	if (navigator.appName == 'Microsoft Internet Explorer'){
		var ua = navigator.userAgent;
		var re  = new RegExp("MSIE ([0-9]{1,}[\.0-9]{0,})");
		if (re.exec(ua) != null)
		rv = parseFloat( RegExp.$1 );
	}
	return rv;
};

var getKeyCode = function(e){
	if(document.all){ return window.event.keyCode;}
	else{return e.which;}
};

var padZero = function(num){
	if(num===0){return "00";}
	if(num< 10){return "0"+num;}
	return ""+num;
};

String.prototype.getMatchString = function(){
	switch(q.matchMode){
		case 1:
			return this.toUpperCase().replace(/[^A-Z0-9]/g,"");
		case 2:
			var m = this.trim();
			m = m.toUpperCase().replace(/[^A-Z0-9 ]/g,"");
			m = m.replace(/[ ]+/g," ");
			return m;
		default:
			return this.toUpperCase().replace(/[^A-Z0-9]/g,"");
	}
};

String.prototype.trim = function(){
	return this.replace(/^\s+|\s+$/g,"");
};

/*** GLOBAL FUNCTIONS ***/

// animate from green to white
var animate = function(x, level){
    var decColor = (255-level) + 256 * 255 + 65536 * (255-level);
	document.getElementById(x).style.backgroundColor = "#" + decColor.toString(16);
	if ( level > 0 ) {
		setTimeout( function() { animate(x,level-6); }, 40 );
	}
};

var oneSecond = function(){
	q.decrementClock(); 
	if ( !q.done ) {
		setTimeout( oneSecond, 1000 );
	}
};

var typing = function(e){
	q.typing(e); 
};

var showAnswersNext = function(){
	q.setResults();
};

var showAnswers = function(){
	$("#askBox").hide();
	showAnswersNext();
};

var showAnswersFinal = function(){
	$("#quiz .scrollable").css("overflow", "visible");
	$("#quiz .scrollable").css("height", "auto");
	$("#controls").hide();
	$("#postGameControls").show();
	$("#overlay").hide();
	q.drawCells();
	statsW.launch();
	q.drawSuggested();
};

/***  QUIZ CLASS ***/
var Quiz = function(){
	this.done = false;
	this.numGuessed = 0;
	this.numAnswers = 0;

	//for image quizzes
	this.iCells = null;

	//stats
	this.timesTaken = -1;
	this.sumOfScores = -1;
	this.userTaken = -1;
	this.userHigh = -1;

	//for resending verification e-mail
	this.verifyCode = "";

	//custom loading function 
	this.specialLoad = null;

	this.suggested = new Array();

	this.matchMode = 1;

	this.init = function(){
		this.mapAnswersToCells();
		for (var i in this.answers ) {
		    if ( this.answers.hasOwnProperty(i) ) {
				this.numAnswers++;
			}
		}
		$("#txtUser").attr("disabled", "");
		this.updateNumGuessed();
		this.drawClock();
		if ( this.bigImages != null ) {
			for (var i=0; i<this.bigImages.length; i++)
			{
				var bi = this.bigImages[i];
				$("#" + bi.div).click(
					function() {
						displayBigImage( $(this).attr('id') );
					}
				);
			}
		}
		if ( this.specialLoad != null ) {
			q.specialLoad();
		}
		setTimeout( oneSecond, 1000 );
	};

	this.typing = function(e)
	{
		var txt = $("#txtUser").val().getMatchString();
		var foundMatch = false;
		var code = getKeyCode(e);
		var alreadyGuessed = [];
		$("#alreadyGuessed").hide();
		for (var i in this.answers )
		{
			if ( this.answers.hasOwnProperty(i) ) {
				var a = this.answers[i];
				if ( a.answered && code != 13 ) {
					continue;
				}
				if ( a.isMatch(txt) )
				{
					if ( a.answered && code == 13 ) {
						alreadyGuessed.push( a.displayText[0] );
						continue;
					}
					a.answered = true;
					foundMatch = true;
					a.drawCells();
					this.numGuessed++;
					this.updateNumGuessed();
					if ( this.numGuessed == this.numAnswers ) {
						this.finish();
					}
				}
			 }
		}
		if ( foundMatch ) {
			$("#txtUser").val("");
		}
		else if ( code == 13 )
		{
			if ( alreadyGuessed.length > 0 ) {
				$("#alreadyGuessed").html( alreadyGuessed.join(", ") + " ist bereits eingetragen.");
			}
			else if ( txt != "" ) {
				$("#alreadyGuessed").html( "Die Antwort " + $("#txtUser").val() + " ist leider falsch.");
			}
			$("#alreadyGuessed").show();
		}
	};

	this.mapAnswersToCells = function()
	{
		for (var i in this.cells)
		{ 
			if ( this.cells.hasOwnProperty(i) ) {
				var c = this.cells[i];
				if ( c.answerId != "" ) {
					c.answer = q.answers[ c.answerId ];
					c.answer.cells.push( c );
				}
			}
		}
	};

	this.decrementClock = function()
	{
		if ( this.done ) {
			return;
		}
		this.seconds--;
		this.drawClock();
		if ( this.seconds === 0 ) {
			this.finish();
		} 
	};

	this.drawClock = function()
	{
		var s = this.seconds % 60;
		var m = ( this.seconds - s ) / 60;
		$("#timer").html( m + ":" + padZero(s) );
	};

	this.updateNumGuessed = function()
	{
		$("#numGuessed").text( this.numGuessed + "/" + this.numAnswers + " guessed" );
	};

	this.finish = function()
	{
		$("#giveUp").html("");
		$("#txtUser").attr("disabled", "disabled");
		this.done = true;
		$("#overlay").show();
		$("#askBox").show();
	};

	this.setResults = function()
	{
		$("#overlay").show();
		$("#loading").show();

		var x = [];
		for ( var i in q.answers )
		{
			if ( q.answers.hasOwnProperty(i) ) {
				var a = q.answers[i];
				if ( a.answered ) {
					x.push( a.id + ":1" );
				}
				else {
					x.push( a.id + ":0" );
				}
			}
		}
		cereal = x.join(";");

		$.post("stats.php", { quiz: q.id, timeLeft: q.seconds, guesses: cereal },
			function(data){
				$("#loading").hide();
				var lines = data.split("\n");

				if ( lines[0] == "200" ) {
					q.readStats(lines);
					showAnswersFinal();
				}
				else {
					alert("Error. " + data);
					$("#overlay").hide();
				}
			});
	};


	this.readStats = function(lines)
	{
		for (var i=1; i<lines.length; i++)
		{
			var x = lines[i].trim();
			if ( x == "" ) {
				continue;
			}
			var tabs = x.split("\t");
			switch ( tabs[0] )
			{
				case "QUIZ":
					this.timesTaken = parseInt(tabs[1],10);
					this.sumOfScores = parseInt(tabs[2],10);
					if ( this.numGuessed === 0 ) {
						this.percentile = 0;
					}
					else if ( this.numGuessed == this.numAnswers ) {
						this.percentile = 100;
					}
					else {
						var better = parseInt(tabs[3],10);
						this.percentile = 100-(((this.timesTaken-better)*100)/this.timesTaken);
						this.percentile = this.percentile.toFixed(1);
					}
					break;
				case "ANSWER":
					var id = tabs[1];
					var a = this.answers[id];
					a.timesGuessed = parseInt(tabs[2],10);
					a.userGuessed = parseInt(tabs[3],10);
					break;
				case "SUGGESTED":
					//this.suggested.push( new SuggestedQuiz(tabs[1],tabs[2],tabs[3],tabs[4]) );
					break;
			}
		}
	};

	this.drawCells = function()
	{
		for (var i in this.cells)
		{ 
			if ( this.cells.hasOwnProperty(i) ) {
				this.cells[i].draw();
			}
		}
	};

	this.preloadMapCells = function()
	{
		for (var i in this.cells)
		{ 
			if ( this.cells.hasOwnProperty(i) ) 
			{
				var c = this.cells[i];
				var i1 = new Image();
				i1.src = "/quizzes/img/quiz-img/" + c.fN;
			}
		}
	};

	this.drawSuggested = function()
	{
		if ( this.suggested.length == 0 ) {
			return;
		}
		var html = new Array();
		for (var i=0; i<this.suggested.length; i++)
		{
			var s = this.suggested[i];
			html.push( "<div class='sugQuiz'>" );
			html.push( "<div class='a'><a href='/quizzes/" + s.fileName + "'><img src='/quizzes/img/sm-thumbs/" + s.thumb + "'></a></div>" );
			html.push( "<div class='b'>");
			html.push( "<div class='x'><a href='/quizzes/" + s.fileName + "'>" + s.linkText + "</a></div>");
			html.push( "<div class='y'>" + s.instructions + "</div>");
			html.push( "</div>" );
			html.push( "</div>" );
		}
		$("#sugBody").html( html.join('') );
		$("#sug").show();

	};
};

/*** CELL CLASS ***/
var Cell = function(id, answerId){
	this.id = id;
	this.answerId = answerId;
	this.answer = null;
};

Cell.prototype = {
	draw: function() {
		alert( "drawParent: " + this.answerId);
	},
	standardDraw: function(col)
	{
		var x = "#" + this.id;
		$(x).html( this.answer.displayText[ col ] );
		if ( this.answer.answered ) {
			$(x).addClass("correct");
		}
		else {
			$(x).addClass("incorrect");
		}
		if ( !q.done ) {
			animate(this.id, 96);
		}
	}
};

//normal cell
var ACell = function(id, answerId){
	Cell.apply(this, [id, answerId] );  
};
ACell.prototype = Object.create(Cell.prototype);  
ACell.prototype.draw = function(){
	this.standardDraw(0);
};


var Answer = function(id, displayText, matchText){
	this.id = id;
	this.displayText = displayText;
	this.matchText = matchText;
	this.answered = false;
	this.cells = [];

	this.timesGuessed = -1;
	this.userGuessed = -1;

	this.drawStatRow = null;

	this.isMatch = function(txt)
	{
		for (var i=0; i<this.matchText.length; i++) 
		{
			if ( txt.match(this.matchText[i]) ) {
				return true;
			}
		}
		return false;
	};

	this.drawCells = function()
	{
		for (var i in this.cells)
		{ 
			if ( this.cells.hasOwnProperty(i) ) {
				this.cells[i].draw();
			}
		}
	};
};

Answer.cmp = function(a, b){
	if ( a.answered && !b.answered ) {
		return -1;
	}
	else if ( b.answered && !a.answered ) {
		return 1;
	}
	else if ( a.timesGuessed > b.timesGuessed ) {
		return -1;
	}
	else if ( a.timesGuessed < b.timesGuessed ) {
		return 1;
	}
	return 0;
};

var StatsWindow = function(){
	this.answers = null;
	this.data = null;
	this.headers = [];
	this.template = [];
	this.drawStatRow = StatsWindow.drawStatRow1;

	this.launch = function()
	{
		this.draw();
		this.drawStatBox1();
	};

	this.drawStatBox1 = function()
	{
		var pct = Math.round( (q.numGuessed / q.numAnswers ) * 100);
		var average = 0;
		if ( q.timesTaken > 0 )
		{
			average = Math.floor( q.sumOfScores / q.timesTaken );
		}
		$("#statLine1").html("Sie haben <span class='big'>" + q.numGuessed + "/" + q.numAnswers + "</span> = <span class='big'>" + pct + "</span>%. erreicht");
		$("#statLine2").html("Damit schlagen Sie " + q.percentile + "% aller Teilnehmer.");
		$("#statLine3").html("Der Durchschnitt liegt bei " + average + ".");
		$("#statLine4").hide();
		$("#statBox1").show();
	};

	this.draw = function(){
		this.answers = [];
		for (var i in q.answers) {
			if ( q.answers.hasOwnProperty(i) ) 
			{
				this.answers.push( q.answers[i] );
			}
		}
		this.answers.sort( Answer.cmp );

		var html = [];
		html.push('<table cellpadding="0" cellspacing="0">');
		for (i=0; i<this.headers.length; i++)
		{
			html.push("<th>" + this.headers[i] + "</th>");
		}
		html.push("<th class='a'>Richtige Antworten</th>");
		for (i=0; i<this.answers.length; i++)
		{
			var a = this.answers[i];
			html.push("<tr>");
			if ( a.drawStatRow !== null ) {
				a.drawStatRow(html);
			}
			else {
				this.drawStatRow(a, html);
			}
			html.push( this.getStatBar( a.timesGuessed, q.timesTaken, a.answered ) );
			html.push("</tr>");
		}
		html.push("</table>");
		$("#statsInner").html( html.join('') );
		$("#stats").show();
	};

	this.getStatBar = function( guessed, taken, correct ){
		var pct = 0;
		if ( taken !== 0 ) {
			pct = Math.floor( (guessed/taken) * 100 );
		}
		var c;
		if ( correct ) {
			c = "correct";
		} else {
			c = "incorrect";
		}
		return '<td><div class="pct ' + c + '">' + pct + '%</div><div class="bout"><div class="bar b' + c + '" style="width: ' + pct + 'px;"></div></div></td>';
	};
};

// default stat row
StatsWindow.drawStatRow1 = function(a, html){
	for (var i=0; i<this.template.length; i++){
		html.push( "<td>" + a.displayText[ this.template[i] ] + "</td>");
	}
};

var statsW = new StatsWindow();


function load() {}

$(document).ready(function() {
	var x = getIEVersion();
	if ( x > 0 && x < 7 )
	{
		$("#lowIe").show();
	}
	q.init();
	$("#btnShowAnswers").click( function() { showAnswers(); } );
	$("#btnRetake").click( function() { window.location.reload(); } );
});



