$.clientCoords = function() {
	var dimensions = {
		width : 0,
		height : 0
	};
	if (jQuery.browser.msie) {
		dimensions.width = document.documentElement.offsetWidth;
		dimensions.height = document.documentElement.offsetHeight;
	} else if (window.innerWidth && window.innerHeight) {
		dimensions.width = window.innerWidth;
		dimensions.height = window.innerHeight;
	}
	return dimensions;
}

function box() {

	this.pos = [ 0, 0 ];
	this.dim = [ 0, 0 ];
	this.dynObj = null;
	this.color = null;
	this.element = $("<div class = 'box'></div>");
	$(this.element).css( {
		'position' : 'absolute'
	});
	this.inflation = 0;
	this.origSize = [ 0, 0 ];
	this.lastTime = 0;
	this.inflateTime = 0;
	this.fear = 0;
	this.damping = 1;
	this.startpos = [ 0, 0 ];
	this.page = "";
	this.stop = false;
	this.oldZ = 0;
}

box.prototype.set = function(pos, dim, color) {

	this.pos = [ pos[0], pos[1] ];
	this.dim = [ dim[0], dim[1] ];
	this.color = color + "";

	$(this.element).css( {
		'top' : this.pos[1],
		'left' : this.pos[0],
		'width' : this.dim[0],
		'height' : this.dim[1],
		'background-color' : this.color
	});
};

box.prototype.setPos = function(pos) {
	this.set(pos, this.dim, this.color);
};

box.prototype.setDim = function(dim) {
	this.set(this.pos, dim, this.color);
};

box.prototype.setColor = function(color) {
	this.set(this.pos, this.dim, color);
}

box.prototype.setContent = function(content) {
	$(this.element).html(content);
}

var boxes = [];
var dyn;
var bgw;
var dims;
var divs;
var simopts = {
	"lasttime" : 0
};
var mousepos = [ NaN, NaN ];
var curMouseSpd = [ 0, 0 ];

function step(obj, bgw) {

	var curTime = bgw.getMillisFromStart();
	var interval = curTime - simopts.lasttime;
	simopts.lasttime = curTime;
	dyn.solveLapse(interval);
	var curBox;
	var curDyn;
	for ( var i = 0; i < boxes.length; i++) {
		curBox = boxes[i];
		curDyn = curBox.dob;
		if (!curBox.stop)
			curBox.setPos( [ curDyn.p[0], curDyn.p[1] ]);
	}
}

function mousemovman(time) {
	var delta;
	if (this.time !== undefined) {
		delta = time - this.time;
	} else {
		delta = time;
	}
	this.time = time;
	var mouseDelta = [ 0, 0 ];
	if (delta <= 0)
		return;
	if (isNaN(mousepos[0])||isNaN(mousepos[1])){
		curMouseSpd = [0,0];
		curMouseSpd.len = 0;
		return;
	}
	if (this.lastMousePos !== undefined) {
		mouseDelta = [ mousepos[0] - this.lastMousePos[0],
				mousepos[1] - this.lastMousePos[1] ];
		this.lastMousePos = [mousepos[0], mousepos[1]];
	}else{
		this.lastMousePos = [0,0];
	}
	curMouseSpd = [ mouseDelta[0] / delta, mouseDelta[1] / delta ];
	curMouseSpd.len = Math.sqrt(Math.pow(curMouseSpd[0], 2)+Math.pow(curMouseSpd[1], 2));
	
}

function objectDynFun(object, time) {
	if (object.box.stop)
		return;

	mousemovman(time);

	beahviour(object, time);
	bounceOnBorder(object, time);

	manageInflation(object.box, time);

	object.box.lastTime = time;

}

