/**
 *	Blob drop
 *	-------------------------
 *	A small game similar to these kind of games.
 *	graphics & code (c) 2004 Peter Nederlof
 *	peterned - http://www.xs4all.nl/~peterned/
 */

window.onload = function() {
	var pane = document.getElementById('blobdrop');
	var blobDrop = new BlobDrop(pane);
	blobDrop.init();
}

blobImages = [];
for(var i=0; i<5; i++) {
	blobImages[i] = new Image();
	blobImages[i].src = 'images/b' + i + '.gif';
}

function BlobDrop(pane) {
	this.scoreLabel = document.getElementById('current');
	this.moveLabel = document.getElementById('move');
	this.blobs = [];
	this.blobsByPos = [];
	this.blobChain = [];
	this.currentType = -1;
	this.score = 0;
	this.pane = pane;
}

/**
 *	Game
 *	-------------------------
 */

BlobDrop.prototype = {
	init:function() {
		var x = 0, y = 0;
		this.dir = [0, 20, 0, -20];
		this.cls = ['t','r','b','l'];

		for(var i=0; i<132; i++) {
			y = Math.floor(i/11) * 20;
			this.blobs[i] = new Blob(this, x, y);
			x = (x+20)%220;
		}
		
		var self = this;
		var getCurrent = function(event){ self.getCurrentBlob(event); };
		var clickCurrent = function(event){ self.clickBlob(event); };

		try {
			this.pane.addEventListener('mousemove', getCurrent, false);
			this.pane.addEventListener('mousedown', clickCurrent, false);	
		} catch(inferiorBrowserException) {
			this.pane.attachEvent('onmousemove', getCurrent);
			this.pane.attachEvent('onmousedown', clickCurrent);
		}
	},

	clickBlob:function(event) {
		var blob, blobs = this.blobChain.length;
		if(blobs < 2) return;
		for(var i=0; i<blobs; i++) {
			blob = this.blobChain[i];
			blob.remove();
			this.shiftRow(blob);
		}

		this.scoreLabel.innerHTML = (this.score += this.currentMove);
		if(!this.hasValidMove() && confirm('Game over.\n\nYou scored ' + this.score + ' points\n\n again?')) {
			window.location.reload(true);
		}
	},

	shiftRow:function(blob) {
		var emptyRow = true;
		for(var i=blob.y-20; i>=0; i-=20) {
			var above = this.getBlob(blob.x, i);
			if(above) {
				emptyRow = false;
				above.moveBy(0, 20);
			}
		}

		if(blob.y == 220 && emptyRow) {
			var item;
			for(var i=blob.x-20; i>=0; i-=20) {
				for(var j=0; j<240; j+= 20) {
					item = this.getBlob(i, j);
					if(item) item.moveBy(20,0);
				}
			}
		}
	},

	getCurrentBlob:function(event) {
		var target = event.target || event.srcElement;
		if(/img/i.test(target.nodeName)) {
			var blob = target.blob;
			if(blob.type != this.currentType) {
				this.currentType = blob.type;
				this.clearBlobs();
				this.blobChain = this.findBlobChain(blob, [], true);
				this.currentMove = Math.pow((this.blobChain.length -1), 2);
				this.moveLabel.innerHTML = this.currentMove;
			}
			return this.currentBlob;
		}	return false;
	},

	findBlobChain:function(blob, chain, show) {
		chain.push(blob);
		blob.checked = true;
		var type = blob.type;
		var x, y, next, cls = '';
		
		for(var i=0; i<4; i++) {
			x = blob.x + this.dir[i];
			y = blob.y + this.dir[(i+3)%4];
			next = this.getBlob(x, y);
			if(next && next.type == type) {
				cls += this.cls[i];
				if(!next.checked)
					this.findBlobChain(next, chain, show);
			}
		}	
		if(show) blob.setClass(cls);
		return chain;
	},

	hasValidMove:function() {
		var blob, valid;
		for(var y=240; y>=0; y-=20) {
			for(var x=220; x>=0; x-=20) {
				blob = this.getBlob(x, y);
				if(!blob) continue;
				valid = this.findBlobChain(blob, [], false);
				for(var i=0; i<valid.length; i++) valid[i].checked = false;
				if(valid.length > 1) return true;
			}
		}	return false;
	},

	clearBlobs:function() {
		for(var i=0; i<this.blobChain.length; i++) {
			this.blobChain[i].clear();
		}	this.blobChain = [];
	},

	setBlob:function(x, y, blob){
		if(!this.blobsByPos[x]) this.blobsByPos[x] = [];
		this.blobsByPos[x][y] = blob;
	},

	getBlob:function(x, y) {
		try {
			return this.blobsByPos[x][y];			
		} catch(e) { return false; }
	}
}

/**
 *	Blobs
 *	-------------------------
 */

function Blob(controller, x, y) {
	this.controller = controller;
	this.type = Math.floor(Math.random()*5);
	this.x = x;
	this.y = y;
	this.init();
	this.register();
}

Blob.prototype = {
	register:function() { this.controller.setBlob(this.x, this.y, this); },
	unregister:function() { this.controller.setBlob(this.x, this.y, false);	},
	init:function() {
		var img = this.element = document.createElement('img');
		img.src = blobImages[this.type].src;
		img.blob = this;
		this.display();
		this.controller.pane.appendChild(img);		
	},

	clear:function() {
		this.setClass('');
		this.checked = false;
	},

	remove:function() {
		this.unregister();
		this.element.style.display = 'none';
	},

	moveBy:function(dx, dy) {
		this.unregister();
		this.x += dx;
		this.y += dy;
		this.display();
		this.register();
	},

	display:function() {
		var css = this.element.style;
		css.left = this.x + 'px';
		css.top = this.y + 'px';
	},

	setClass:function(name) {
		this.element.className = name;
	}
}
