/*
 * Copyright 2007, Jesse Farmer <farmerje@uchicago.edu>
 * This code is licensed as BY-SA (http://creativecommons.org/licenses/by-sa/3.0/)
 */

Infection = Class.create();

Infection.prototype = {
	initialize: function(n, canvas) {
		this.canvas = canvas;
		this.cells = new Array(n*n);
		this.dim = n;
		
		Event.observe(canvas, 'click', function(e) {
			pos = Position.cumulativeOffset(canvas);
			var canvasX = pos[0];
			var canvasY = pos[1];
			var pointerX = Event.pointerX(e);
			var pointerY = Event.pointerY(e);
			var col = Math.floor((pointerX - canvasX)/20);
			var row = Math.floor((pointerY - canvasY)/20);
			
			this.cells[col + row*this.dim] = (!game.cells[col + row*this.dim]);
			this.draw();	
		}.bindAsEventListener(this), true);
		
	},
	
	cell: function(row, col) {
		if (row < 0 || row >= this.dim || col < 0 || col >= this.dim)
			return false;
		
		return this.cells[row * this.dim + col];
	},
	
	randomize: function() {
		this.cells = this.cells.map(function(i) {
			return (Math.random() * 2 > 1.0);
		});
		
		this.draw();
	},
	
	clear: function() {
		this.cells = this.cells.map(function() {
			return false;
		});
		
		this.draw();
	},

	start: function() {
		if (this.step())
			this.draw();
		new PeriodicalExecuter(function(pe) {
			if (this.step())
				this.draw();
			else
				pe.stop();
		}.bind(this), 0.5);
	},
	
	step: function() {
		var next = this.cells.clone();
		var changed = false;
		for (var row = 0; row < this.dim; row++) {
			for (var col = 0; col < this.dim; col++) {
				var count = 0;
				
				if (this.cell(row+1, col)) count++;
				if (this.cell(row-1, col)) count++;
				if (this.cell(row, col+1)) count++;
				if (this.cell(row, col-1)) count++;
				
				if (this.cells[row*this.dim + col] != count > 1) {
					next[row*this.dim + col] = 1;
					changed = true;
				}
			}
 		}

		this.cells = next;
		return changed;
	},
	
	draw: function() {
		var canvas = this.canvas;
		var ctx = canvas.getContext('2d');
		var width = Math.floor(canvas.width / this.dim);
		var height = Math.floor(canvas.height / this.dim);
		
		ctx.fillStyle = 'white';
	    ctx.fillRect(0, 0, this.dim * width, this.dim * height);
		ctx.fillStyle = 'black';
		
		for (var row = 0; row < this.dim; row++) {
			for (var col = 0; col < this.dim; col++) {
				if (this.cell(row, col)) {
					ctx.fillRect(col*width, row*height, width, height);
				}
			}
		}
		
		ctx.fillStyle = 'grey';
		for (var row = 0; row <= this.dim; row++) {
			ctx.fillRect(0, row*height, this.dim*width, 1);
			for (var col = 0; col <= this.dim; col++) {
				ctx.fillRect(col * width, 0, 1, this.dim*height);
			}
		}
	}
}
