document.write("<div id='jsocket_div'></div>");
document.write("<div id=flivia_log></div>");


function initialize_interface()
{
	$("<div id=gamewrapper></div>").load("/game.html?" + Math.random(),function(){
			send("/roominfo");
			$("#inputfield").keypress(
				function(key){
					switch(key.keyCode)
					{
						case(10):
						case(13):
						case(9):
							send(this.value);
							this.value="";
					}
				});
			input_focus();
			do_rounded_shadows();
		}).appendTo("body");
}

function input_focus()
{
	$("#inputfield").focus();
}



function loadjscssfile(filename)
{
	if (filename.match(/\.js$/i)){ //if filename is a external JavaScript file
		var fileref=document.createElement('script')
		fileref.setAttribute("type","text/javascript")
		fileref.setAttribute("src", filename)
	}
	else if (filename.match(/\.css$/i)){ //if filename is an external CSS file
		var fileref=document.createElement("link")
		fileref.setAttribute("rel", "stylesheet")
		fileref.setAttribute("type", "text/css")
		fileref.setAttribute("href", filename)
	}
	if (typeof fileref!="undefined")
		document.getElementsByTagName("head")[0].appendChild(fileref)
}


$(document).ready(function(){
	var js_to_load = ["/flivia.css",
			"/js/swfobject.js",
			"/jsocket/src/jsocket.js",
			"/jsocket/src/jquery.socket.js"];

	for(i=0;i<js_to_load.length;i++)
	{
		loadjscssfile(js_to_load[i]);
	}
});


var _mode = [];
function set_init_mode(type,value)
{
	type = type.toUpperCase();
	return _mode[type] = value;
}

function get_init_mode(type)
{
	type = type.toUpperCase();
	var val = _mode[type];
	_mode[type] = null;
	return val;
}


var f;
//$(window).load(function(){
function start_flivia(Context)
{
	$(Context).append("<div id='jsocket_div'></div><div id=flivia_log></div>");
	$("#content").hide();
	$("#footer").hide();


	f = new jSocket();
	f.onReady = 
		function() {
			log("socket ready, attempting to connect");
			f.connect(location.hostname,8599)
		};

	f.onConnect =
		function(success,data) {
			if(!success)
				log("There was a problem connecting: " + data);
			else
				log("Connected");
		};

	f.onData =
		function(data) {
			log("&lt;&lt; " + data);

			data_handler(data);
		};
	f.onClose =
		function() {
			alert("Connection Closed");
			log("conn closed");
		};

	f.setup("jsocket_div","/jsocket/flash/jsocket.swf");
//});
}


function close()
{
	f.close();
}

function log(s)
{
	$("#flivia_log").append(s + "<br />").scrollTo("max");

}

function chomp(raw_text)
{
	return raw_text.replace(/[\n\r]+$/, '');
}

function decode_helper(m)
{
	// can't use typical regular expressions because they will replace eachother
	var slashes = m.split(/\\\\/);
	for(var i=0;i<slashes.length;i++)
		slashes[i] = slashes[i].replace(/\\n/g,"\n");
	return slashes.join("\\");
}

function decode_packet(msg)
{
	//alert(msg);
	decoded = [];
	msgs = msg.split(/[\r\n]+/);
	for(var i=0;i<msgs.length;i++)
	{
		if(msgs[i].length > 0)
			decoded.push(decode_helper(msgs[i]));
	}
	return decoded;
}

function encode_packet(msg)
{
	return msg.replace(/\\/g,"\\\\")
		.replace(/[\r\n]+/g,"\\n") + "\n";
}

function send(msg)
{
	if(msg.length>0)
	{
		msg = encode_packet(msg);
		f.write(msg);
		log("&gt;&gt; " + msg);
	}
}

