/*@cc_on
	try { document.execCommand('BackgroundImageCache', false, true); }
	catch(e) {}
@*/

Object.extend(Array.prototype,
{
	indexOf: function(searchElement, fromIndex)
	{
		var l = this.length, i = 0;
		if (fromIndex)
		{
			i = fromIndex;
			if (i < 0)
			{
				i += l;
				if (i < 0) i = 0;
			}
		}

		while (i < l)
		{
			if (this[i] === searchElement) return i;
			i++;
		}

		return -1;
	},
	forEach: function(func, obj)
	{
		for (var i = 0, l = this.length; i < l; i++)
		{
			if (i in this)
				func.call(obj, this[i], i, this);
		}
	},
	filter: function(func, obj)
	{
		var res = [], val;
		for (var i = 0, l = this.length; i < l; i++)
		{
			if (i in this)
			{
				val = this[i]; // in case func mutates this
			        if (func.call(obj, val, i, this))
					res.push(val);
			}
		}

		return res;
	}
});



function Lemming()
{
	if (this == window)
		return new Lemming();

	this.animate = function()
	{
		this[this.ani]();

		if (this.element)
		{
			this.imgleft -= this.imgleft == this.maximgleft ? this.imgleft : 32;
			this.element.style.backgroundPosition = this.imgleft+'px';
			this.element.style.top = this.top+'px';
			this.element.style.left = this.left+'px';

			setTimeout(this.animate, 70);
		}
	}.bind(this);

	this.top = -32;
	this.left = 2 * Math.floor(Math.random() * ((Lemmings.gridwidth - 60) / 2)) + 20;
	this.dx = Math.random() > 0.5 ? 2 : -2;

	this.element = document.createElement('div');
	this.element.style.cssText = 'position:absolute;top:'+this.top+'px;left:'+this.left+'px;height:32px;width:32px;z-index:200;overflow:hidden;';

	this.floater = Math.random() > 0.5;
	this.changeAni('fall');

	Lemmings.layout.appendChild(this.element);

	this.animate();
}

