/**
 * Board management functions for the Futoshiki game.
 */

var gameSize;
var gameDifficulty;
var gameBoard;

var selectedX = -1;
var selectedY = -1;

/**
 * state indicates the place from where the cell value is retrieved:
 *   0: retrieve the value at the beginning of the game.
 *   1: retrieve the value from the final solved board configuration.
 */
function getBoardCellValue(y, x, state) {
	var charsPerLine = gameSize * 2 - 1;

	var offset = 0;
	offset += state * (gameSize * 2 - 1) * charsPerLine;
	offset += y * 2 * charsPerLine + x * 2;
	return gameBoard[offset];
}

function cancelFocus() {
	if ((selectedY != -1) && (selectedX != -1)) {
		document.getElementById('cell-' + selectedY + "-" + selectedX).
			style.backgroundColor = "#ffffff";
	}
	selectedY = -1;
	selectedX = -1;
	document.getElementById('digitsSelector').style.display = "none";
}
window.onresize = cancelFocus;

function getComputedWidth(theElt){
        tmphght = document.getElementById(theElt).offsetWidth;
        if (!tmphght) {
                docObj = document.getElementById(theElt);
                var tmphght1 = document.defaultView.getComputedStyle(docObj, "").getPropertyValue("width");
                tmphght = tmphght1.split('px');
                tmphght = tmphght[0];
        }
        return tmphght;
}

function clicked(y, x) {
	cancelFocus();
	if (getBoardCellValue(y, x, 0) == '.') {
		document.getElementById('cell-' + y + "-" + x).style.backgroundColor = "#eeeeee";
		selectedY = y;
		selectedX = x;
		if (document.getElementById('mclick').selectedIndex == 0) {
			var cellSize = getComputedWidth('boardTable') / gameSize;
			document.getElementById('digitsSelector').style.display = "block";
			document.getElementById('digitsSelector').style.top = 1 + cellSize * y + "px";
			document.getElementById('digitsSelector').style.left =
				(getComputedWidth('board') - getComputedWidth('boardTable')) / 2 + cellSize * x + "px";
		} else {
			var val = document.getElementById('cell-' + y + "-" + x).innerHTML;
			if (val == '') {
				val = "1";
			} else if (val == gameSize) {
				val = "";
			} else {
				val = Math.floor(val) + 1;
			}
			document.getElementById('cell-' + y + "-" + x).innerHTML = val;
			setRedMarkers();

			if (isPuzzleCorrect()) {
				doFinishGame();
			}
		}
	}
}

function kinput(actualkey) {
	if ((selectedY != -1) && (selectedX != -1) && (actualkey >= '0') && (actualkey <= gameSize.toString())) {
		if (actualkey == '0') {
			actualkey = '';
		}
		document.getElementById('cell-' + selectedY + "-" + selectedX).innerHTML = actualkey;
		document.getElementById('cell-' + selectedY + "-" + selectedX).style.color = "#00C000";
		cancelFocus();
		setRedMarkers();

		if (isPuzzleCorrect()) {
			doFinishGame();
		}
	}
}

function kdown(ev) {
	//distinguish between IE's explicit event object (window.event) and Firefox's implicit.
	var evtobj = window.event? event : ev;
	var unicode = evtobj.charCode? evtobj.charCode : evtobj.keyCode;
        var actualkey=String.fromCharCode(unicode);
	if (unicode == 46) {
		actualkey = '0';
	}

	kinput(actualkey);
}
document.onkeypress = kdown;

function isPuzzleCorrect() {
	for (var y = 0; y < gameSize; y++) {
		for (var x = 0; x < gameSize; x++) {
			if (getBoardCellValue(y, x, 1) != document.getElementById('cell-' + y + "-" + x).innerHTML) {
				return false;
			}
		}
	}
	return true;
}