function data_handler(data)
{
	//alert(data);
	data = chomp(data);
	if(data.match(/\?$/))
	{
		no_q = data.toUpperCase().replace(/\?$/,"");
		switch(no_q)
		{
			case("HELLO"):
				send("HELLO flivia.js 0.01");
				return;
			case("SECID_OR_PW"):
				send("SECID_OR_PW SECID");
				return;
			case("ROUNDS"):
				send("ROUNDS 20");
				return;
			case("SECID"):
			case("CREATE_OR_JOIN"):
			case("CATID"):
			case("ROOM"):
				value = get_init_mode(no_q);
				if(value==null)
				{
					alert("No Response for " + no_q);
					return; //exit function early
				}
				else
					send(no_q + " " + value);
				return; // exit function early
		}
	}

	switch(data)
	{
		case("OK"):
			break;
		default:
			packets = decode_packet(data);
			for(var i=0;i<packets.length;i++)
				advanced_data_handler(packets[i]);
	}

}


var popup_timer = null;
function popup_notify(msg,color)
{
	if(color==undefined)
		popup_notify(msg,"black");
	else
	{
		var div = $("<span></span>").text(msg).css("color",color).append("<br />");
		if(popup_timer)
		{
			clearTimeout(popup_timer);
		}
		else
		{
		}

		$("#popuptext").append(div);
		$("#popupnotifier").vAlign().show();

		popup_timer = setTimeout(function(){
				$("#popupnotifier").fadeOut();
				$("#popuptext").html("");
				//$("#popuptext").html();
			},3000);
		
	}
}

function say(msg,classname)
{
	id = Math.floor(Math.random()*100000000);
	$("<div id=" + id + "></div>")
		.text(msg)
		.addClass(classname)
		.css("font-size","20pt")
		.appendTo("#chatwrapper")
		.delay(12000)
		.animate({fontSize:"11pt"},1000);
	$("#chatwrapper").scrollTo("max");
}

function flag_link(qid)
{
	id = Math.floor(Math.random()*100000000);
	$("<div id=" + id + "></div>")
		.html("<a href='javascript:flag_popup(" + qid + ")'>[Report something wrong with this question]</a>")
		.addClass("flag")
		.appendTo("#chatwrapper")
	$("#chatwrapper").scrollTo("max");
}

function flag_popup(qid)
{
	id = "flag" + qid;
	$("<div id=" + id + " class=flagpopup>Briefly describe what's wrong with this question and/or answer<br /><input type=text id='" + id + "_text' class=flagtext><input type=button value='Submit' onclick=\"send_flag('" + qid + "','" + id + "')\"><input type=button value='Cancel' onclick=\"cancel_flag('" + id + "')\" /><div class=flagnotifier></div></div>")
		.css("display","none")
		.appendTo("body")
		.fadeIn();

}



function cancel_flag(id)
{
	$("#" + id).fadeOut(300,function(){$(this).remove()});
}

function flag_notifier(divid,msg)
{
	$("#" + divid + " div.flagnotifier").text(msg).fadeIn(200);
}

function send_flag(qid,divid)
{
	desc = $("#" + divid + "_text").val();
	desc = desc.replace(/^\s+|\s+$/g,"");
	if(desc.length==0)
		flag_notifier(divid,"Please enter a description of the problem");
	else
	{
		send("/flag " + qid + " " + desc);
		cancel_flag(divid);
	}
}


function set_question(q)
{
	$("#questiontext").hide().text(q).fadeIn();
	input_focus();	
}

function class_safe(s)
{
	return s.toLowerCase();
}

var _correct = [];
function set_correct(name,amount)
{
	_correct.push(name);
	
	for(var i=0;i<_players.length;i++)
		if(_players[i].name==name)
			_players[i].score += parseFloat(amount);


	_players = sort_player_array(_players);
	redraw_playerlist();
}

function mark_correct(name)
{
	classname = class_safe(name);
	$("#playerlist .player ." + classname)
		.addClass("correct");
}



function remark_correct()
{
	for(var i=0;i<_correct.length;i++)
		mark_correct(_correct[i]);
}

function clear_correct()
{
	$("#playerlist .player .playername").removeClass("correct");
	_correct = [];
}

// playerlist data comes as "Name(Score),Name2(Score2)"
// ie: Chops:30,Fries:25,Taadan:15.5
// Names are not expected to come in order of score (highest score first)
// Returns the array of players
function build_playerlist(raw)
{
	build_player_array(raw);
	redraw_playerlist();
}

