function broadcastGUI() {
	var numbers = [8, 7, 6, 5, 4, 3, 2, 1];
	var letters = ["a", "b", "c", "d", "e", "f", "g", "h"];
	var letter = [];
	letter["a"] = 1;
	letter["b"] = 2;
	letter["c"] = 3;
	letter["d"] = 4;
	letter["e"] = 5;
	letter["f"] = 6;
	letter["g"] = 7;
	letter["h"] = 8;
	
	if (navigator.appName == "Microsoft Internet Explorer" && navigator.appVersion.match(/MSIE 6\./)) {
		var ie6 = true;
	}
	
	this.displayLang = getCookie("displayLang");
	if (!this.displayLang) this.displayLang = "English";

	
	try {
		var canvas = Raphael("board_svg", 432, 422);
	} catch (e) {
		
	}
	this.arrow;
	this.startPoint;

	// If board is flipped
	this.flipped = false;

	this.drawGamesList = 
	function(games, selectedGame) {
		var gamesList = document.getElementById("gameslist");
		var html = "\n";
		for (var i = 0; i < games.length; i++) {
			html += "<div onclick='broadcast.loadGame(\"" + i  +"\")' class='game" + (i == selectedGame ? " selected" : "") + "'>\n";
			var players = games[i].tags["White"] + " - " + games[i].tags["Black"];
			if(players.length > 19) {
				players = players.substr(0, 18).replace(/\s*$/, "") + "";
			}
			html += players + "<br />\n";
			var result = games[i].tags["Result"];
			html += "<span class='lastmoves" + (i != selectedGame && games[i].lastStamp < games[i].tags["Stamp"] ? " updated" : "") + "'>";
			if (result != "*") {
				html += result.replace(/1\/2/g, "½");
			} else {
				html += (games[i].tags["LastMoves"] ? games[i].tags["LastMoves"] : "*") + "</span>\n";
			}
			html += "</span>";
			html += "</div>\n";
		}
		
		html += "<div id=\"language\">\n";
		html += "<span class=\"leftfloat\">Language: </span>";
		html += "<select id=\"langselect\" onChange=\"broadcast.changeLanguage(this.selectedIndex)\">\n";
		html += "<option value=\"English\">English</OPTION>\n";
		html += "<option value=\"Russian\">Русский</OPTION>\n";
		html += "<option value=\"German\">Deutsch</OPTION>\n";
		html += "<option value=\"Spanish\">Español</OPTION>\n";
		html += "<option value=\"French\">Français</OPTION>\n";
		html += "<option value=\"Italian\">Italiano</OPTION>\n";
		html += "</select>\n";
		html += "</div>\n\n";
		var expr = eval("/value=\"" + this.displayLang + "\"/");
		html = html.replace(expr, "selected value=\"" + this.displayLang + "\"");

		gamesList.innerHTML = html;
	}
	
	this.drawGameHeader = 
	function(game, board) {
		var headerWhite = document.getElementById("header_white");
		var headerBlack = document.getElementById("header_black");
		var headerClock = document.getElementById("header_clock");
		var html = "";
		html += "<b>" + game.tags["White"] + "</b>" + (game.tags["WhiteElo"] ? " <span class='elo_rating'>(" + game.tags["WhiteElo"] + ")</span>" : "");
		html += (game.tags["WhiteClock"] && game.tags["Result"] == "*" ? " [<span class='player_clock'>" + game.tags["WhiteClock"] + "</span>]" : "");
		headerWhite.innerHTML = html;

		html = "";
		html += game.tags["Result"].replace(/1\/2/g, "½").replace(/\*/g, "<b>vs</b>").replace(/-/, " - ").replace(/\s/g, "&nbsp;");
		headerClock.innerHTML = html;

		html = "";
		html += (game.tags["BlackClock"] && game.tags["Result"] == "*" ? "[<span class='player_clock'>" + game.tags["BlackClock"] + "</span>] " : "");
		html += "<b>" + game.tags["Black"] + "</b>" + (game.tags["BlackElo"] ? " <span class='elo_rating'>(" + game.tags["BlackElo"] + ")</span>" : "");
		headerBlack.innerHTML = html;
	}
	
	this.drawBoardPosition =
	function(game, board) {
		var square;
		for(var rows = 1; rows <= 8; rows++) {
			for(var cols = 1; cols <= 8; cols++) {
				square = document.getElementById("square" + rows + cols);
				while (square.childNodes[0]) {
					square.removeChild(square.childNodes[0]);
				}
			}
		}
		var GUIsquare;
		var piece;
		var square;
		var shortName;
		for(var i = 0; i < board.pieces.length; i++) {
			var piece = board.pieces[i];
			var square = piece.square;
			if (square != undefined) {
				GUIsquare = this.getGUISquare(square.x, square.y);
				if (piece.name != "knight")
					shortName = piece.name.charAt(0);
				else
					shortName = "n";
				var pieceImg = document.createElement("IMG");
				pieceImg.id = "piece" + square.x + square.y;
				pieceImg.src = "images/pieces/classic/45" + (ie6? "gif" : "") + "/" + piece.color.charAt(0) + shortName + (ie6? ".gif" : ".png");
				GUIsquare.appendChild(pieceImg);
			}
		}
		
		this.drawCoordinates();
		if (this.arrow) {
			this.arrow.remove();
			this.arrow = undefined;
		}

		if (this.startPoint) {
			this.startPoint.remove();
			this.startPoint = undefined;
		}

		var id = game.notationMove;

		if(id != "start") {
			var fromX = game.displayNotation[id]["fromto"].fromX;
			var fromY = game.displayNotation[id]["fromto"].fromY;
			var toX = game.displayNotation[id]["fromto"].toX;
			var toY = game.displayNotation[id]["fromto"].toY;

			var knight = (game.displayNotation[id]["token"].charAt(0) == "N" ? true : false);

			this.drawArrow(fromX, fromY, toX, toY, knight);
		} else {
			if (this.arrow) {
				this.arrow.remove();
				this.arrow = undefined;
			}
		}
		var white = document.getElementById("header_white");
		var black = document.getElementById("header_black");
		if (game.displayNotation[id]["color"] == "white") {
			var oldM = white;
			var newM = black;
		} else {
			var oldM = black;
			var newM = white;
		}
		this.removeClass(oldM, "active");
		this.addClass(newM, "active");
		
		var cfen = document.getElementById("currfen");
		cfen.value = game.FENs[game.displayNotation[id]["fenlink"].variation][game.displayNotation[id]["fenlink"].number];
	}

	// Rotates the board
	this.flipBoard =
	function() {
		document.getElementById("flipicon").blur();
		if (this.flipped)
			this.flipped = false;
		else
			this.flipped = true;
		this.drawBoardPosition(broadcast.games[broadcast.selectedGame], broadcast.board);
	}

	// Draws the coordinates according to this.flipped state
	this.drawCoordinates=
	function() {
		var lttr;
		var nmbr;
		for (var i = 0; i < letters.length; i++) {
			if (this.flipped) {
				lttr = letters[7 - i];
				nmbr = 8 - i;
			} else {
				lttr = letters[i];
				nmbr = i + 1;
			}
			var holder = document.getElementById("top" + letters[i]);
			holder.firstChild.nodeValue = lttr.toUpperCase();
			holder = document.getElementById("bottom" + letters[i]);
			holder.firstChild.nodeValue = lttr.toUpperCase();
			holder = document.getElementById("left" + parseInt(i + 1));
			holder.firstChild.nodeValue = nmbr;
			holder = document.getElementById("right" + parseInt(i + 1));
			holder.firstChild.nodeValue = nmbr;
		}
	}
	
	this.drawGameLink =
	function(path, game) {
		var gameLink = document.getElementById("gamelink");
		gameLink.innerHTML = "<a href='http://chessok.com/broadcast?key=" + path + "&game=" + game + "'>http://chessok.com/broadcast?key=" + path + "&game=" + game + "</a>";
	}

	this.drawNotation =
	function(game) {
		var notationBox = document.getElementById("notation_box");
		var pretoken;
		var vartoken = 0;
		var variations = [];
		var prevvariation;
		var bracket1 = "<span class='invisible'>{</span>";
		var bracket2 = "<span class='invisible'>}</span>";
		var notation = "<span class='notmove' id='movestart'><a href='javascript: broadcast.loadMove(\"start\")'>[" + "<span class='invisible'>Void </span>" + "<span class='invisible'>\"</span>#<span class='invisible'>\"</span>" +"]</a></span> ";

		notation += "<span class='invisible'>";
		for (var keyVar in game.tags) {
			notation += "[" + keyVar + " " + "\"" + game.tags[keyVar] + "\"]\n";
		}
		notation += "</span>\n";
		
		for (var i = 0; i < game.displayNotation.length; i++) {
			var token = game.displayNotation[i];
			if (token["type"] == "regular") {
				if (vartoken == 2) {
					vartoken = 0;
					if (!z0) {
						notation += " " + bracket1 + "<a href='javascript: broadcast.gui.expand_variation(" + variations[variations.length - 1] + ")'>" + "<img id=\"expandimg" + variations[variations.length - 1] + "\" src='images/layout/expandplus.png'/>" + "</a>" + bracket2 + "<span class='hidden' id='var" + variations[variations.length - 1] + "'> ";
					}
				}
				if (pretoken == "longcomm") {
					notation += "<br />";
				}
				if (token["color"] == "white") {
					if (pretoken == "varstart" || pretoken == "longcomm") {
					} else {
						notation += " ";
					}
					notation += "<span class='num'>" + token["num"] + ". </span>\n";
					notation += "<span class='notmove' id='move" + i + "'><a href='javascript: broadcast.loadMove(" + i + ")'>" + token["token"] + "</a></span>\n";
				} else if (token["color"] == "black") {
					if (pretoken == "varstart" || pretoken == "longcomm") {
						notation += "<span class='num'>" + (token["num"] - 1) + "... </span>";
					} else if (pretoken == "comm") {
						notation += " <span class='num'>" + (token["num"] - 1) + "... </span>";
					} else if (pretoken == "regular") {
						notation += " ";
					}
					notation += "<span class='notmove' id='move" + i + "'><a href='javascript: broadcast.loadMove(" + i + ")'>" + token["token"] + "</a></span>\n";
				}
				if (vartoken == 1) {
					vartoken++;
				}
				if (vartoken == 0 && !z0) {
					var lastMove = i;
				}
				pretoken = "regular";
			} else if (token["type"] == "variation_start") {
				notation += "<div class='variation'><span class='commentary'>(</span>";
				pretoken = "varstart";
				variations.push(i);
				vartoken = 1;
			} else if (token["type"] == "variation_end") {
				if (!z0) {
					notation += "</span>";
				}
				notation +="<span class='commentary'>)</span></div>\n";
				pretoken = "varend";
				variations.pop();
				vartoken = 0;
			} else if(token["type"] == "commentary") {
				if (token["value"].length > 35) {
					notation += "<br />";
				}
				notation += " " + bracket1 + "<span class='commentary'>" + token["value"] + "</span>" + bracket2;
				
				if (token["value"].length > 35) {
					pretoken = "longcomm";
				} else {
					pretoken = "comm";
				}
			} else if(token["type"] == "z0") {
				var z0 = true;
			}
			if (token["fenlink"]) {
				var corrFEN = game.FENs[token["fenlink"].variation][token["fenlink"].number];
				if (game.currPosition == game.FENs[0][0]) {
					currToken = "start";
				} else if (corrFEN == game.currPosition) {
					var currToken = i;
					if (token["fenlink"].variation > 0 && token["fenlink"].number > 1 && !z0) {
						var openVariation = variations[variations.length - 1];
					}
				}
			}
		}
		notation += "<span class='invisible'> " + game.tags["Result"] + " </span>" + "&nbsp;" + bracket1 + "<span class='notmove'>[" + game.tags["Result"].replace(/1\/2/g, "½") + "]</span>" + bracket2;
		notation += "<br />&nbsp;";
		if (broadcast.noupdate) {
			notation += "<span class='jumpoption'><input type='checkbox' onclick='broadcast.switchjump();'" + (broadcast.jump? " checked" : "") +"> Jump to last move on update</span>";
			notation += "<br />&nbsp;";
		}
		notation += "<hr style='width: 80%; size: 1px; background: #936a50;'>";
		notation += "<center><span style='font-size: 12px'>Order <b><a href='http://chessok.com/shop/index.php?main_page=index&cPath=7_43'>Houdini 2 Aquarium</a></b> from our online <b><a href='/shop/'>shop</b></a></center>";
		notationBox.innerHTML = notation;
		
		if (currToken)
		{
			var notMove = document.getElementById("move" + currToken);
			game.notationMove = currToken;
			this.addClass(notMove, "selected");
		}
		if (openVariation) {
			this.expand_variation(openVariation);
		}
		game.lastMove = lastMove;
	}

	this.expand_variation =
	function(id) {
		var varNotation = document.getElementById("var" + id);
		var img = document.getElementById("expandimg" + id);
		img.parentNode.blur();
		if (this.hasClass(varNotation, "hidden")) {
			this.removeClass(varNotation, "hidden");
			img.src = img.src.replace(/plus/, "minus");
		} else {
			img.src = img.src.replace(/minus/, "plus");
			this.addClass(varNotation, "hidden");
		}
	}

	this.displayMove =
	function(game, board, oldid) {
		var oldMove = document.getElementById("move" + oldid);
		var notMove = document.getElementById("move" + game.notationMove);
		if (this.hasClass(oldMove, "selected")) {
			this.removeClass(oldMove, "selected");
		}
		this.addClass(notMove, "selected");

		notMove.childNodes[0].blur();
		notMove.childNodes[0].focus();
		this.drawBoardPosition(game, board);
	}
	
	this.drawArrow =
	function(fromX, fromY, toX, toY, knight) {
		//alert(fromX + fromY + toX + toY);
		var fX = letter[fromX];
		var fY = 9 - fromY;
		var tX = letter[toX];
		var tY = 9 - toY;
		if (this.flipped) {
			fX = 9 - fX;
			fY = 9 - fY
			tX = 9 - tX;
			tY = 9 - tY
		}

		fX = fX * 50 - 25 + 17;
		fY = fY * 50 - 25 + 21;
		tX = tX * 50 - 25 + 17;
		tY = tY * 50 - 25 + 21;
		
		if (this.arrow) {
			this.arrow.remove();
		}
		
		var lX = Math.abs(tX - fX);
		var lY = Math.abs(tY - fY);
		var tL = Math.sqrt(lX*lX + lY*lY);
		var mod = -1*lX / (tX - fX);

		if (lX == 0) {
			var rotationAngle = 0;
		} else {
			var rotationAngle = - Math.atan((tX - fX)/(tY - fY));
		}
		
		if (lY == 0) {
			rotationAngle = - rotationAngle;
		} else if (tY > fY) {
			rotationAngle = Math.PI + rotationAngle;
		}

		rotationAngle = rotationAngle / Math.PI * 180;

	try {
		//var c = canvas.path({fill: "#ff0", stroke: "#000", opacity: 0.66}).moveTo(fX, fY).lineTo(fX - 5, fY - tL + 15);
		if (knight) {
			var sq = Math.sqrt(50*50/2);
			//this.arrow = canvas.path({fill: "#ff0", stroke: "#000", opacity: 0.6}).moveTo(fX, fY).qcurveTo(fX - 5 + mod*sq, fY - 1.5*sq, fX - 5 + mod*sq, fY - 3*sq + 15).lineTo(fX - 15 + mod*sq, fY - 3*sq + 20).lineTo(fX + mod*sq, fY - 3*sq).lineTo(fX + 15 + mod*sq, fY - 3*sq + 20).lineTo(fX + 5 + mod*sq, fY - 3*sq + 15).qcurveTo(fX + 5 + mod*sq, fY - 1.5*sq, fX, fY);
			this.arrow = canvas.path({fill: "#ff0", stroke: "#000", opacity: 0.6}).moveTo(fX, fY).curveTo(fX - 2 + 0.5*mod*sq, fY - sq, fX - 5 + mod*sq, fY - 1.5*sq, fX - 5 + mod*sq, fY - 3*sq + 15).lineTo(fX - 15 + mod*sq, fY - 3*sq + 20).lineTo(fX + mod*sq, fY - 3*sq).lineTo(fX + 15 + mod*sq, fY - 3*sq + 20).lineTo(fX + 5 + mod*sq, fY - 3*sq + 15).curveTo(fX + 5 + mod*sq, fY - 1.5*sq, fX + 2 + 0.5*mod*sq, fY - sq, fX, fY);


			var knightAngle = Math.atan(1/3) / Math.PI * 180;
			this.arrow.rotate(rotationAngle - mod*knightAngle, fX, fY);
			//alert(/Math.PI * 180);
		} else {
			this.arrow = canvas.path({fill: "#ff0", stroke: "#000", opacity: 0.6}).moveTo(fX, fY).lineTo(fX - 5, fY - tL + 15).lineTo(fX - 15, fY - tL + 20).lineTo(fX, fY - tL).lineTo(fX + 15, fY - tL + 20).lineTo(fX + 5, fY - tL + 15).lineTo(fX, fY);
			this.arrow.rotate(rotationAngle, fX, fY);
		}

		this.startPoint = canvas.circle(fX, fY, 10);
		this.startPoint.attr({fill: "#ff0", stroke: "#000", opacity: 0.25});
	} catch (e) {
		
	}
	}

	// Returns the GUI square reference given the board coordinates;
	this.getGUISquare =
	function(x, y) {
		if (!this.flipped) {
			x = letter[x];
			y = 9 - y;
		} else {
			x = 9 - letter[x];
		}
		return document.getElementById("square" + x + y);
	}

	// Returns the board coordinates given the id of GUI square
	this.getSquare =
	function(id) {
		if (id.match(/piece/)) {
			return {x: id.charAt(5), y: id.charAt(6)};
		}
		if (!this.flipped) {
			x = letters[id.charAt(6) - 1];
			y = 9 - id.charAt(7);
		} else {
			x = letters[8 - id.charAt(6)];
			y = id.charAt(7);
		}
		return {x: x, y: y};
	}


	this.addClass =
	function(target, classValue) {
		if (!this.hasClass(target, classValue))
			if (target.className == "")
				target.className = classValue;
			else
				target.className += " " + classValue;
		return true;
	}

	this.removeClass =
	function(target, classValue) {
		if(this.hasClass(target, classValue)) {
			var removedClass = target.className;
			var pattern = new RegExp("(^| )" + classValue + "( |$)");
			removedClass = removedClass.replace(pattern, "$1");
			removedClass = removedClass.replace(/ $/, "");
			target.className = removedClass;
		}
		return true;
	}

	this.hasClass =
	function(target, classValue) {
		var pattern = new RegExp("(^| )" + classValue + "( |$)");    
		if (target.className.match(pattern))
			return true;
		return false;
	}
}