function beahviour(object, time) {

	object.a[0] = 0;
	object.a[1] = 0;
	// return home
	var rhv = [ object.box.startpos[0] - object.box.pos[0],
			object.box.startpos[1] - object.box.pos[1] ];
	object.a[0] += rhv[0] / 500000;
	object.a[1] += rhv[1] / 500000;

	// fear
	if ((object.box.fear != 0)) {
		if ((!isNaN(mousepos[0])) && (!isNaN(mousepos[1]))) {
			var center = [ object.p[0] + object.box.dim[0] / 2,
					object.p[1] + object.box.dim[1] / 2 ];
			var dvect = [ mousepos[0] - center[0], mousepos[1] - center[1] ];
			var av = [ (0 - dvect[0]) / 500000, (0 - dvect[1]) / 500000 ];
			object.a[0] += av[0] * object.box.fear * curMouseSpd.len;
			object.a[1] += av[1] * object.box.fear * curMouseSpd.len;
		}
	}
	// Speed control
	if ((Math.abs(object.v[0]) > 0.50) || (Math.abs(object.v[1]) > 0.50)) {
		var spd = Math
				.sqrt(Math.pow(object.v[0], 2) + Math.pow(object.v[1], 2));
		var normV = [ 0.5 * object.v[0] / spd, 0.5 * object.v[1] / spd ];
		object.v[0] = normV[0];
		object.v[1] = normV[1];
	}
	object.v[0] = object.v[0] * object.box.damping + 0.3
			* (Math.random() * 0.02 - 0.01);
	object.v[1] = object.v[1] * object.box.damping + 0.3
			* (Math.random() * 0.02 - 0.01);
}

function bounceOnBorder(object, time) {

	var elem = object.box.element;
	var w = $(elem).width();
	var h = $(elem).height();

	if ((object.p[0] + w) > dims.width) {
		object.v[0] = 0 - object.v[0];
		object.p[0] = dims.width - w - 1;
		// inflate(object.box, time);
	}
	if ((object.p[1] + h) > dims.height) {
		object.v[1] = 0 - object.v[1];
		object.p[1] = dims.height - h - 1;
		// inflate(object.box, time);
	}

	if (object.p[0] < 0) {
		object.v[0] = 0 - object.v[0];
		object.p[0] = 0 - object.p[0];
		inflate(object.box, time);
	}
	if (object.p[1] < 0) {
		object.v[1] = 0 - object.v[1];
		object.p[1] = 0 - object.p[1];
		inflate(object.box, time);
	}

}

function manageInflation(abox, time) {
	var rtt = (time - abox.inflateTime) / 2000;

	if (rtt > 1)
		rtt = 1;
	if (rtt < 0)
		rtt = 0;
	if (rtt < 0.01)
		abox.inflation = 1;
	else
		abox.inflation = rtt + (1 - rtt) * abox.inflation;
	var w, h;
	w = abox.origSize[0] * abox.inflation;
	h = abox.origSize[1] * abox.inflation;
	abox.dim[0] = w;
	abox.dim[1] = h;

}

function inflate(abox, start) {

	abox.inflation = 3;
	abox.inflateTime = start;
}

function mousemovebody(event) {
	mousepos[0] = event.clientX;
	mousepos[1] = event.clientY;

}

function mousemoveout(event) {
	mousepos[0] = NaN;
	mousepos[1] = NaN;
}

var contentDivs = [];
function listDivs() {
	var xs = $(".content");
	return xs;
}

function getBaseUrl(href) {
	if (href === undefined)
		return [ "", "" ];
	var i, j;
	for (i = 0; i < href.length; i++) {
		if (href[i] == "#") {
			var k = href.indexOf("arg=");
			j = k + 4;
			break;
		}
	}
	var baseUrl = href.substring(0, i);
	return [ baseUrl, href.substring(j) ];
}

function restoreEvent(event) {
	if (closingBox == null)
		return;
	var elem = closingBox.element;
	$(elem).click(makeCallBack(popIndex, closingBox.title));
	closingBox.stop = false;
	closingBox = null;

}

var closingBox = null;

function closePopup(event) {
	if (popIndex == -1) {
		return;
	}

	var ibox = boxes[popIndex];
	$(ibox.element).html(ibox.oldContent);
	$(ibox.element).css("z-index", ibox.oldZ);
	closingBox = ibox;

	popOn = false;
	$(ibox.element).animate( {
		width : ibox.origSize[0],
		height : ibox.origSize[1]

	}, 1500, "linear", restoreEvent);
}

var popOn = false;
var popIndex = -1;

function popupOpen() {
	var ibox = boxes[popIndex];
	var content = $("<table width='100%' height='100%'><tr height='20px' valign = 'top' align = 'right'><td align = 'left'>"
			+ ibox.title
			+ "</td><td><img id = 'closeImm' src = 'close.png'></td></tr><tr><td colspan = '2' id = 'contTd'><div id = 'inner' style = 'overflow: auto'></div></td></tr></table>");

	var contentDiv = contentDivs[popIndex];
	ibox.page = $(contentDiv).find("span.page").html();

	ibox.oldZ = $(ibox.element).css("z-index");
	$(ibox.element).css("z-index", 900);
	var inners = $(content).find("#inner");
	$(ibox.element).append(content);
	var w = $("#contTd").width();
	var h = $("#contTd").height();
	$(inners[0]).css( {
		width : w * 0.9,
		height : h * 0.90
	});
	$(inners[0]).html(ibox.page);
	$(content).find("#closeImm").click(closePopup);
}