function getBoard(size) {
	var ret = "";
	ret += "<table border='0' cellpadding='3' style='margin:15px auto;text-align:center' id='boardTable'>";
	for (var y = 0; y < size; y++) {
		ret += "<tr>";
		for (var x = 0; x < size; x++) {
			ret += "<td id='cell-" + y + "-" + x +
				"' style='border:" + borderSize + " solid #808080;font-size:32px' onclick='clicked(" +
				y + ", " + x + ")'>";
			ret += "</td>";
			ret += "<td>" +
			       "<img id='arrow-" + y + "-" + x + "v' src='/?page=arrow_v.gif'>" +
			       "</td>";
		}
		ret += "</tr>";
		if (y + 1 < size) {
			ret += "<tr>";
			for (var x = 0; x < size; x++) {
				ret += "<td><img id='arrow-" + y + "-" + x + "h' src='/?page=arrow_h.gif'></td>";
				if (x + 1 < size) {
					ret += "<td></td>";
				}
			}
			ret += "</tr>";
		}
	}
	ret += "</table>";
	return ret;
}

function initBoard(size) {
	gameSize = size;
	var content = "";
	var wpx = 25;
	var hpx = 22;
	for (var x = 1; x <= size; x++) {
		content += "<div style='width:" + wpx + "px;height:" + hpx + "px;display:inline-block;margin:2px 0px;font-size:" + hpx + "px'>" +
			"<a href='javascript:kinput(" + x + ")'>" + x + "</a></div>";
	}
	content += "<div style='width:" + wpx + "px;height:" + hpx + "px;display:inline-block;margin:2px 0px 6px;font-size:" + hpx + "px'>" +
			"<a href='javascript:kinput(0)'>X</a></div>";
	document.getElementById('digitsSelector').innerHTML = content;
}

function getHTTPObject() {
	var xmlhttp;
	try {
		xmlhttp = new ActiveXObject("Msxml2.XMLHTTP");
	} catch (e) {
		try {
			xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
		} catch (E) {
			xmlhttp = false;
		}
	}

	if (!xmlhttp && typeof XMLHttpRequest != 'undefined') {
		try {
			xmlhttp = new XMLHttpRequest();
		} catch (e) {
			xmlhttp = false;
		}
	}

	return xmlhttp;
}

function initGame(gameString) {
	gameBoard = gameString;

	document.getElementById('board').innerHTML = getBoard(gameSize);
	var charsPerLine = gameSize * 2 - 1;
	for (var y = 0; y < gameSize; y++) {
		for (var x = 0; x < gameSize; x++) {
			var offset = y * 2 * charsPerLine + x * 2;
			var val = gameString.charAt(offset);
			if ((val >= 1) && (val <= gameSize)) {
				document.getElementById('cell-' + y + '-' + x).innerHTML = val;
			}
		}
	}
	for (var y = 0; y < gameSize; y++) {
		for (var x = 0; x < gameSize - 1; x++) {
			var offset = y * 2 * charsPerLine + x * 2 + 1;
			var val = gameString.charAt(offset);
			if (val == '(') {
				document.getElementById('arrow-' + y + '-' + x + 'v').src = "/?page=arrow_l0.gif";
			} else if (val == ')') {
				document.getElementById('arrow-' + y + '-' + x + 'v').src = "/?page=arrow_r0.gif";
			}
		}
	}
	for (var y = 0; y < gameSize - 1; y++) {
		for (var x = 0; x < gameSize; x++) {
			var offset = (y * 2 + 1) * charsPerLine + x * 2;
			var val = gameString.charAt(offset);
			if (val == '^') {
				document.getElementById('arrow-' + y + '-' + x + 'h').src = "/?page=arrow_u0.gif";
			} else if (val == 'v') {
				document.getElementById('arrow-' + y + '-' + x + 'h').src = "/?page=arrow_d0.gif";
			}
		}
	}
}

var initialFetch = false;
function fetchGame(difficulty, id) {
	cancelFocus();
	gameDifficulty = difficulty;
	if (typeof(id) === "undefined") {
		id = Math.floor(Math.random() * 10000);
	}

	var http = getHTTPObject();
	http.open("GET", "get.cgi?size=" + gameSize + "&difficulty=" + difficulty + "&id=" + id, true);
	http.onreadystatechange = function() {
		if (http.readyState == 4) {
			if (initialFetch == false) {
				initialFetch = true;
			} else if (_gaq) {
				_gaq.push(['_trackPageview']);
			}
			var xmlDocument = http.responseXML;
			initGame(xmlDocument.getElementsByTagName('game')[0].firstChild.data);
		}
	}

	http.send(null);
	resetInfo();
	document.getElementById('boardEnd').style.display = "none";
}

