// minesweeper.js - a Javascript/HTML minesweeper game
// By Fredrik Fornwall, fredrikfornwall@gmail.com

function init() {
	NUMBER_OF_ROWS = 18;
	NUMBER_OF_BOMBS = 46;
	TO_DISCOVER = NUMBER_OF_ROWS * NUMBER_OF_ROWS - NUMBER_OF_BOMBS;
	FLAGGED = 0;

	gamePlan = new Array(NUMBER_OF_ROWS);   // gamePlan[i][j] is -1 if bomb, else a number with the number of adjacent bombs
	for (var i = 0; i < NUMBER_OF_ROWS; i++) gamePlan[i] = new Array(NUMBER_OF_ROWS);

	updateTimeInterval = 0;

	timeElement = document.getElementById('timeDisplay');
	bombsElement = document.getElementById('bombsDisplay');
	discoveredElement = document.getElementById('discovered');

	timeElement.appendChild(document.createTextNode('0'));
	discoveredElement.appendChild(document.createTextNode('0 / ' + TO_DISCOVER));
	bombsElement.appendChild(document.createTextNode('0 / ' + NUMBER_OF_BOMBS));

	name = prompt('Welcome to Minesweeper!\nUse shift and click to place flags\nEnter your name:');
	restart();
}

function updateTime() {
	timeElement.replaceChild(document.createTextNode(seconds++), timeElement.lastChild);
}

function updateBombs() {
	bombsElement.replaceChild(document.createTextNode(FLAGGED + ' / ' + NUMBER_OF_BOMBS), bombsElement.lastChild);
}

function updateDiscovered() {
	discoveredElement.replaceChild(document.createTextNode(discovered + ' / ' + TO_DISCOVER), discoveredElement.lastChild);
}


function restart() {
	FLAGGED = 0;
	discovered = 0;
	seconds = 0;
	clearInterval(updateTimeInterval);
	updateTime();
	updateBombs();
	updateDiscovered();

	for (var i = 0; i < NUMBER_OF_ROWS; i++) {
		for (var j = 0; j < NUMBER_OF_ROWS; j++) {
			gamePlan[i][j] = 0;
		}
	}

	var table = document.getElementsByTagName('table')[0];
	if (table) table.parentNode.removeChild(table);

	var newTable = document.createElement('table');
	newTable.setAttribute('class', 'compact');
	var tbody = document.createElement('tbody');
	tbody.setAttribute('id', 'gameView');
	newTable.appendChild(tbody);
	document.getElementsByTagName('div')[1].appendChild(newTable);

	var bombsPlaced = 0;
	while (bombsPlaced < NUMBER_OF_BOMBS) {
		var row = Math.floor(Math.random() * NUMBER_OF_ROWS);
		while (row == NUMBER_OF_ROWS) row = Math.floor(Math.random() * NUMBER_OF_ROWS)
			var col = Math.floor(Math.random() * NUMBER_OF_ROWS);
		while (col == NUMBER_OF_ROWS) col = Math.floor(Math.random() * NUMBER_OF_ROWS)
			if (gamePlan[row][col] != -1) {
				bombsPlaced++;
				gamePlan[row][col] = -1;
			}
	}

	for (var row = 0; row < NUMBER_OF_ROWS; row++) {
		for (var col = 0; col < NUMBER_OF_ROWS; col++) {
			if (gamePlan[row][col] == -1) continue;
			var adjacent = 0;
			for (var i = -1; i <= 1; i++) {
				for (var j = -1; j <= 1; j++) {
					if (row + i >= 0 && row + i < NUMBER_OF_ROWS
							&& col + j >= 0 && col + j < NUMBER_OF_ROWS
							&& !(i == 0 && j == 0) ) {
						if (gamePlan[row + i][col + j] == -1) adjacent++;
					}
				}
			}
			gamePlan[row][col] = adjacent;
		}
	}

	var i = 0;
	for (var row = 0; row < NUMBER_OF_ROWS; row++) {
		var newRow = document.createElement('tr');
		for (var column = 0; column < NUMBER_OF_ROWS; column++) {
			var newColumn = document.createElement('td');
			var image = document.createElement('object');
			image.setAttribute('id', row + column * NUMBER_OF_ROWS);
			image.setAttribute('width', '16');
			image.setAttribute('height', '16');
			image.setAttribute('type', 'image/gif');
			image.setAttribute('data', 'blank.gif');
			image.addEventListener('mousedown', click, false);
			newColumn.appendChild(image);
			newRow.appendChild(newColumn);
			i++;
		}
		tbody.appendChild(newRow);
	}

	updateTimeInterval = setInterval('updateTime()', 1000);
}