function linkClick(titleAttr, index) {
	if (popOn)
		return;
	var ibox = boxes[index];
	if (ibox.page == null)
		return;
	$(ibox.element).unbind('click');
	popOn = true;
	popIndex = index;
	ibox.stop = true;
	ibox["oldContent"] = $(ibox.element).html();
	$(ibox.element).html("");
	$(ibox.element).animate( {
		width : dims.width * 0.7,
		left : dims.width * 0.175,
		top : "40",
		height : dims.height - 40
	}, 1500, "linear", popupOpen);
}

function makeBoxContent(contentDiv, index) {
	var content = "";
	// content += "<a onclick = 'linkClick(\'"+titleAttr+"\')' href =
	// '"+getBaseUrl(window.location.href)+"#key="+titleAttr+"'>"+
	// titleAttr+"</a>";
	var url = $(contentDiv).find("a").attr('href');
	var titleAttr = $(contentDiv).attr("title");
	linkBoxMap[getBaseUrl(url)[1]] = [ titleAttr, index ];
	boxes[index]['title'] = titleAttr;
	if ((titleAttr !== undefined) && (titleAttr.length != 0))
		content += titleAttr;
	// content += "<a onclick = \"" + "linkClick('" + titleAttr + "',
	// "+index+")" + "\">"
	// + titleAttr + "</a>";

	return content;
}

var linkBoxMap = {};

function makeBox(contentDiv, index) {
	var nbox = new box();
	var pos = [ $(contentDiv).attr('posx') * 1, $(contentDiv).attr('posy') * 1 ];
	var dim = [ $(contentDiv).attr('width') * 1,
			$(contentDiv).attr('height') * 1 ];
	var color = $(contentDiv).attr('color');
	boxes.push(nbox);
	nbox.fear = $(contentDiv).attr('fear') * 1;
	nbox.damping = 0.98;
	nbox.setContent(makeBoxContent(contentDiv, index));
	nbox.page = $(contentDiv).find("span.page").html();
	$("body").append(nbox.element);
	nbox.set(pos, dim, color);
	nbox.origSize = [ dim[0], dim[1] ];
	nbox.startpos = [ pos[0], pos[1] ];
	var dob = dyn.addObj();
	nbox.dob = dob;
	dob.p = [ pos[0], pos[1] ];
	dob.v = [ 0, 0 ];
	dob.govFun = objectDynFun;
	dob.box = nbox;
	return nbox;
}

function makeCallBack(index, title) {
	return function(event) {
		linkClick(title, index);
	};
}

function start(event) {

	$(".hideous").css("display", "none");
	
	$(document).mousemove(mousemovebody);
	$(document).mouseleave(mousemoveout);

	var encoded = $(".base64");
	for ( var i = 0; i < encoded.length; i++) {
		var stringEnc = $(encoded[i]).text();
		var dec = Base64.decode(stringEnc);
		$(encoded[i]).text(dec);
	}
	dims = $.clientCoords();
	dims = {
		'width' : dims.width - 32,
		'height' : dims.height - 32
	};
	dyn = new dynEng();
	divs = listDivs();
	contentDivs = divs;
	for ( var i = 0; i < divs.length; i++) {
		var nbox = makeBox(divs[i], i);
		$(nbox['element']).click(makeCallBack(i, boxes[i]['title']));
	}
	bgw = new BackgroundWorker();
	bgw.setWorker(step, null);

	var links = $(".aTransf");
	for ( var i = 0; i < links.length; i++) {
		var elem = links[i];
		var href = $(elem).attr("href");
		var uc = getBaseUrl(href);
		var index = linkBoxMap[uc[1]][1];
		var name = linkBoxMap[uc[1]][0];
		var link = "javascript: linkClick('" + name + "'," + index + ");";
		$(elem).attr("href", link);
	}
	bgw.startTimed(23);
	if (window.location.href.indexOf("#") != -1) {
		var uc = getBaseUrl(window.location.href);
		var bb = linkBoxMap[uc[1]];
		linkClick(bb[0], bb[1]);
	}
}

