// make sure max_reaction > max_dist
var max_dist = 20;
var max_reaction = 140;
var elongationType = "linear";	// see function elongation

var mouseX = 0;
var mouseY = 0;
var canvasPos = {};
var knotenpunkt = [];
var kante = [];

var ctx;
$(function(){
	if($.browser.msie) return;	// no canvas available
	ctx = document.getElementsByTagName("canvas")[0].getContext('2d');
	$(window).mousemove(onDocMouseMove).resize(getCanvasOffset);
	
	getCanvasOffset();
	
	for(var i = 0; i < $("#tags .nodeLinks").length && i < knotenpunkt.length; i++)
	{
		$("#tags .nodeLinks:eq("+i+")").each(function(index, obj)
			{
				// save original position
				obj = $(obj).find("> *");
				$(obj).each( function(index2, link){
					$(link)
						.data("origLeft", parseInt($(link).css("left")))
						.data("origTop", parseInt($(link).css("top")))
					;
					knotenpunkt[i].addChild($(link));
				});
			}
		);
	}
	redraw();
});

	// the order in which nodes are created assigns them to their children, e.g. links
	knotenpunkt[0] = new Knoten("#ffed00",65,115,20);		// yellow
	knotenpunkt[1] = new Knoten("#e2007a",107,207,12);		// reddish
	knotenpunkt[2] = new Knoten("#009ee0",260,238,27);		// blue
	knotenpunkt[3] = new Knoten("#009036",153,66,20);		// green
	knotenpunkt[4] = new Knoten("#ec7205", 250, 115, 20);	// orange
	// top nodes
	knotenpunkt[5] = new Knoten("#009ee0", 190, -12, 20);	// blue
	knotenpunkt[5].isDynamic = false;
	knotenpunkt[6] = new Knoten("#94be0e", 105, -12, 10);	// green
	knotenpunkt[6].isDynamic = false;
	
	kante = [
		new Kante(knotenpunkt[0], knotenpunkt[1]),	// yellow - reddish
		new Kante(knotenpunkt[0], knotenpunkt[3]),	// yellow - green
		new Kante(knotenpunkt[1], knotenpunkt[2]),	// reddish - blue
		new Kante(knotenpunkt[1], knotenpunkt[4]),	// reddish - orange
		new Kante(knotenpunkt[2], knotenpunkt[4]),	// blue - orange
		new Kante(knotenpunkt[3], knotenpunkt[4]),	// green - orange
		new Kante(knotenpunkt[5], knotenpunkt[3]),	// top blue - green
		new Kante(knotenpunkt[5], knotenpunkt[4]),	// top blue - orange
		new Kante(knotenpunkt[6], knotenpunkt[3])	// top green - green
	];
	


function getCanvasOffset()      {canvasPos = $("canvas").offset();}

function redraw()
	{
	cleanup();
	for(var k in knotenpunkt)   {if(knotenpunkt[k].isDynamic) moveKnoten(knotenpunkt[k]);}
	for(var k in kante)         {drawKante(kante[k]);}
	for(var k in knotenpunkt)   {drawKnoten(knotenpunkt[k]);}
	}


function Knoten(color,x,y,size)
	{
	this.color = color;
	this.y     = y;
	this.x     = x;
	this.orig_y   = y;
	this.orig_x   = x;
	this.size  = size;
	this.children = [];
	this.isDynamic = true;	// reacts to mousemove or not
	this.addChild = function(obj) {this.children.push(obj);}
	}

function Kante(Knoten1, Knoten2, color)
    {
	if(color == undefined) color = "#cccccc";
	this.node1 = Knoten1;
	this.node2 = Knoten2;
	this.color = color;
    }

function moveKnoten(punkt)
	{
	var dist = Math.sqrt(Math.pow((mouseX-punkt.orig_x),2) + Math.pow((mouseY-punkt.orig_y),2));
	if(dist < 1)	// avoid division by zero
		return;
	var pixelsInMouseDirection = elongation(dist, elongationType);
	//console.log(pixelsInMouseDirection);

	// translation vector = elongation * unit vector in mouse direction
	punkt.x = punkt.orig_x + (pixelsInMouseDirection * (mouseX-punkt.orig_x)/dist);
	punkt.y = punkt.orig_y + (pixelsInMouseDirection * (mouseY-punkt.orig_y)/dist);
	}

function drawKnoten(knoten)
	{
	ctx.beginPath();  
	ctx.arc(knoten.x,knoten.y,knoten.size,0,2*Math.PI,true);
	ctx.lineWidth = 25;
	ctx.fillStyle = "white";
	ctx.strokeStyle = knoten.color;
	ctx.stroke();
	ctx.fill();
	ctx.closePath();
	for(var i in knoten.children)
	{
		knoten.children[i]
			.css("left", knoten.x - knoten.orig_x + knoten.children[i].data("origLeft"))
			.css("top", knoten.y - knoten.orig_y + knoten.children[i].data("origTop"))
		;
	}
	}

function drawKante(kante)
{
	ctx.beginPath();
	ctx.lineWidth=10;
	ctx.strokeStyle = kante.color;
	ctx.fillStyle = kante.color;
	ctx.moveTo(kante.node1.x, kante.node1.y);
	ctx.lineTo(kante.node2.x, kante.node2.y);
	ctx.stroke();
	ctx.fill();
	ctx.closePath();
}

function onDocMouseMove(e)
	{
	var ev = e ? e : window.event;
	mouseX = ev.clientX - canvasPos.left; // - outerDiv.offsetLeft - canvasDiv.offsetLeft;
	mouseY = ev.clientY - canvasPos.top; // - outerDiv.offsetTop  - canvasDiv.offsetTop;
    if(mouseX>-90 && mouseY<330) redraw();
	}


function cleanup()  {ctx.clearRect(0, 0, 320, 350);}

function elongation(dist, type)
{
	if(dist <= max_dist)
		return dist;		// stay exactly under mouse cursor
	if(dist > max_reaction)
		return 0;	// no reaction

	var x = dist;
	//conditions: f(max_reaction) = 0, f(max_dist) = max_dist
	if(type==undefined || type=="linear")
	{
		// form: f(x) = a*x + b
		return -max_dist/(max_reaction-max_dist) * x + (max_dist*max_reaction)/(max_reaction-max_dist);
	}
	if(type=="quadric")
	{
		// form f(x) = a*(x-b)^2
		return max_dist/Math.pow(max_dist-max_reaction,2) * Math.pow((x - max_reaction),2);
	}
}