/**************************************
 *		The Blue Duck Collective
 *
 *		UnfitMemes.org | April 2009
 ************************************** 
 */

/*
 * DO NOT CHANGE THIS FILE
 * If you want to change the letters go to model.js
 */

var auto = true;			//animation running?
var width = 80;
var height = 10;
var lifecycle = 4;
var timeoutfactor = 100;
var randompoints = 25;		//random points in initial board

var city;					//current city (cells on board)
var initialcity;			//city shown on page load
var initialchanged;
var newcity;				//new calculated city
var changed;

/*
 * Called on page load (init all the stuff)
 */
function window_onload( page_title ) {
	log("started");
	
	//width = document.getElementById("textfield_width").value;
	//height = document.getElementById("textfield_height").value;
	createInitialBoard(page_title);
	resetTemps();
	resetGame();
}

/*
 * Called ONCE on page load
 */
function createInitialBoard( page_title ) {
	log("createInitialBoard()");
	createModel(page_title);
	createBoard();
}

/*
 * Called on mouse hover on up_table
 * Start animation
 */
function go() {
	if(!auto) {
		log("go()");
		cleanBoard();
		auto=true;
		step();
	}
}

/*
 * Called on mouse hover on down_table
 * Stop animation
 */
function stop() {
	if(auto) {
		log("stop()");
		auto=false;
		resetGame();
	}
}

/*
 * Advance animation (main cycle)
 */
function step() {
	if (auto) {
		calculateNewState();
		renderBoard();
		setTimeout("step();", timeoutfactor * lifecycle);	//calls step again in x miliseconds
	}
}

/*
 * Reset to initial state
 */
function resetGame() {
	log("resetGame()");
	auto = false;
	resetTemps();
	renderInitialBoard();
}

/*
 * Called when the user creates a new cell (double click)
 */
function toggleCell(e) {
	log("toggleCell()");
	var cell;
	//TODO: safari, opera
	try {
		cell = e.target;				//getting the event source in Mozilla Firefox
	} catch (e) {
		cell = window.event.srcElement;	//getting the event source in MSIE
	}
	if (cell.alive == "false") {
		cell.alive = "true";
		cell.style.backgroundColor = "black";
		city[cell.x][cell.y] = true;
	} else {
		cell.alive = "false";
		cell.style.backgroundColor = "white";
		city[cell.x][cell.y] = false;
	}
}

/*
 * Erase board
 */
function cleanBoard() {
	log("cleanBoard()");
	var arena = document.getElementById("playarea");
	for (var y = 0; y < height; y++) {
		var cells = arena.rows[y].cells;
		for (var x = 0; x < width; x++) {
			cells[x].style.backgroundColor = "white";
		}
	}
}

/*
 * Create the table (board)
 */
function createBoard() {
	log("createBoard()");
	var arena = document.getElementById("playarea");

	//delete all rows
	var number_rows = arena.rows.length;
	for (var y = 0; y < number_rows; y++) {
		arena.deleteRow(-1);
	}

	//add all rows
	for (var y = 0; y < height; y++) {
		var row = arena.insertRow(-1);
		for (var x = 0; x < width; x++) {
			var cell = row.insertCell(-1);
			cell.className = "cell";
			cell.innerHTML = "&nbsp;";
			cell.x = x;
			cell.y = y;
			if (city[x][y])
				cell.alive = "true";
			else
				cell.alive = "false";
			cell.onclick = toggleCell;
		}
	}
}

/*
 * Step forward
 */
function calculateNewState() {
	resetTemps();
	for (var y = 0; y < height; y++) {
		for (var x = 0; x < width; x++) {
			var alive_now = city[x][y];
			var alive_then = false;
			var number_neighbors = numberOfNeighbors(x, y);

			if ((alive_now) && (number_neighbors < 2)) {
				alive_then = false;
			} else if ((alive_now) && (number_neighbors > 3)) {
				alive_then = false;
			} else if ((!alive_now) && (number_neighbors == 3))	{
				alive_then = true;
			} else if ((alive_now) && ((number_neighbors == 2) || (number_neighbors == 3))) {
				alive_then = true;
			}
			newcity[x][y] = alive_then;
			changed[x][y] = (alive_now != alive_then);
		}
	}
	updateCity();
}

function updateCity() {
	for (var x = 0; x < width; x++) {
		for (var y = 0; y < height; y++) {
			city[x][y] = newcity[x][y];
		}
	}
}

function resetTemps() {
	for (var x = 0; x < width; x++) {
		for (var y = 0; y < height; y++) {
			newcity[x][y] = false;
			changed[x][y] = false;
		}
	}
}

/*
 * Put new calculated board on screen
 */
function renderBoard() {
	var arena = document.getElementById("playarea");
	for (var y = 0; y < height; y++) {
		var cells = arena.rows[y].cells;
		for (var x = 0; x < width; x++) {
			if (changed[x][y]) {
				cells[x].style.backgroundColor = 
					(city[x][y]) ? "black" : "white";
			}
		}
	}
}

/*
 * Put initial board on screen
 */
function renderInitialBoard() {
	cleanBoard();
	log("renderInitialBoard()");
	
	//get initial board state
	for(var w=0; w < width; w++) {
		for(var r=0; r<height; r++) {
			city[w][r] = initialcity[w][r];
			changed[w][r] = initialchanged[w][r];
		}
	}
	
	//add some randomnessness
	//not needed anymore
	/*
	for (var z=0; z<randompoints; z++) {
		x= Math.floor(Math.random()*width);
		y= Math.floor(Math.random()*height);
		city[x][y] = true;
		changed[x][y] = true;
	}
	*/
	var arena = document.getElementById("playarea");
	for (var y = 0; y < height; y++) {
		var cells = arena.rows[y].cells;
		for (var x = 0; x < width; x++) {
			if (changed[x][y]) {
				cells[x].style.backgroundColor = 
					(city[x][y]) ? "black" : "white";
			}
		}
	}
}

function numberOfNeighbors(x, y) {
	var n = 0;
	if (isCellAlive(x-1, y-1))	n++;
	if (isCellAlive(x-1, y))	n++;
	if (isCellAlive(x-1, y+1))	n++;
	if (isCellAlive(x, y-1))	n++;
	if (isCellAlive(x, y+1))	n++;
	if (isCellAlive(x+1, y-1))	n++;
	if (isCellAlive(x+1, y))	n++;
	if (isCellAlive(x+1, y+1))	n++;
	return n;
}

function isCellAlive(x, y) {
	var alive = false;
	if ((x >= 0) && (x < width) && (y >= 0) && (y < height)) {
		alive = city[x][y];
	} else {
		alive = false;
	}
	return alive;
}

/*
 * Firebug console logging
 */
function log(message) {
	//console.log(message);
}

