function Ease (position) { 
	this.position = position; 
} 
Ease.prototype = { 
	ease : function () { 
		if (this.m == 0 && this.s == -1) { 
			this.moving = false; 
			return this.position; 
		} 
		this.moving = true; 
		this.m += this.s; 
		this.position += (this.d * this.m * .0025); 
		if (this.m == 20) this.s = -1; 
		return this.position; 
	}, 
	setTarget : function (target) { 
		this.target = target; 
		this.m = 0; 
		this.s = 1; 
		this.d = target - this.position; 
	} 
} 
 
var grid = { 
	O : [], 
	M : [], 
	D : {}, 
	screen : { 
		w : 0, 
		h : 0 
	}, 
	m : false, 
	moving: false, 
 
	createHTML : function (id, x, y) { 
		var o = document.createElement('span'); 
		o.className = 'gridSpan'; 
		var p = document.getElementById(id); 
		if (p) o.innerHTML = p.innerHTML; 
		grid.screen.obj.appendChild(o); 
		grid.O.push(o); 
		o.m = false; 
		o.X = x; 
		o.Y = y; 
		o.c = o.childNodes[o.firstChild.nodeType == 3 ? 1 : 0] 
		if (!grid.M[y]) grid.M[y] = []; 
		grid.M[y][x] = o; 
		grid.D[id] = o; 
		o.w = new Ease(20); 
		o.h = new Ease(20); 
		o.x = new Ease(grid.screen.w / 2); 
		o.y = new Ease(grid.screen.h / 2); 
 
		o.onmousedown = function (e) { 
			if (window.event) e = window.event; 
			var tg = (e.target) ? e.target : e.srcElement; 
			if (this != grid.m) { 
				if (grid.m) grid.m.m = false; 
				grid.m = this; 
				grid.position(); 
			} else { 
				if ((tg.tagName == "IMG" || tg.className.indexOf('click') >= 0) && tg.parentNode.tagName != "A") { 
					grid.m = false; 
					grid.position(); 
				} 
			} 
			return false; 
		} 
 
		o.animate = function () { 
			var o   = this.style; 
			o.left   = Math.round(this.x.ease()) + 'px'; 
			o.top    = Math.round(this.y.ease()) + 'px'; 
			o.width  = Math.round(this.w.ease()) + 'px'; 
			o.height = Math.round(this.h.ease()) + 'px'; 
			if (this.x.moving || this.y.moving) grid.moving = true; 
		} 
	}, 
 
	init : function (ids, marg, nw, nh) { 
		this.screen.obj = document.getElementById('screen'); 
		this.ids = ids; 
		this.H = ids.length; 
		this.L = 0; 
		this.marg = marg; 
		this.nw = nw; 
		this.nh = nh; 
		this.resize(); 
		this.screen.obj.onmousedown = function (e) { 
			if (window.event) e = window.event; 
			var tg = (e.target) ? e.target : e.srcElement; 
			if (tg.id == "screen") { 
				grid.m = false; 
				grid.position(); 
			} 
			return false; 
		} 
	}, 
 
	structure : function () { 
		for (var i = 0; i < this.H; i++) this.L = Math.max(this.L, this.ids[i].length); 
		for (var i = 0; i < this.H; i++) { 
			var l = this.ids[i]; 
			for (var j = 0; j < l.length; j++) { 
				var id = l[j]; 
				if (id) this.createHTML(id, j, i); 
			} 
		} 
		grid.init = false; 
		this.resize(); 
	}, 
 
	position : function () { 
		var x = (grid.screen.w - (grid.L * grid.nw)) / 2; 
		var y = (grid.screen.h - (grid.H * grid.nh)) / 2; 
		var i = 0, o; 
		while( o = grid.O[i++] ) { 
			o.w.setTarget(grid.nw - grid.marg); 
			o.h.setTarget(grid.nh - grid.marg); 
			o.x.setTarget(x + grid.marg + o.X * grid.nw); 
			o.y.setTarget(y + grid.marg + o.Y * grid.nh); 
		} 
		if (grid.m) { 
			grid.m.w.setTarget(grid.m.c.offsetWidth); 
			grid.m.h.setTarget(grid.m.c.offsetHeight); 
			grid.m.x.setTarget(grid.marg + (grid.screen.w - grid.m.w.target) / 2); 
			grid.m.y.setTarget(grid.marg + (grid.screen.h - grid.m.h.target) / 2); 
			var y = grid.m.y.target; 
			for (var i = grid.m.Y; i < grid.H; i++) { 
				for (var j = 0; j < grid.L; j++) { 
					var o = grid.M[i][j]; 
					if (o) o.y.setTarget(y); 
				} 
				y += grid.nh; 
			} 
			var y = grid.m.y.target - grid.nh; 
			for (var i = grid.m.Y - 1; i >= 0; i--) { 
				for (var j = 0; j < grid.L; j++) { 
					var o = grid.M[i][j]; 
					if (o) o.y.setTarget(y); 
				} 
				y -= grid.nh; 
			} 
			var y = grid.m.y.target + grid.m.h.target + grid.marg; 
			for (var i = 0; i < grid.H; i++) { 
				var o = grid.M[i][grid.m.X]; 
				if (o) { 
					o.x.setTarget(grid.m.x.target); 
					if (i > grid.m.Y) { 
						o.y.setTarget(y); 
						y += o.h.target + grid.marg; 
					} 
				} 
			} 
			var x = grid.m.x.target - grid.nw; 
			for (var i = grid.m.X - 1; i >= 0; i--) { 
				for (var j = 0; j < grid.H; j++) { 
					var o = grid.M[j][i]; 
					if (o) o.x.setTarget(x); 
				} 
				x -= grid.nw; 
			} 
			var x = grid.m.x.target + grid.m.w.target + grid.marg; 
			for (var i = grid.m.X + 1; i < grid.L; i++) { 
				for (var j = 0; j < grid.H; j++) { 
					var o = grid.M[j][i]; 
					if (o) o.x.setTarget(x); 
				} 
				x += grid.nw; 
			} 
		} 
		if (!grid.sid) grid.sid = setInterval(grid.run, 32); 
	}, 
 
	goto : function (id) { 
		if (grid.D[id]) { 
			if (grid.m) grid.m.m = false; 
			grid.m = grid.D[id]; 
			grid.position(); 
		} 
	}, 
 
	resize : function () { 
		var o = grid.screen.obj; 
		if (o && o.offsetWidth) { 
			grid.screen.h = o.offsetHeight - grid.marg; 
			grid.screen.w = o.offsetWidth - grid.marg; 
			if (!grid.init) grid.position(); else grid.structure(); 
		} else setTimeout(grid.resize, 32); 
	}, 
 
	run : function () { 
		grid.moving = false; 
		var i = 0, o; 
		while( o = grid.O[i++] ) o.animate(); 
		grid.screen.obj.style.backgroundPosition = Math.round(-grid.O[0].x.position * .5) + 'px ' + Math.round(-grid.O[0].y.position * .5) + 'px'; 
		if (!grid.moving && grid.sid) { 
			clearInterval(grid.sid); 
			grid.sid = false; 
		}
	} 
}