function redraw_playerlist()
{
	var str = "<div class=playerheader>Players:</div>";

	for(var i=0;i<_players.length;i++)
	{
		str += "<div class=player><div class=score>" + _players[i].score + "</div><span class='playername " + class_safe(_players[i].name) + "'>" + _players[i].name + "</span></div>";
	}

	$("#playerlist").html(str);
	remark_correct();
}

function sort_player_array(players)
{
	players.sort(function(a,b){
		return b.score - a.score;
	});
	return players;
}

var _players = [];
// returns the list of players, sorted
function build_player_array(raw)
{
	_players = [];
	names_scores = raw.split(",");
	for(var i=0;i<names_scores.length;i++)
	{
		var ns_split = names_scores[i].split(/:/);
		var name = ns_split[0];
		var score = parseFloat(ns_split[1]);
		_players.push({name:name,score:score});
	}
	_players = sort_player_array(_players);
	return _players;
}

//returns a list of winners
function find_winners()
{
	var max=0;
	for(var i=0;i<_players.length;i++)
		if(_players[i].score > max)
			max = _players[i].score;

	var winners = [];
	for(i=0;i<_players.length;i++)
		if(_players[i].score==max)
		{
			winners.push(_players[i].name);
		}
	return winners;
}


function game_over(raw)
{
	build_playerlist(raw);
	winners = find_winners();

	say("Game Over!","gameover");
	playsnd("gameover");


	var msg = "";
	if(winners.length==1)
		msg = winners[0] + " won the game!";
	else if(winners.length==2)
		msg = "It was a tie! " + winners.join(" and ") + " were the winners";
	else if(winners.length>2)
		msg = "It was a " + winners.length + "-way tie between the following players: " + winners.join(", ");
	say(msg,"winner");

	$("#questiontext").addClass("gameover").html("<div class=gameover>Game Over!</div><div class=winners>" + msg + "</div>");
}


function start_game()
{
	send("/start");
}

function button(text,js)
{
	msg = "<div class=button onclick=\"" + js + "\"><div class=buttonouter><div class=buttonmiddle><div class=buttonshadow>" + text + "<div class=buttontext>" + text + "</div></div></div></div></div>";
	return msg;
}

function enable_start_button()
{
	txt = button("Start Game","start_game()");

	$("#countdown").html(txt);
}


function set_gamename(gamename)
{
	$("#gamename").text(gamename);
}

function already_correct()
{
	say("You already got it right. Great job, though, your fervor is appreciated!","alreadycorrect");	
}

function set_gamecategory(cat)
{
	$("#gamecategory").text(cat);
}

var _roundtimelimit = 0;
var _curcount = 0;
var _countdowntimer;
function set_roundtimelimit(t)
{
	return _roundtimelimit = t;
}

function get_roundtimelimit()
{
	return _roundtimelimit;
}

function start_countdown(countdown)
{
	if(_countdowntimer)
		clearTimeout(_countdowntimer);
	if(countdown)
		_curcount = countdown;
	else
		_curcount = get_roundtimelimit();
	next_countdown();

}

function next_countdown()
{
	$("#countdown").css("font-size","36pt").text(_curcount);
	
	if(_curcount <= 5)
	{
		$("#countdown").css("color","#ff0000");
		if(_curcount >= 1)
			playsnd("warning");
	}
	else
	{
		$("#countdown").css("color","#000000");
	}


	if(_curcount>=1)
		_countdowntimer = setTimeout(next_countdown,950);
	else
	       _curcount = 1;	
	_curcount--;
}

function end_countdown()
{
	clearTimeout(_countdowntimer);
}

var _myname;
function whoami(name)
{
	_myname = name;
}

function myname()
{
	return _myname;
}

function format_right_users(names)
{
	var str = "";
	var arr = names.split(/,\s*/);
	for(var i=0;i<arr.length;i++)
		arr[i] = arr[i].replace(/=/," for ") + " points";
	
	return arr.join(", ");
}