function showSolution() {
	cancelFocus();
	for (var y = 0; y < gameSize; y++) {
		for (var x = 0; x < gameSize; x++) {
			if (getBoardCellValue(y, x, 0) == '.') {
				document.getElementById('cell-' + y + "-" + x).innerHTML =
					getBoardCellValue(y, x, 1);
			}
		}
	}
	if (_gaq) {
		_gaq.push(['_trackEvent', 'futoshiki', 'viewSolution']);
	}
	doFinishGame();
}

function setRedMarkers() {
	var charsPerLine = gameSize * 2 - 1;
	for (var y = 0; y < gameSize; y++) {
		for (var x = 0; x < gameSize; x++) {
			var val = document.getElementById('cell-' + y + "-" + x).innerHTML;
			if ((val >= 1) && (val <= gameSize) && (getBoardCellValue(y, x, 0) == '.')) {
				document.getElementById('cell-' + y + "-" + x).style.color = "#00C000";
				for (var z = 0; z < gameSize; z++) {
					if (((y != z) && (document.getElementById('cell-' + y + "-" + x).innerHTML ==
							document.getElementById('cell-' + z + "-" + x).innerHTML)) ||
					    ((x != z) && (document.getElementById('cell-' + y + "-" + x).innerHTML ==
							document.getElementById('cell-' + y + "-" + z).innerHTML))) {
						document.getElementById('cell-' + y + "-" + x).style.color = "#f00000";
					}
				}
			}
		}
	}
	for (var y = 0; y < gameSize; y++) {
		for (var x = 0; x < gameSize - 1; x++) {
			var offset = y * 2 * charsPerLine + x * 2 + 1;
			var val = gameBoard.charAt(offset);
			var left = document.getElementById('cell-' + y + "-" + x).innerHTML;
			var right = document.getElementById('cell-' + y + "-" + (x + 1)).innerHTML;
			if ((val == '(') && (left >= '1') && (left <= gameSize.toString()) && (right >= 1) && (right <= gameSize.toString()) &&
				(left >= right)) {
				document.getElementById('arrow-' + y + '-' + x + 'v').src = "/?page=arrow_l1.gif";
			} else if (val == '(') {
				document.getElementById('arrow-' + y + '-' + x + 'v').src = "/?page=arrow_l0.gif";
			}
			if ((val == ')') && (left >= '1') && (left <= gameSize.toString()) && (right >= 1) && (right <= gameSize.toString()) &&
				(left <= right)) {
				document.getElementById('arrow-' + y + '-' + x + 'v').src = "/?page=arrow_r1.gif";
			} else if (val == ')') {
				document.getElementById('arrow-' + y + '-' + x + 'v').src = "/?page=arrow_r0.gif";
			}
		}
	}
	for (var y = 0; y < gameSize - 1; y++) {
		for (var x = 0; x < gameSize; x++) {
			var offset = (y * 2 + 1) * charsPerLine + x * 2;
			var val = gameBoard.charAt(offset);
			var up = document.getElementById('cell-' + y + "-" + x).innerHTML;
			var down = document.getElementById('cell-' + (y + 1) + "-" + x).innerHTML;
			if ((val == '^') && (up >= '1') && (up <= gameSize.toString()) && (down >= 1) && (down <= gameSize.toString()) &&
			    (up >= down)) {
				document.getElementById('arrow-' + y + '-' + x + 'h').src = "/?page=arrow_u1.gif";
			} else if (val == '^') {
				document.getElementById('arrow-' + y + '-' + x + 'h').src = "/?page=arrow_u0.gif";
			}
			if ((val == 'v') && (up >= '1') && (up <= gameSize.toString()) && (down >= 1) && (down <= gameSize.toString()) &&
			    (up <= down)) {
				document.getElementById('arrow-' + y + '-' + x + 'h').src = "/?page=arrow_d1.gif";
			} else if (val == 'v') {
				document.getElementById('arrow-' + y + '-' + x + 'h').src = "/?page=arrow_d0.gif";
			}
		}
	}
}