Object.extend(Lemming.prototype,
{
	walk: function()
	{
		this.left += this.dx;

		var row = (this.top / 2) + 15, col = (this.left / 2) + 7, dy = 0;

		if (row && !Lemmings.grid[row][col])
		{
			dy--;
			if (row-- && !Lemmings.grid[row][col])
			{
				dy--;
				if (row-- && !Lemmings.grid[row][col])
				{
					dy--;
					if (row-- && !Lemmings.grid[row][col])
					{
						dy--;
						if (row-- && !Lemmings.grid[row][col])
						{
							dy--;
							if (row-- && !Lemmings.grid[row][col])
							{
								dy--;
								if (row-- && !Lemmings.grid[row][col])
								{
									this.changeDir();
									return;
								}
							}
						}
					}
				}
			}
		}
		else if (Lemmings.grid[++row] && Lemmings.grid[row][col])
		{
			dy++;
			if (Lemmings.grid[++row] && Lemmings.grid[row][col])
			{
				dy++;
				if (Lemmings.grid[++row] && Lemmings.grid[row][col])
				{
					dy++;
					if (Lemmings.grid[++row] && Lemmings.grid[row][col])
					{
						dy++;
						if (Lemmings.grid[++row] && Lemmings.grid[row][col])
						{
							this.top += 6
							this.changeAni('fall');
							return;
						}
					}
				}
			}
		}

		this.top += 2 * dy;

		if (this.left > 8 && this.left < Lemmings.gridwidth - 40 && !Math.floor(Math.random() * 200))
		{
			if (dy <= 0 && (!Lemmings.grid[row] || !Lemmings.grid[row][col+2*this.dx]) && !Math.floor(Math.random() * 4))
				this.changeAni('mine');
			else
				this.changeAni('explode');
		}
	},

	fall: function()
	{
		var row = (this.top / 2) + 16, col = (this.left + this.dx + 14) / 2;

		if (Lemmings.grid[row] && Lemmings.grid[row][col])
		{
			this.top += 2;
			this.anicounter++;

			if (Lemmings.grid[++row] && Lemmings.grid[row][col])
			{
				this.top += 2;
				this.anicounter++;

				if (this.floater && this.anicounter > 16)
					this.changeAni('floatstart');

				return;
			}
		}

		this.changeAni(this.anicounter > 64 ? 'splut' : 'walk');
	},

	floatstart: function()
	{
		var row = (this.top / 2) + 16, col = (this.left + this.dx + 14) / 2;

		if (Lemmings.grid[row] && Lemmings.grid[row][col])
		{
			this.top += 2;

			if (this.imgleft == this.maximgleft)
				this.changeAni('float');
		}
		else
		{
			this.changeAni('walk');
		}
	},

	'float': function()
	{
		var row = (this.top / 2) + 16, col = (this.left + this.dx + 14) / 2;

		if (Lemmings.grid[row] && Lemmings.grid[row][col])
			this.top += 2;
		else
			this.changeAni('walk');
	},

	mine: function()
	{
		if (!this.imgleft)
		{
			if (this.left <= 8 || this.left >= Lemmings.gridwidth - 40)
			{
				this.dx = -this.dx;
				this.changeAni('confused');
			}
			else
			{
				this.top += 4;
				this.left += 4 * this.dx;
			}
		}
		else if (this.imgleft == -64)
		{
			this.makeHole('miner_'+(this.dx > 0 ? 'r' : 'l'), this.top + 8, this.left);

			var row = (this.top / 2) + 16, col = (this.left / 2) + 7;
			if (Lemmings.grid[row] && Lemmings.grid[row][col])
				this.changeAni('fall');
		}
	},

	confused: function()
	{
		if (this.imgleft == this.maximgleft)
		{
			this.changeAni('walk');
		}
	},

	explode: function()
	{
		if (this.imgleft == this.maximgleft)
		{
			this.element.parentNode.removeChild(this.element);
			this.element = null;

			// explosion
			var i = 12;
			while (i--)
				new Spark(this.left+16, this.top+24).fly();

			// make nice hole
			this.makeHole('exploder', this.top + 4, this.left);

			// spawn new lemming
			setTimeout(Lemming, 3000);
		}
	},

	splut: function()
	{
		if (this.imgleft == this.maximgleft)
		{
			this.element.parentNode.removeChild(this.element);
			this.element = null;

			// spawn new lemming
			setTimeout(Lemming, 3000);
		}
	},

	changeAni: function(ani)
	{
		this.ani = ani;
		this.anicounter = 0;
		this.imgleft = 32;
		this.maximgleft = Lemmings.preload[this.ani].num;

		this.element.style.backgroundImage = 'url('+Lemmings.preload[this.ani][this.dx > 0 ? 'r' : 'l'].src+')';
	},

	changeDir: function()
	{
		this.dx = -this.dx;
		this.element.style.backgroundImage = 'url('+Lemmings.preload[this.ani][this.dx > 0 ? 'r' : 'l'].src+')';
	},

	makeHole: function(which, top, left)
	{
		var h = document.createElement('img');
		h.style.cssText = 'position:absolute;z-index:151;top:'+top+'px;left:'+left+'px';
		h.src = Lemmings.preload['hole_'+which].src;
		Lemmings.layout.appendChild(h);

		var hole = Lemmings.holes[which], row = top / 2, col = left / 2, i = 0, j = 0, coords;
		while ((coords = hole[i++]))
		{
			if (coords != -1)
			{
				if (!Lemmings.grid[row])
					Lemmings.grid[row] = [];

				for (j = coords[0]; j < coords[1]; j++)
					Lemmings.grid[row][col+j] = 1;
			}

			row++;
		}
	}
});