function click(e) {
	var i = parseInt(e.target.getAttribute('id'));
	var row = i % NUMBER_OF_ROWS;
	var col = Math.floor(i / NUMBER_OF_ROWS);

	var image = document.createElement('object');
	image.setAttribute('width', '16');
	image.setAttribute('height', '16');
	image.setAttribute('type', 'image/gif');
	if (e.target.getAttribute('data') == './flagged.gif') {
		if (!e.shiftKey) return;
		FLAGGED--;
		updateBombs();
		image.setAttribute('data', './blank.gif');
		image.setAttribute('id', i);
		image.addEventListener('mousedown', click, false);
	} else if (e.shiftKey) {
		FLAGGED++;
		updateBombs();
		image.setAttribute('data', './flagged.gif');
		image.setAttribute('id', i);
		image.addEventListener('mousedown', click, false);
		gameCompleteCheck();
	} else {
		if (gamePlan[row][col] == -1) {
			image.setAttribute('data', './dead.gif');
			e.target.parentNode.replaceChild(image, e.target);
			alert('BOOM!');
			restart();
			return;
		} else {
			if (gamePlan[row][col] == 0) {
				cascade(row, col);
				updateBombs();
				updateDiscovered();
				gameCompleteCheck();
				return;
			} else {
				image.setAttribute('data', './' + gamePlan[row][col] + '.gif');
				discovered++;
				gamePlan[row][col] = - 2;
				updateDiscovered();
				gameCompleteCheck();
			}
		}
	}
	e.target.parentNode.replaceChild(image, e.target);
}

function cascade(row, col) {
	if (gamePlan[row][col] == -2) return;

	var i = row + col * NUMBER_OF_ROWS;
	var element = document.getElementById(i);
	if (element.getAttribute('data') == './flagged.gif') return;

	var image = document.createElement('object');
	image.setAttribute('width', '16');
	image.setAttribute('height', '16');
	image.setAttribute('type', 'image/gif');
	image.setAttribute('data', './' + gamePlan[row][col] + '.gif');
	image.setAttribute('id', i);
	discovered++;
	element.parentNode.replaceChild(image, element);
	gameCompleteCheck();

	if (gamePlan[row][col] == 0) {
		gamePlan[row][col] = -2;
		for (var i = -1; i <= 1; i++) {
			for (var j = -1; j <= 1; j++) {
				if (row + i >= 0 && row + i < NUMBER_OF_ROWS 
						&& col + j >= 0 && col + j < NUMBER_OF_ROWS
						&& !(i == 0 && j == 0) ) {
					cascade(row + i, col + j);
				}
			}
		}
	} else {
		gamePlan[row][col] = -2;
	}
}


function gameCompleteCheck() {
	if (!(discovered == TO_DISCOVER && FLAGGED == NUMBER_OF_BOMBS)) return;

	var form = document.createElement("form");
	form.setAttribute("method", "post");
	form.setAttribute("action", "../highscore/?game=minesweeper");
	form.setAttribute("style", "display: none;");
	document.getElementsByTagName("body").item(0).appendChild(form);

	var nameInput = document.createElement("input");
	nameInput.setAttribute("type", "text");
	nameInput.setAttribute("name", "name");
	nameInput.setAttribute("value", name);
	form.appendChild(nameInput);

	var timeInput = document.createElement("input");
	timeInput.setAttribute("type", "text");
	timeInput.setAttribute("name", "time");
	timeInput.setAttribute("value", seconds);
	form.appendChild(timeInput);

	form.submit();
}
