﻿function chessGUI() {

	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;
	
	var nags = [];
	nags[1] = "!";
	nags[2] = "?";
	nags[3] = "!!";
	nags[4] = "??";
	nags[5] = "!?";
	nags[6] = "?!";
	nags[7] = "the only move";
	nags[8] = "the only move";
	nags[9] = "worst move";
	nags[10] = "=";
	nags[11] = "=";
	nags[12] = "=";
	nags[13] = "unclear";
	nags[14] = "white stands slightly better";
	nags[15] = "black stands slightly better";
	nags[16] = "White have the upper hand";
	nags[17] = "Black have the upper hand";
	nags[18] = "White have a decisive advantage";
	nags[19] = "Black have a decisive advantage";
	nags[20] = "White has a crushing advantage";
	nags[21] = "Black has a crushing advantage";
	nags[22] = "zugzwang";
	nags[23] = "zugzwang";
	nags[30] = "Development advantage";
	nags[31] = "Development advantage";
	nags[36] = "With iniative";
	nags[37] = "With iniative";
	nags[40] = "With attack";
	nags[41] = "With attack";
	nags[44] = "With compensation for the material";
	nags[45] = "With compensation for the material";
	nags[130] = "With counter-play";
	nags[131] = "With counter-play";


	// Path to images folder
	this.baseImages = "images/";
	this.piecesTheme = getCookie("piecestheme");
	if (!this.piecesTheme) this.piecesTheme = "classic";
	this.piecesSize = "45";

	var arrows = true;
	if (navigator.appName == "Microsoft Internet Explorer" && navigator.appVersion.match(/MSIE 6\./)) {
		var ie6 = true;
		//arrows = false;
	}
	
	if (ie6) {
		this.piecesSize = "45gif";
		this.piecesTheme = "modern";
	}

	// Draws the display options

	this.drawDisplayOptions =
	function() {
		var result = "";
		result += "<DIV id=\"displayOptions\">\n";
		result += "<SPAN class=\"leftfloat\">Фигуры:</SPAN> <SELECT id=\"theme\" onChange=\"GUI.changeTheme(this.selectedIndex)\">\n";
		if (ie6) {
			result += "<OPTION value=\"modern\">Современные</OPTION>\n";
		} else {
			result += "<OPTION value=\"classic\">Классические</OPTION>\n";
			result += "<OPTION value=\"modern\">Современные</OPTION>\n";
			result += "<OPTION value=\"veronika\">Сказочные</OPTION>\n";
			result += "<OPTION value=\"fantasy\">Фентезийные</OPTION>\n";
			result += "<OPTION value=\"eyes\">Глаза</OPTION>\n";
			result += "<OPTION value=\"spatial\">Объемлющие</OPTION>\n";
		}
		result += "</SELECT>\n";
		result += "<DIV id=\"gamestate\">&nbsp;</DIV>";
		result += "</DIV>\n\n";
		var expr = eval("/value=\"" + this.piecesTheme + "\"/");
		result = result.replace(expr, "selected value=\"" + this.piecesTheme + "\"");
		document.write(result);
	}
	
	this.changeTheme =
	function(index) {
		this.piecesTheme = document.getElementById("theme").options[index].value;
		setCookie("piecestheme", this.piecesTheme, 365)
		this.flushPosition();
		this.drawPosition();
	}

	// Display the chessboard
	this.drawBoard = 
	function() {
		var result = "";
		function switchColor(color) {
			if(color == "black")
				return "white";
			else
				return "black";
		}

		var color = "white";

		result += "<DIV id=\"boardCanvas\">\n";
		result += "<TABLE cellspacing=0 cellpadding=0 id=\"chessBoard\">\n";
		result += "<TR>\n";
		result += "<TD class=\"corner\"></TD>\n";
		for(cols = 1; cols <= 8; cols++) {
			result += "<TD id=\"top" + letters[cols - 1] + "\" class=\"lettertop\">&nbsp;</TD>\n";
		}
		result += "<TD class=\"corner\">";
		result += "</TD>\n";
		result += "</TR>\n";
		for(rows = 1; rows <= 8; rows++) {
			result += "<TR>\n";
			result += "<TD id=\"left" + numbers[rows - 1] + "\" class=\"numberleft\">&nbsp;</TD>\n";
			for(cols = 1; cols <= 8; cols++) {
				result += "<TD class=\"" + color +"\" id=\"square" + cols + rows + "\"></TD>\n";
				
				color = switchColor(color);
			}
			color = switchColor(color);
			result += "<TD id=\"right" + numbers[rows - 1] + "\" class=\"numberright\">&nbsp;</TD>\n";
			result += "</TR>\n";
		}
		result += "<TR>\n";
		result += "<TD class=\"corner\"></TD>\n";
		for(cols = 1; cols <= 8; cols++) {
			result += "<TD id=\"bottom" + letters[cols - 1] + "\" class=\"letterbottom\">&nbsp;</TD>\n";
		}
		result += "<TD class=\"corner\"><A title=\"Flip board\" id=\"flipicon\" href=\"javascript: GUI.flipBoard();\"><IMG src=\"" + this.baseImages + "flip.jpg\" /></A></TD>\n";
		result += "</TR>\n";
		result += "</TABLE>\n";
		result += "</DIV>\n";

		document.write(result);
		this.drawCoordinates();
	}

	// 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;
			}
			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;
		}
	}

	// Draws the game options container
	this.drawGameOptions=
	function() {
		var result = "";
		result += "<DIV id=\"gameOptions\">";
		result += "<SPAN class=\"leftfloat\">Сложность:</SPAN> <SELECT id=\"difficulty\" onChange=\"changeDifficulty(this.selectedIndex)\">\n";
		result += "<OPTION " + (difficulty == "l1" ? "selected=\"selected\"" : "") + " value=\"l1\">Уровень 1</OPTION>\n";
		result += "<OPTION " + (difficulty == "l2" ? "selected=\"selected\"" : "") + " value=\"l2\">Уровень 2</OPTION>\n";
		result += "<OPTION " + (difficulty == "l3" ? "selected=\"selected\"" : "") + " value=\"l3\">Уровень 3</OPTION>\n";
		result += "<OPTION " + (difficulty == "l4" ? "selected=\"selected\"" : "") + " value=\"l4\">Уровень 4</OPTION>\n";
		result += "<OPTION " + (difficulty == "l5" ? "selected=\"selected\"" : "") + " value=\"l5\">Уровень 5</OPTION>\n";
		//result += "<OPTION value=\"test\">Test</OPTION>\n";
		result += "</SELECT>\n";
		//result += "<A id=\"takeback\" class=\"btn\" href=\"javascript: takeBack();\">Takeback</A> ";
		result += "<A id=\"newpuzzle\" class=\"btn\"href=\"javascript: newPuzzle();\">Новая задача</A>";
		result += "<DIV id=\"timer\"><SPAN id=\"puzzletimer\">00:00</SPAN></DIV>";
		result += "<DIV id=\"tabcontentborder\">";
		result += "<DIV id=\"tabcontentholder\">";
		result += "<DIV id=\"tabcontent\">";
		result += "</DIV>";
		result += "</DIV>";
		result += "</DIV>";
		result += "</DIV>\n";
		result += "<DIV id=\"promotion\">";
		result += "Превратить в <BR /><A href=\"javascript: promoteTo('queen')\"><IMG src=\"" + this.baseImages + "pieces/" + this.piecesTheme + "/" + this.piecesSize + "/" +  "wq" + (ie6? ".gif" :".png") + "\"/></A> ";
		result += "<A href=\"javascript: promoteTo('rook')\"><IMG src=\"" + this.baseImages + "pieces/" + this.piecesTheme + "/" + this.piecesSize + "/" + "wr" + (ie6? ".gif" :".png") + "\"/></A> ";
		result += "<A href=\"javascript: promoteTo('bishop')\"><IMG src=\"" + this.baseImages + "pieces/" + this.piecesTheme + "/" + this.piecesSize + "/" +"wb" + (ie6? ".gif" :".png") + "\"/></A> ";
		result += "<A href=\"javascript: promoteTo('knight')\"><IMG src=\"" + this.baseImages + "pieces/" + this.piecesTheme + "/" + this.piecesSize + "/" + "wn" + (ie6? ".gif" :".png") + "\"/></A> ";
		result += "</DIV>\n";
		document.write(result);
	}
	
	this.drawmoveslist = 
	function() {
		var moveslist = "";
		if (game != undefined) {
			this.Z0 = false;
			moveslist += "<SPAN id=\"moveslist\"><A href=\"javascript:loadMove(0)\" id=\"move0\">[#]</A> ";
			moveslist += this.drawMoves(game, game.movetext, 1, false, 0, 0, false, 0);
			moveslist += "</SPAN>";
		}
		return moveslist;
	}
	
	this.varend = false;
	// Display moves assigned to give game
	this.drawMoves = 
	function(game, movetext, moveCounter, variation, varNum, varCounter, newVar, deep) {
		var moveTokens = movetext.split(/[\s]+/);
		var token;
		var moves = "";
		var mvCounter;
		for(var i = 0; i < moveTokens.length; i++) {
			token = moveTokens[i];
			if (/[RBQKPN]?[a-h]?[1-8]?[x]?[a-h][1-8][=]?[QNRB]?[+#]?|O-O-O|O-O/.test(token)) {
				if (moveCounter == 1 || this.varend)
						moves +="<SPAN id=\"notmove" + (variation ? varNum + "_" + moveCounter : moveCounter) + "\" class=\"movehidden\">";
					else
						moves +="</SPAN><SPAN id=\"notmove" + (variation ? varNum + "_" + moveCounter : moveCounter) + "\" class=\"movehidden\">";
				if (!variation) {
					pre = "<B>";
					after = "</B>";
				} else {
					pre = "";
					after = "";
				}
				if (blackdot)
					mvCounter = moveCounter + 1;
				else
					mvCounter = moveCounter;
				if (Math.round((varCounter + mvCounter)/2) != (varCounter + mvCounter) / 2)
					moves += pre + Math.round((varCounter + mvCounter)/2) + "." + after + "&nbsp;";
				else if (Math.round(varCounter + mvCounter/2) == (varCounter + mvCounter) / 2)
					moves += pre + Math.floor((varCounter + mvCounter)/2) + "..." + after + "&nbsp;";
				else if (newVar && Math.round(varCounter + mvCounter/2) != (varCounter + mvCounter) / 2)
					moves += pre + Math.floor((varCounter + mvCounter)/2) + "..." + after + "&nbsp;";
				newVar = false;
				if (!variation) {
					moves += "<B><A id=\"move" + moveCounter + "\" href=\"javascript: loadMove(" + moveCounter + ")\">" + token + "</A></B> ";
				} else
					moves += "<A id=\"var" + varNum + "_"+ moveCounter + "\" href=\"javascript:loadVariation(" + varNum + ", " + moveCounter + ")\">" + token + "</A> ";
				this.varend = false;
				moveCounter++;
			} else if (/\{[\d]+\}/.test(token)) {
				cM = token.match(/\{([\d]+)\}/)[1];
				cM = game.commentaries[cM];
				cM = cM.replace(/\&gt\;/g, ">");
				cM = cM.replace(/\&lt\;/g, "<");
				cM = cM.replace(/\&amp\;/g, "&");
				if (cM != "") {
					moves += (cM.length > 50 ? "<BR />": "") + "<SPAN class=\"comment\">" + cM + "</SPAN>" + (cM.length > 50 ? (variation ? (game.varFENs[varNum][moveCounter + 1] ? "<BR />" : "") : "<BR />") : (variation ? (game.varFENs[varNum][moveCounter + 1] ? " " :"") : " "));
					newVar = true;
				}
			} else if (/Z0/.test(token)) {
				this.Z0 = true;
			} else if (/<[\d]+>/.test(token)) {
				//if (!this.linebreak)
				//moves += "<BR />";
				if (!this.varend) 
					moves += "</SPAN>";
				this.varend = false;
				vN = token.match(/<([\d]+)>/)[1];
				moves += "<DIV class=\"variations\"><SPAN class=\"movehidden\" id=\"variation" + vN + "\">(<A id=\"var" + vN + "_0\" href=\"javascript:loadVariation(" + vN + ", " + 0 +")\" id=\"move0\">[#]</A> ";
				if (this.Z0) {
					delta = 1;
				} else {
					delta = 2;
				}
				moves += this.drawMoves(game, game.variations[vN], 1, true, vN, varCounter + moveCounter - delta, true, deep + 1);
				//if (deep == 0 && !this.Z0)
					//moves += "</SPAN>";
				moves += ")</SPAN></DIV>";
				this.varend = true;
			} else if (/(?:0-1|1-0|1\/2-1\/2|\*)/.test(token)) {
				end = token.match(/(0-1|1-0|1\/2-1\/2|\*)/)[1];
				moves += "</SPAN><SPAN class=\"end\">[" + end.replace(/1\/2/g,"?") + "]</SPAN>";
			} else if (/\$[\d]+/.test(token)) {
				nag = token.match(/\$([\d]+)/)[1];
				moves += "<SPAN class=\"nag\">" + nags[nag] + "</SPAN> ";
				this.varend = false;
			}
		}
		if (deep != 0 && !this.varend)
			moves += "</SPAN>";
		if (game.tags["Result"] == "*" && !variation) {
			//moves += "<BR /><BR /><SPAN class=\"clock\">White clock: " + game.tags["WhiteClock"] + "<BR />Black clock: " +  game.tags["BlackClock"] + "</SPAN>";
		}
		return moves;
	}


	// Pops the promotion box
	this.popPromotion=
	function() {
		var promBox = document.getElementById("promotion");
		var imgSrc;
		for (var i = 0; i < promBox.childNodes.length; i++) {
			if (promBox.childNodes[i].nodeName == "A") {
				imgSrc = promBox.childNodes[i].firstChild.src;
				promBox.childNodes[i].firstChild.src = imgSrc.replace(/^[\w\W]+[wb]([nbpqr])\.png/, this.baseImages + "pieces/" + this.piecesTheme + "/" + this.piecesSize + "/" + game.currentMove.charAt(0) + "$1.png");
			}
		}
		promBox.style.position = 'absolute';
		promBox.style.left = promData.x;
		promBox.style.top = promData.y;
		promBox.style.visibility = 'visible';
	}

	// Holds the state of the board flipped/not flipped
	this.flipped = false;

	// Rotates the board
	this.flipBoard =
	function() {
		document.getElementById("flipicon").blur();
		if (!promoting) {
			if (this.flipped)
				this.flipped = false;
			else
				this.flipped = true;
			this.flushPosition();
			this.drawPosition();
			this.drawCoordinates();
		}
	}

	// Empties the board
	this.flushPosition =
	function() {
		var square;
		jg.clear();
		for(rows = 1; rows <= 8; rows++) {
			for(cols = 1; cols <= 8; cols++) {
				square = document.getElementById("square" + rows + cols)
				removeChildNodes(square);
				// innerHTML way
				//document.getElementById("square" + rows + cols).innerHTML = "";
			}
		}
	}

	this.drawPosition =
	function() {
		var GUIsquare;
		var piece;
		var square;
		var shortName;
		for(var i = 0; i < game.pieces.length; i++) {
			piece = game.pieces[i];
			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 = this.baseImages + "pieces/" + this.piecesTheme + "/" + this.piecesSize + "/" + piece.color.charAt(0) + shortName +  (ie6? ".gif" :".png");
				GUIsquare.appendChild(pieceImg);
				// innerHTML way
				//GUIsquare.innerHTML = "<IMG id=\"piece" + square.x + square.y + "\" src=\"" + this.baseImages + "pieces/" + this.piecesTheme + "/" + this.piecesSize + "/" + piece.color.charAt(0) + shortName + ".png\"/>";
				if (game.moves[variation + 1][(variation == -1 ? currMove : varMove + 1)] && game.moves[variation + 1][(variation == -1 ? currMove : varMove + 1)].guess)
					makeDraggable(this.getGUISquare(square.x, square.y));
			}
		}
		
		this.drawCoordinates();
		if (arrows && game.moves[0].length > 0 && ((currMove > 0 && variation == -1) || varMove > 0 && variation != -1)) {
			var curTarget = (variation == -1 ? GUI.getGUISquare(game.moves[0][currMove - 1].toX, game.moves[0][currMove - 1].toY) : GUI.getGUISquare(game.moves[variation + 1][varMove].toX, game.moves[variation + 1][varMove].toY));
			var targPos = getPosition(curTarget);
			var targWidth = parseInt(curTarget.offsetWidth);
			var targHeight = parseInt(curTarget.offsetHeight);

			var oldSquare = (variation == -1 ? GUI.getGUISquare(game.moves[0][currMove - 1].fromX, game.moves[0][currMove - 1].fromY) : GUI.getGUISquare(game.moves[variation + 1][varMove].fromX, game.moves[variation + 1][varMove].fromY));
			var oldPos = getPosition(oldSquare);
			var oldWidth = parseInt(oldSquare.offsetWidth);
			var oldHeight = parseInt(oldSquare.offsetHeight);

			var x1 = targPos.x + Math.round(targWidth/2);
			var y1 = targPos.y + Math.round(targHeight/2);
			var xC = oldPos.x + Math.round(oldWidth/2);
			var yC = oldPos.y + Math.round(oldHeight/2);
			this.drawArrow(x1, y1, xC, yC, "#933b57");
		}


	}
	
	this.drawArrow =
	function(x1, y1, xC, yC, color, width) {
		jg.setColor("#000000");
		jg.setStroke(1);  
		var Xpoints = [];
		var Ypoints = [];
		if (x1 == xC) {
			var rotationAngle = 0;
		} else {
			var rotationAngle = - Math.atan((x1 - xC)/(y1 - yC));
		}
		if (y1 == yC) {
			rotationAngle = - rotationAngle;
		} else if (y1 > yC) {
			rotationAngle = Math.PI + rotationAngle;
		}
		var lineAngle = Math.PI/2 + Math.atan(6/20);
		var length = Math.sqrt(20*20 + 6*6);
		var angle = rotationAngle + lineAngle;
		var x2 = x1 + Math.round(length * (Math.cos(angle)));
		var y2 = y1 + Math.round(length * (Math.sin(angle)));
		lineAngle = Math.PI/2 - Math.atan(6/20);
		angle = rotationAngle + lineAngle;
		var x7 = x1 + Math.round(length * (Math.cos(angle)));
		var y7 = y1 + Math.round(length * (Math.sin(angle)));
		length = Math.sqrt(10*10 + 5*5);
		lineAngle = - Math.PI/2 + Math.atan(5/10);
		angle = rotationAngle + lineAngle;
		var x3 = x2 + Math.round(length * (Math.cos(angle)));
		var y3 = y2 + Math.round(length * (Math.sin(angle))); 
		lineAngle = - Math.PI/2 - Math.atan(5/10);
		angle = rotationAngle + lineAngle;
		var x6 = x7 + Math.round(length * (Math.cos(angle)));
		var y6 = y7 + Math.round(length * (Math.sin(angle)));
		length = Math.sqrt((x1 - xC)*(x1 - xC) + (y1 - yC)*(y1 - yC)) - 10;

		lineAngle = Math.PI/2;
		angle = rotationAngle + lineAngle;
		var x4 = x3 + Math.round(length * (Math.cos(angle)));
		var y4 = y6 + Math.round(length * (Math.sin(angle)));
		lineAngle = Math.PI/2;
		angle = rotationAngle + lineAngle;
		var x5 = x6 + Math.round(length * (Math.cos(angle)));
		var y5 = y6 + Math.round(length * (Math.sin(angle)));
		if (y4 == y5 && rotationAngle == -Math.PI/2) {
			y4 = y4 + 1;
			//y5 = y5 + 1;
		}
		Xpoints.push(x1);
		Ypoints.push(y1);
		Xpoints.push(x2);
		Ypoints.push(y2);
		Xpoints.push(x3);
		Ypoints.push(y3);
		//alert(rotationAngle);
		if (y4 == y5 && rotationAngle == Math.PI/2) {
			y4 = y4 - 1;
			y5 = y5 + 1;
		}
		Xpoints.push(x4);
		Ypoints.push(y4);
		Xpoints.push(xC);
		Ypoints.push(yC);
		Xpoints.push(x5);
		Ypoints.push(y5);
		Xpoints.push(x6);
		Ypoints.push(y6);
		Xpoints.push(x7);
		Ypoints.push(y7);
		jg.setColor(color);
		jg.fillPolygon(Xpoints, Ypoints);
		jg.paint();
	}

	// 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};
	}
}