function Spark(x,y)
{
	this.x = x;
	this.y = this.firsty = y;

	var a = Math.random() * 6.294;
	var s = Math.min(Math.random() * 5, 4);
	this.dx = s * Math.sin(a);
	this.dy = s * Math.cos(a) - 4;

	var colors = ['#ff0','#0f0','#f00','#00f','#f0f','#0ff'];

	this.spark = document.createElement('div');
	this.spark.style.cssText = 'position:absolute;width:2px;height:2px;overflow:hidden;background:'+colors[Math.floor(Math.random()*colors.length)]+';left:'+x+'px;top:'+y+'px;z-index:250;';

	this.fly = function()
	{
		this.y += this.dy += 0.18;
		this.x += this.dx;

		if (this.y < 0 || this.y > this.firsty + 100)
		{
			this.spark.parentNode.removeChild(this.spark);
			this.spark = null;
		}
		else
		{
			this.spark.style.left = this.x+'px';
			this.spark.style.top = this.y+'px';

			setTimeout(this.fly, 10);
		}
	}.bind(this);

	Lemmings.layout.appendChild(this.spark);
}

function Lemmings(layout,num)
{
		var preloadUrl = './images/l/';

		Lemmings.preload = {};

		[['walk','b',8],['fall','b',4],['explode','s',16],['splut','s',16],['floatstart','b',6],['float','b',8],['build','b',16],['confused','b',8],['mine','b',24]].forEach(
			function(lem)
			{
				Lemmings.preload[lem[0]] = {
					num: -32*(lem[2]-1),
					l: new Image(),
					r: new Image()
				};

				Lemmings.preload[lem[0]].l.src = preloadUrl+'lemming_'+lem[0]+'_'+(lem[1]=='b'?'l':'s')+'.gif';
				Lemmings.preload[lem[0]].r.src = preloadUrl+'lemming_'+lem[0]+'_'+(lem[1]=='b'?'r':'s')+'.gif';
			}
		);

		Lemmings.holes = {
			exploder: [[5,10],[4,11],[3,12],[3,12],[2,13],[2,13],[1,14],[1,14],[1,14],[1,14],[0,15],[0,15],[0,15],[0,15],[0,15],[0,15],[1,14],[1,14],[1,14],[2,13],[3,12],[5,10]],
			miner_l: [[4,12],[3,12],[2,12],[2,12],[2,12],[2,12],[2,12],[2,12],[2,12],[2,12],[3,9],[4,9]],
			miner_r: [[3,11],[3,12],[3,13],[3,13],[3,13],[3,13],[3,13],[3,13],[3,13],[3,13],[6,12],[6,11]]
		};

		for (var hole in Lemmings.holes)
		{
			Lemmings.preload['hole_'+hole] = new Image();
			Lemmings.preload['hole_'+hole].src = preloadUrl+'hole_'+hole+(layout ? '_'+layout : '')+'.gif'
		}

		Lemmings.layout = document.getElementById('lemmings');
		if (Lemmings.layout)
		{
			//var top = document.getElementById('layout_main_top');
			//if (top)
			//{
			//	top.style.position = 'relative';
			//	top.style.zIndex = 150;
			//}

			// define default grid
			Lemmings.grid = [];
			Lemmings.gridwidth = Lemmings.layout.offsetWidth;
			Lemmings.gridheight = 135; /* top ? Math.floor(top.offsetHeight / 2) : 61; */

			for (var y = 0; y < Lemmings.gridheight; y++)
			{
				Lemmings.grid[y] = [];

				for (var x = 2, ex = Math.floor(Lemmings.gridwidth / 2) - 4; x < ex; x++)
				{
					Lemmings.grid[y][x] = 1;
				}
			}

			// spawn lemmings
			num = num || 3;
			var timeout = Math.round(10000 / num);
			var spawn = function()
			{
				Lemming();
				if (--num)
					setTimeout(spawn, timeout);
			}

			setTimeout(spawn, 3000);
		}
}