function advanced_data_handler(data)
{
	if(matches = data.match(/^SAY (\w+?) ([\s\S]+)$/i))
	{
		say(matches[1] + ": " + matches[2],"say");
	}
	else if(matches = data.match(/^JOIN (\w+)$/i))
	{
		say(matches[1] + " has joined the game","join");
		send("/whoroom");
		playsnd("join");
	}
	else if(matches = data.match(/^QUIT (.*)$/i))
	{
		say(matches[1] + " has left the game","quit");
		send("/whoroom");
		playsnd("leave");
	}
	else if(matches = data.match(/^WHOROOM (.+)$/i))
	{
		build_playerlist(matches[1]);
	}
	else if(matches = data.match(/^WHOAMI (.+)$/i))
	{
		whoami(matches[1]);
	}
	else if(matches = data.match(/^Q (\d+) (\d+)\/(\d+) ([\s\S]+)$/i))
	{
		clear_correct();
		set_question(matches[4]);
		start_countdown();
		say("Question " + matches[2] + " of " + matches[3] + ": " + matches[4],"question");
		flag_link(matches[1]);
		playsnd("newquestion");
	}
	else if(matches = data.match(/^HINT (.+)$/))
	{
		say("Hint: " + matches[1],"hint");	
	}
	else if(matches = data.match(/^CLARIFY (.+)$/))
	{
		say(matches[1],"close");
		playsnd("close");
	}
	else if(matches = data.match(/^ROUNDTIMELIMIT (\d+)$/))
	{
		set_roundtimelimit(parseFloat(matches[1]));
	}
	else if(matches = data.match(/^START_GAME$/i))
	{
		send("/whoroom");
		$("#questiontext").removeClass("gameover");
	}
	else if(matches = data.match(/^A ([\s\S]+)$/i))
	{
		Answer = matches[1].replace("/\n/","\n")
		say("Answer:\n" + Answer,"answers");
		popup_notify("The Answer was: " + Answer,"red");
	}
	else if(matches = data.match(/^ROUNDTIMELIMIT$/i))
	{
		$("#countdown")
			.css("font-size","24pt")
			.css("color","#ff0000")
			.html("Time's<br />Up!");
		end_countdown();
		playsnd("timeup");

	}
	else if(matches = data.match(/^ALLCORRECT$/i))
	{
		$("#countdown")
			.css("font-size","20pt")
			.css("color","#007700")
			.html("Everyone<br />Got It");
		end_countdown();
		playsnd("everyone");
		popup_notify("Everyone got it right!","green");
	}
	else if(matches = data.match(/^CORRECTLIST (.*)$/i))
	{
		//say("Users who got the right answer: " + format_right_users(matches[1]),"users_correct");
	}
	else if(matches = data.match(/^CLOSE /i))
	{
		say("You're REALLY Close","close");
		playsnd("close");
	}
	else if(matches = data.match(/^CORRECT ([\d\.]+) (.*)$/i))
	{
		var name=matches[2];
		if(name==myname())
		{
			playsnd("mecorrect");
			displayname="You";
			popup_notify("You got it right!","green")
		}
		else
		{
			playsnd("correct");
			displayname=name;
		}

		say(displayname + " got it right for " + matches[1] + " points!","correct");
		set_correct(matches[2],matches[1]);
	}
	else if(matches = data.match(/^INACTIVE$/i))
	{
		alert("Game room abandoned due to inactivity");
		location.href=location.href;
	}
	else if(matches = data.match(/^ROOMREADY$/i))
	{
		initialize_interface();
		send("/whoami");
	}
	else if(matches = data.match(/^COUNTDOWN (\d+)$/))
	{
		start_countdown(matches[1]);
		
	}
	else if(matches = data.match(/^ROOMNAME (.+)$/))
	{
		set_gamename(matches[1]);

		setTimeout("send('/catchup');",1000);
	}
	else if(matches = data.match(/^ALREADYCORRECT$/))
	{
		already_correct();
	}
	else if(matches = data.match(/^CATEGORY (.+)$/i))
	{
		set_gamecategory(matches[1]);
		send("/whoroom");
	}
	else if(matches = data.match(/^GAMEOVER (.*)$/i))
	{
		game_over(matches[1]);
		playsnd("gameover");
		send("/ownercheck");
	}
	else if(matches = data.match(/^OWNER$/i))
	{
		enable_start_button();
	}
	else if(matches = data.match(/^NEWOWNER (.+)$/i))
	{
		say(matches[1] + " has been promoted to the leader of this game");
	}
}

