/* Copyright 2009-2010 Hugo Camboulive <hugo DOT camboulive AT gmail DOT com>
 * Licensed under a BSD license */

/* Note about canvas multi text line functions :
 * It kinda sucks that the canvas does not provide its own
 * functions. This function considers the input data's width
 * is evenly distributed around characters. A sentence like
 * "AAAAAAAA aaaaaaaa" split in two may pose problem. A rewrite
 * will be necessary, but not a priority */
/* This function returns the number one lines we need to use to
 * write text over a length < maxwidth. It is only completely
 * correct when using a monotype font but should be approximate
 * enough for most uses. Use a margin just in case */
CanvasRenderingContext2D.prototype.measureTextLines = function(str, maxwidth) {
	var pixlen = this.measureText(str).width;
	if (pixlen < maxwidth)
		return 1;
	return str.splitLine(parseInt(maxwidth * str.length / pixlen))[0];
};

/* This function draws text in a multiline way over over a
 * length < maxwidth. It is only completely correct when
 * using a monotype font but should be approximate enough
 * for most uses. Use a margin just in case */
CanvasRenderingContext2D.prototype.fillTextMultiLine = function(str, x, y, maxWidth, lineHeight) {
	lineHeight = lineHeight || 12; /* default spacing = 12 */
	var pixlen = this.measureText(str).width;
	var strings = str.splitLine(parseInt(maxWidth * str.length / pixlen))[1];
	var string_ar = strings.split("\n");
	for(var i = 0 ; i < string_ar.length ; i++) {
		y += lineHeight;
		this.fillText(string_ar[i], x, y);
	}
};

/* Line Splitter Function
 * copyright Stephen Chapman, 19th April 2006
 * you may copy this code but please keep the copyright notice as well */
String.prototype.splitLine = function(n) {
	var b = '';
	var s = this;
	var linecount = 1;
	while (s.length > n) {
		var c = s.substring(0,n);
		var d = c.lastIndexOf(' ');
		var e =c.lastIndexOf('\n');
		if (e != -1)
			d = e;
		if (d == -1)
			d = n;
		b += c.substring(0,d) + '\n';
		linecount += 1;
		s = s.substring(d+1);
	}
	return [linecount, b+s];
};

/*
 * http://stackoverflow.com/questions/1353408/messageformat-in-javascript-parameters-in-localized-ui-strings
 */
String.prototype.format = function() {
    var args = arguments;

    return this.replace(/\{(\d+)\}/g, function() {
        return args[arguments[1]];
    });
};

/* Constructor for a network canvas, we need to give it
 * a canvas ID */
NetworkCanvas = function(canvasid, width, height, names_width, meta, data, commitUrlTemplate, networkUrl, metaUrl, dataUrl) {
	this.canvas = $('#'+canvasid).get(0);
	this.height = height || 600;
	this.width = width || 920;
	this.canvas.width = this.width;
	this.canvas.height = this.height;
	this.commitUrlTemplate = commitUrlTemplate || "https://github.com/{0}/{1}/commit/{2}";
	this.networkUrl = networkUrl || "/";
	this.metaUrl = metaUrl || "network_meta";
	this.dataUrl = dataUrl || "network_data_chunk?nethash=";

	this.names_width = names_width || 100;
	/* more stuff */
	this.xoffset = this.names_width;/* the left column with names is 100 px wide */
	this.yoffset = 40;		/* the two month/day bars at the top take 40px */

	this.dotsMouseOver = [];	/* here we store the dots we can hover */
	this.avatars = {};		/* we store images loaded from gravatars in there */

	this.drawLabels = true;

	this.maxx = - this.width + (this.xoffset * 2);
	/* the +100 is just a margin in case we need to display HEADS */
	this.maxy = - this.height + (this.yoffset * 2) + 100;
	this.loading = false;
	/* we iterate of those colors when drawing branches... later we'll include more */
	this.branchColor = ["black", "red", "blue", "lawngreen", "magenta", "yellow", "orange", "cyan", "hotpink", "peru"];
	this.usersBySpace = [];

	/* Initialize mouse handler */
	this.mouse = new NetworkCanvas.Mouse(this);
	this.mouse.init();
	/* Initialize keyboard handler */
	this.keyboard = new NetworkCanvas.Keyboard(this);
	this.keyboard.init();

	/* Initialize the data loader */
	this.dataManager = new NetworkCanvas.DataManager(this);
	this.dataManager.init(meta, data);
};

NetworkCanvas.prototype = {
	/* The main draw function, it load the context from the canvas
	 * and draws everything on it. It's called everytime we have
	 * to update the graphics. */
	draw: function() {
		/* if the data is not loaded yet, draw nothing */
		if (!this.dataManager.meta)
			return;
		if (!this.dataManager.data)
			return;

		/* retreive the canvas */
		if (this.canvas.getContext){
			var ctx = this.canvas.getContext('2d');
			ctx.font = "small sans-serif";
			this.drawBlocks(ctx);
			/* draw the data points and arrows */
			this.drawData(ctx);
			/* draw the names on the left */
			this.drawNames(ctx);
			/* draw the month bar */
			this.drawMonthBar(ctx);
			/* draw the day bar */
			this.drawDayBar(ctx);
			/* draw the months/days in the two bars */
			this.drawDates(ctx);
			/* hide the first 100px of the months/days bars */
			ctx.fillStyle = "black";
			ctx.fillRect(0,0,this.names_width,20);
			ctx.fillStyle = "rgb(64,64,64)";
			ctx.fillRect(0,20,this.names_width,20);
			if (this.drawDot)
				this.drawHint(ctx, this.drawDot);
		}
	},
	/* Draw a 'hint' when a dot is mouse-hovered
	 * It's basically a rectangle with smooth corners
	 * a gravatar image + name + hash of the commit + comment */
	drawHint: function(ctx, hint) {
		var x = (this.names_width * 2) + (20 * hint.time) - this.xoffset + 10;
		var y = 80 + 20 * hint.space - this.yoffset - 10;
		/* compute the height of the hint box */
		ctx.font = "small sans-serif";
		ctx.fillStyle = "black";
		var txtlen = ctx.measureTextLines(hint.message, 400 - 15 - 15);
		var maxy = 70 + txtlen * 15 + 5;
		/* reposition the hint horizontally */
		if (x + 10 + 400 > this.width) {
			x = this.width - 400 - 10;
		} else if (x + 10 < this.names_width) {
			x = this.names_width + 10;
		} else {
			x += 10;
		}
		/* reposition the hint vertically */
		if (y + 10 + maxy > this.height) {
			/* not enough space under the dot */
			y = Math.max(40, y - 10 - maxy);
		} else if (y < 40) {
			y = 40 + 10;
		} else {
			y += 10;
		}
		/* draw the smoothed rectangle */
		ctx.beginPath();
		ctx.strokeStyle = "black";
		ctx.fillStyle = "white";
		ctx.lineWidth = "2";
		ctx.moveTo(x,y+5);
		ctx.quadraticCurveTo(x, y, x+5, y);
		ctx.lineTo(x + 400 - 5, y);
		ctx.quadraticCurveTo(x + 400, y, x + 400, y + 5);
		ctx.lineTo(x + 400, y + maxy - 5);
		ctx.quadraticCurveTo(x + 400, y + maxy, x + 395, y + maxy);
		ctx.lineTo(x + 5, y + maxy);
		ctx.quadraticCurveTo(x, y + maxy, x, y + maxy - 5);
		ctx.lineTo(x, y + 5);
		ctx.fill();
		ctx.stroke();
		/* Preload the avatar if it hasn't already been loaded */
		if (!this.avatars[hint.gravatar]) {
			this.avatars[hint.gravatar] = new Image();
			this.avatars[hint.gravatar].src = "http://www.gravatar.com/avatar/"+hint.gravatar+"?s=32";
			var ths = this;
			this.avatars[hint.gravatar].onload = function() {
				if (hint == ths.drawDot)
					ctx.drawImage(ths.avatars[hint.gravatar], x + 15, y + 15);
			};
		} else {
			ctx.drawImage(this.avatars[hint.gravatar], x + 15, y + 15);
		}
		/* Add name */
		ctx.fillStyle = "black";
		ctx.font = "medium sans-serif";
		ctx.fillText(hint.author, x + 15 + 32 + 15, y + 35);
		/* Add commit hash */
		ctx.font = "small sans-serif";
		ctx.fillStyle = "grey";
		ctx.fillText(hint.id, x + 15, y + 65);
		/* Add commit message */
		ctx.font = "small sans-serif";
		ctx.fillStyle = "black";
		ctx.fillTextMultiLine(hint.message, x + 15, y + 70, 400 - 15 - 15);
	},
	/* Draw the black month bar at the top of the canvas */
	drawMonthBar: function(ctx) {
		ctx.fillStyle = "black";
		ctx.fillRect(0,0,this.width,20);
	},
	/* Draw the grey day bar just under the month bar */
	drawDayBar: function(ctx) {
		ctx.fillStyle = "rgb(64,64,64)";
		ctx.fillRect(0,20,this.width,20);
	},
	/* Draw a name block in the left bar */
	drawNameBlock: function(ctx, idx) {
		var colors = ["rgb(235,235,255)", "rgb(224,224,255)"];
		var val = this.dataManager.meta.blocks[idx];
		var ystart = 80 + val.start * 20;
		var yend = ystart + val.count * 20;
		
		if ( (ystart - this.yoffset >= 40 && ystart - this.yoffset <= this.height) ||
		     (yend - this.yoffset >= 40 && yend - this.yoffset <= this.height) ) {
			/* draw the background */
			if (this.mouse.lastPoint.y > ystart - this.yoffset &&
				this.mouse.lastPoint.y <= yend - this.yoffset &&
				this.mouse.lastPoint.x <= this.names_width) {
				/* hovered */
				ctx.fillStyle = "rgb(223,223,243)";
				ctx.fillRect(0, ystart - this.yoffset, this.names_width, val.count * 20);
			} else if (idx%2 == 1) {
				/* odd lines */
				ctx.fillStyle = "rgb(224,224,255)";
				ctx.fillRect(0, ystart - this.yoffset, this.names_width, val.count * 20);
			}
			/* draw border */
			ctx.strokeStyle = "rgb(222,222,222)";
			ctx.lineWidth = "1";
			ctx.beginPath();
			ctx.moveTo(this.names_width, ystart - this.yoffset + 0.5);
			ctx.lineTo(0.5, ystart - this.yoffset + 0.5);
			ctx.lineTo(0.5, yend - this.yoffset + 0.5);
			ctx.lineTo(this.names_width, yend - this.yoffset + 0.5);
			ctx.stroke();
			/* draw text */
			ctx.fillStyle = "black";
			ctx.fillText(val.name, 5, (ystart + yend) / 2 - this.yoffset + 5, this.names_width - 10);
		}
	},
	/* Draw the names of each repository owner in the left column */
	drawNames: function(ctx) {
		ctx.save();
		ctx.fillStyle = "rgb(235,235,255)";
		ctx.fillRect(0, 40, this.names_width, this.height - 40)
		for (var i = 0 ; i < this.dataManager.meta.blocks.length ; i++) {
			this.drawNameBlock(ctx, i);
		}
		ctx.restore();
	},
	/* Draw the to the right of each name in the right column */
	drawBlocks: function(ctx) {
		var colors = ["rgb(245,245,255)", "rgb(240,240,255)"];
		var y = 80;
		ctx.save();
		ctx.fillStyle = colors[0];
		ctx.fillRect(this.names_width, 40, this.width - this.names_width, this.height - 40)
		for (var i = 0 ; i < this.dataManager.meta.blocks.length ; i++) {
			var val = this.dataManager.meta.blocks[i];
			var ydest = y + val.count * 20;
			if ( (y - this.yoffset >= 40 && y - this.yoffset <= this.height) ||
			     (ydest - this.yoffset >= 40 && ydest - this.yoffset <= this.height) ) {
				if (i%2 == 1) {
					ctx.fillStyle = colors[1];
					ctx.fillRect(this.names_width, y - this.yoffset, this.width - this.names_width, val.count * 20);
				}
				ctx.lineWidth = "1";
				ctx.strokeStyle = "rgb(222,222,222)";
				ctx.strokeRect(0.5, y - this.yoffset + 0.5, this.width - 0.5, val.count * 20);
			}
			y += val.count * 20;
		}
		ctx.restore();
	},
	/* Draw the dates in the two bars at the top of the canvas
	 * (month in the first bar and day in the second bar */
	drawDates: function(ctx) {
		/* used to transform a month number to a 3 character string */
		var valtomonth = {"01": "Jan", "02": "Feb", "03": "Mar", "04": "Apr", "05": "May", "06": "Jun",
			"07": "Jul", "08": "Aug", "09": "Sep", "10": "Oct", "11": "Nov", "12": "Dec"};
		var olddate;
		var newdate;
		var min = parseInt((this.xoffset - this.names_width)/20);
		if (min <= 0)
			olddate = [1970,1,1];
		else
			olddate = this.dataManager.meta.dates[min - 1].split("-");

		for (var i = parseInt((this.xoffset - this.names_width)/20) ; i <= parseInt((this.xoffset - this.names_width)/20 + 50) ; i++) {
			var val = this.dataManager.meta.dates[i];
			if (!val)
				continue;
			newdate = val.split("-");
			var x = (2 * this.names_width) + 20 * i - this.xoffset;
			/* Check if we need to display a new month */
			if (newdate[0] != olddate[0] || newdate[1] != olddate[1]) {
				ctx.fillStyle = "white";
				ctx.fillText(valtomonth[newdate[1]], x, 15)
			}
			/* Check if we need to display a new day */
			if (newdate[0] != olddate[0] || newdate[1] != olddate[1] || newdate[2] != olddate[2]) {
				ctx.fillStyle = "rgb(192,192,192)";
				ctx.fillText(newdate[2], x, 35)
			}
			olddate = newdate;
		}
	},
	/* Draw a little branch head label under a dot */
	drawHead: function(ctx, label, x, y) {
		ctx.save();
		ctx.font = "10px monospace"
		var size = ctx.measureText(label).width;
		/* draw the shape */
		ctx.beginPath();
		ctx.fillStyle = "black";
		ctx.globalAlpha = 0.8;
		ctx.moveTo(x, y);
		ctx.lineTo(x - 4, y + 10);
		ctx.quadraticCurveTo(x - 8, y + 10, x - 8, y + 15);
		ctx.lineTo(x - 8, y + 15 + size);
		ctx.quadraticCurveTo(x - 8, y + 15 + size + 5, x - 4, y + 15 + size + 5);
		ctx.lineTo(x + 4, y + 15 + size + 5);
		ctx.quadraticCurveTo(x + 8, y + 15 + size + 5, x + 8, y + 15 + size);
		ctx.lineTo(x + 8, y + 15);
		ctx.quadraticCurveTo(x + 8, y + 10, x + 4, y + 10);
		ctx.lineTo(x, y);
		ctx.fill();
		/* print the text */
		ctx.globalAlpha = 1.0;
		ctx.fillStyle = "white";
		ctx.textBaseline = "middle";
		ctx.rotate(Math.PI / 2);
		ctx.fillText(label, y + 15 , - x);
		ctx.rotate(- Math.PI / 2);
		ctx.restore();
		return size + 5 + 15; /* 5 = bottom border, 15 = top border */
	},
	drawDataDots: function(ctx) {
		this.dotsMouseOver = [];
		/* Draw all the dots */
		for (var i = parseInt((this.xoffset - this.names_width)/20) ; i <= parseInt((this.xoffset - this.names_width + this.width)/20) ; i++) {
			var val = this.dataManager.getCommit(i);
			if (!val)
				continue;
			var x = (this.names_width * 2) + (20 * val.time) - this.xoffset + 10;
			var y = 80 + 20 * val.space - this.yoffset - 10;
			/* draw the dot */
			if (x > this.names_width - 20 && x < this.width + 20 && y > 20 && y < this.height + 20) {
				ctx.beginPath();
				if (val == this.drawDot) {
					/* we are hovering a dot, draw it bigger
					 * and add a hint */
					ctx.fillStyle = "white";
					ctx.arc(x, y, 6, 0, (Math.PI * 2), false);
					ctx.fill();
					ctx.beginPath();
					ctx.fillStyle = this.branchColor[(val.space-1)%this.branchColor.length];
					ctx.arc(x, y, 5, 0, (Math.PI * 2), false);
					ctx.fill();
				} else {
					/* only draw a small dot */
					ctx.fillStyle = this.branchColor[(val.space-1)%this.branchColor.length];
					ctx.arc(x, y, 3, 0, (Math.PI * 2), false);
					ctx.fill();
				}
				/* add the data to the array of dotsmouseover */
				this.dotsMouseOver.push({"x":x, "y": y, "val": val});
			}
		}
	},
	drawDataHeads: function(ctx) {
		/* Draw all the HEADS */
		for (var i = parseInt((this.xoffset - this.names_width)/20) ; i <= parseInt((this.xoffset - this.names_width + this.width)/20) ; i++) {
			var val = this.dataManager.getCommit(i);
			if (!val)
				continue;
			var x = (this.names_width * 2) + (20 * val.time) - this.xoffset + 10;
			var y = 80 + 20 * val.space - this.yoffset - 10;
			var yhead = y + 5;
			var user = this.usersBySpace[0];
			if(!user)
				continue;
			var userName = user.name;
			if (this.dataManager.heads[userName] && this.dataManager.heads[userName][val.id]) {
				for (var j = 0 ; j < this.dataManager.heads[userName][val.id].length ; j++) {
					var label = this.dataManager.heads[userName][val.id][j];
					yhead += this.drawHead(ctx, label, x, yhead) + 5;
				}
			}
		}
	},
	drawDataLinks: function(ctx) {
		/* draw points */
		var displaycount = 0;
		for (var i = this.dataManager.meta.dates.length - 1; i >= parseInt((this.xoffset - this.names_width)/20) ; i--) {
			var val = this.dataManager.getCommit(i);
			if (!val)
				continue;
			var x = (this.names_width * 2) + (20 * val.time) - this.xoffset + 10;
			var y = 80 + 20 * val.space - this.yoffset - 10;
			ctx.strokeStyle = this.branchColor[(val.space-1)%this.branchColor.length];
			ctx.lineWidth = 2;

			var middle_used = false;
			for (var j = 0 ; j < val.parents.length ; j++) {
				var parnt = val.parents[j];
				if (parnt[2] == val.space) {
					middle_used = true;
				}
			}
			/* for each dot, we ~may~ have to draw the line/arrow
			 * to its parent. */
			for (var j = 0 ; j < val.parents.length ; j++) {
				var parnt = val.parents[j];
				var xdest = (this.names_width * 2) + (20 * parnt[1]) - this.xoffset + 10;
				var ydest = 80 + 20 * parnt[2] - this.yoffset - 10;
				/* Check if the line can be seen */
				if (!this.needToDrawLine(x, y, xdest, ydest))
					continue;
				/* here we can draw different type of lines/arrows */
				if (parnt[2] == val.space) {
					/* the dots are on the same line,
					 * we only draw a line */
					ctx.beginPath();
					ctx.strokeStyle = this.branchColor[(val.space-1)%this.branchColor.length];
					ctx.moveTo(x - 5, y);
					ctx.lineTo(xdest + 5, y);
					ctx.stroke();
				} else if (parnt[2] > val.space) {
					/* the parent is > than the current
					 * this will be a merge arrow */
					ctx.beginPath();
					ctx.lineWidth = 2;
					ctx.strokeStyle = this.branchColor[(parnt[2]-1)%this.branchColor.length];
					ctx.fillStyle = this.branchColor[(parnt[2]-1)%this.branchColor.length];
					ctx.moveTo(xdest + 5, ydest);
					ctx.lineTo(x - 11, ydest);
					ctx.lineTo(x - 11, y + 13);
					ctx.lineTo(x - 9, y + 9);
					ctx.stroke();
					/* draw arrowhead */
					ctx.beginPath();
					ctx.lineWidth = 1;
					ctx.moveTo(x - 5, y + 5);
					ctx.lineTo(x - 13, y + 8);
					ctx.lineTo(x - 7, y + 14);
					ctx.lineTo(x - 5, y + 5);
					ctx.fill();
				} else {
					/* the parent is < the current, this
					 * will be a fork arrow */
					if (middle_used == false) {
						ctx.beginPath();
						ctx.strokeStyle = this.branchColor[(val.space-1)%this.branchColor.length];
						ctx.fillStyle = this.branchColor[(val.space-1)%this.branchColor.length];
						/* draw arrowhead */
						ctx.lineWidth = 1;
						ctx.moveTo(x - 5, y);
						ctx.lineTo(x - 5 - 9, y - 3.5);
						ctx.lineTo(x - 5 - 9, y + 3.5);
						ctx.lineTo(x - 5, y);
						ctx.fill();
						/* draw lines */
						ctx.beginPath();
						ctx.lineWidth = 2;
						ctx.moveTo(x - 5 - 8, y);
						ctx.lineTo(xdest, y);
						ctx.lineTo(xdest, ydest + 5);
						ctx.stroke();
					} else {
						ctx.beginPath();
						ctx.lineWidth = 2;
						ctx.strokeStyle = this.branchColor[(val.space-1)%this.branchColor.length];
						ctx.fillStyle = this.branchColor[(val.space-1)%this.branchColor.length];
						ctx.moveTo(xdest, ydest + 5);
						ctx.lineTo(xdest, y - 12);
						ctx.lineTo(x - 12, y - 12);
						ctx.lineTo(x - 9, y - 9);
						ctx.stroke();
						/* draw arrowhead */
						ctx.beginPath();
						ctx.lineWidth = 1;
						ctx.moveTo(x - 5, y - 5);
						ctx.lineTo(x - 13, y - 8);
						ctx.lineTo(x - 7, y - 14);
						ctx.lineTo(x - 5, y - 5);
						ctx.fill();
					}
				}
			}
		}
	},
	/* Draw the dots and arrows / links in the canvas.
	 * We may also draw a hint if a dot is hovered */
	drawData: function(ctx) {
		this.drawDataLinks(ctx);
		this.drawDataDots(ctx);
		if (this.drawLabels)
			this.drawDataHeads(ctx);
	},
	/* Calculate if we will need to draw an arrow (two segments)
	 * in this canvas (the whole data is bigger than the canvas, so
	 * we can't afford to draw everything, especially on big graphs) */
	needToDrawLine: function(xorig, yorig, xdest, ydest) {
		/* both dots are higher than the canvas, no need to draw */
		if (xorig < this.names_width && xdest < this.names_width)
			return false;
		/* both dots are lower than the canvas, no need to draw */
		if (xorig > this.width && xdest > this.width)
			return false;
		/* both dots are lefter than the canvas, no need to draw */
		if (yorig < 40 && ydest < 40)
			return false;
		/* both dots are righter than the canvas, no need to draw */
		if (yorig > this.height && ydest > this.height)
			return false;
		/* those two are a bit trickier, but work */
		/*if ( (xorig < xmin || xorig > xmax) && (ydest < ymin || ydest > ymax) )
			return false;
		if ( (xdest < xmin || xdest > xmax) && (yorig < ymin || yorig > ymax) )
			return false;*/
		/* if we are here, we have to draw */
		return true;
	}
};

/******* Here starts the data loading mechanics *******/
NetworkCanvas.DataManager = function(c) {
	this.canvas = c;
	this.meta;			/* the metadata loaded from 'network_meta' file */
	this.data = [];			/* the data loaded from 'network_data?nethash=<hash>&start=<s>&end=<e> */
	this.heads = {};
	this.loading = [];
};

NetworkCanvas.DataManager.prototype = {
	init: function(meta, data) {
		var ths = this;
		if (meta != null && data != null) {
			this.meta = meta;
			this.parseMeta();
			this.canvas.xoffset = ths.canvas.names_width + ths.meta.focus * 20;
			this.loadStartData(data);
		} else {
			$.getJSON(ths.canvas.metaUrl, function(metadata) {
				ths.meta = metadata;
				ths.parseMeta();
				ths.canvas.xoffset = ths.canvas.names_width + ths.meta.focus * 20;
				ths.loadStartData();
			});
		}
	},
	/* Compute the max width and height of the data inside the
	 * canvas so we can block scrolling when going too far
	 * We also put the HEADS in an associative array */
	parseMeta: function() {
		/* each user can take 20px * X in height */
		for (var i = 0 ; i < this.meta.blocks.length ; i++) {
			this.canvas.maxy += 20 * this.meta.blocks[i].count;
			for (var j = 0 ; j < this.meta.blocks[i].count ; j++) {
				this.canvas.usersBySpace[this.meta.blocks[i].start + j] = this.meta.users[i];
			}
		}
		/* each column takes 20px */
		this.canvas.maxx = 100 + (this.meta.dates.length * 20);
		/* parse the heads */
		for (var i = 0 ; i < this.meta.users.length ; i++) {
			var val = this.meta.users[i];
			if(!this.heads[val.name])
				this.heads[val.name] = {};
			for (var j = 0 ; j < val.heads.length ; j++) {
				var head = val.heads[j];
				if (!this.heads[val.name][head.id])
					this.heads[val.name][head.id] = [];
				this.heads[val.name][head.id].push(head.name);
			}
		}
	},
	parseDataChunk: function(chunk) {
		for (var i = 0 ; i < chunk.commits.length ; i++) {
			var commit = chunk.commits[i];
			this.data[commit.time] = commit;
		}
	},
	loadStartData: function(data) {
		var ths = this;
		if (data) {
			ths.parseDataChunk(data);
			ths.canvas.draw();
		} else {
			$.getJSON(ths.canvas.dataUrl+ths.meta.nethash+"&start="+ths.meta.focus, function(chunk) {
				ths.parseDataChunk(chunk);
				ths.canvas.draw();
			});
		}
	},
	getCommit: function(i) {
		var ths = this;
		/* if there is no existing data loaded */
		if (!this.data[i] && i < this.meta.dates.length && i >= 0 && (!this.loading[i] || this.loading[i] == false)) {
			var start;
			if (i >= 1 && this.data[i - 1]) {
				/* there is something on the left */
				start = i;
			} else {
				start = Math.max(i - 100, 0);
			}
			var end = Math.min(start + 100, this.meta.dates.length - 1);
			for (var j = start ; j <= end ; j++) {
				this.loading[j] = true;
			}
			if (!this.canvas.loading) {
				this.loadData();
			}
		}
		return this.data[i];
	},
	loadData: function() {
		var ths = this;
		var len = 0;
		this.canvas.loading = true;

		for (var i = 0 ; i < this.loading.length ; i++)
			if (this.loading[i] && !this.data[i])
				len++;
		
		var prevLen = 0;
		while(len > 0 && len != prevLen) {
			prevLen = len;
			var end = this.loading.length - 1;
			while (!this.loading[end] || this.data[end]) {
				end--;
			}
			var start = end;
			while (start > 0 && this.loading[start] && end - start < 100 && !this.data[start])
				start--;

			$.ajax({
				async: false,
				dataType: "json",
				url: ths.canvas.dataUrl+this.meta.nethash+"&start="+start+'&end='+end,
				success: function(d) {
					ths.parseDataChunk(d);
					ths.canvas.draw();
				}
			});

			for (var i = end; i >= start ; i--)
				this.loading[i] = false;
			len = 0;
			for (var i = 0 ; i < this.loading.length ; i++)
				if (this.loading[i] && !this.data[i])
					len++;
		}
		this.canvas.loading = false;
	}
};

/******* Here starts the mouse management mechanics *******/
NetworkCanvas.Mouse = function(c) {
	this.dragging = false;		/* is the mouse button pressed right now? */
	this.lastPoint = {"x":0, "y":0}; /* last coords of the mouse */
	this.drawDot = false;		/* the dot that we are hovering */
	this.canvas = c;
	/* once the onmouse* are bound to the canvas, the parent is the canvas
	 * so we can't access this.*, we have to use a variable local to the
	 * constructor that references itself. Funny stuff */
	var parnt = this;

	/* When the mouse button is pressed, we start dragging */
	this.down = function(e) {
		parnt.lastPoint.x = e.pageX - e.target.offsetLeft;
		parnt.lastPoint.y = e.pageY - e.target.offsetTop;
		/* if we clicked on a dot, open commit in new window */
		if (parnt.canvas.drawDot) {
			var user = parnt.canvas.usersBySpace[parnt.canvas.drawDot.space - 1];
			window.open(parnt.canvas.commitUrlTemplate.format(user.name, user.repo, parnt.canvas.drawDot.id));
		}
		/* if we clicked on a name, go to network for this person */
		if (parnt.lastPoint.x < parnt.canvas.names_width && parnt.lastPoint.y > 40) {
			for (var i = 0 ; i < parnt.canvas.dataManager.meta.blocks.length ; i++) {
				var val = parnt.canvas.dataManager.meta.blocks[i];
				var ystart = 80 + val.start * 20;
				var yend = ystart + val.count * 20;
				if ((ystart - parnt.canvas.yoffset <= parnt.lastPoint.y && yend - parnt.canvas.yoffset >= parnt.lastPoint.y)) {
					var user = parnt.canvas.dataManager.meta.users[i];
					window.open(parnt.canvas.networkUrl);
				}
			}
		}
		parnt.dragging = true;
	};
	/* When the mouse button is released, we stop the dragging */
	this.up = function(e) {
		parnt.dragging = false;
	};
	/* When the mouse goes out of the canvas, we stop dragging */
	this.out = function(e) {
		parnt.dragging = false;
	};
	/* When the mouse cursor is moved, we either :
	 * - move the data displayed in the canvas left/up/down/right
	 *   if the button is pressed (dragging)
	 * - check if we are hovering a dot so we can display a hint */
	this.move = function(e) {
		var needRedraw = false;
		var end = 0;
		var x = e.pageX - e.target.offsetLeft;
		var y = e.pageY - e.target.offsetTop;
		/* Movement while the mouse button is pressed = scrolling */
		if (parnt.dragging) {
			var dx = x - parnt.lastPoint.x;
			var dy = y - parnt.lastPoint.y;
			/* limit left <-> right scrolling */
			parnt.canvas.xoffset -= dx;
			if (parnt.canvas.xoffset < parnt.canvas.names_width)
				parnt.canvas.xoffset = parnt.canvas.names_width;
			if (parnt.canvas.xoffset > parnt.canvas.maxx)
				parnt.canvas.xoffset = parnt.canvas.maxx;
			/* limit up <-> down scrolling */
			parnt.canvas.yoffset -= dy;
			if (parnt.canvas.yoffset > parnt.canvas.maxy)
				parnt.canvas.yoffset = parnt.canvas.maxy;
			if (parnt.canvas.yoffset < 40)
				parnt.canvas.yoffset = 40;

			needRedraw = true;
		} else {
			/* if we're not scrolling, check for mouseovers */
			/* check names (left column) mouseovers */
			if (x <= parnt.canvas.names_width && y > 40) {
				parnt.cursorOnNames = true;
				parnt.canvas.canvas.style.cursor = 'pointer';
				needRedraw = true;
			} else if (parnt.cursorOnNames == true) {
				parnt.cursorOnNames = false;
				needRedraw = true;
				parnt.canvas.canvas.style.cursor = 'default';
			}
			/* check dots mouseovers */
			var found = false;
			for (var i = 0 ; i < parnt.canvas.dotsMouseOver.length ; i++) {
				var val = parnt.canvas.dotsMouseOver[i];
				if (found == false) {
					if (Math.abs((x - e.target.offsetParent.offsetLeft) - val.x) <= 5) {
						if (Math.abs((y - e.target.offsetParent.offsetTop) - val.y) <= 5) {
							found = val.val;
							break;
						}
					}
				}
			}
			if (parnt.canvas.drawDot != found) {
				/* Change the mouse so that we know we are on a link */
				if (found == false) {
					parnt.canvas.canvas.style.cursor ='default';
				} else {
					parnt.canvas.canvas.style.cursor ='pointer';
				}
				parnt.canvas.drawDot = found;
				needRedraw = true;
			}
		}
		if (needRedraw) {
			parnt.lastPoint.x = x;
			parnt.lastPoint.y = y;
			parnt.canvas.draw();
		}
	}
};

NetworkCanvas.Mouse.prototype = {
	init: function() {
		this.canvas.canvas.onmouseup = this.up;
		this.canvas.canvas.onmousedown = this.down;
		this.canvas.canvas.onmousemove = this.move;
		this.canvas.canvas.onmouseout = this.out;
	}
};

/******* Here starts the keyboard management mechanics *******/
NetworkCanvas.Keyboard = function(c) {
	this.canvas = c;
	var parnt = this;
	this.down = function(e) {
		var needRedraw = false;
		if (e.shiftKey) {
			switch(e.which) {
				case 72:	/* H */
				case 37:	/* <- */
					parnt.canvas.xoffset = 0;
					needRedraw = true;
					break;
				case 75:	/* K */
				case 38:	/* UP */
					parnt.canvas.yoffset = 0;
					needRedraw = true;
					break;
				case 76:	/* L */
				case 39:	/* -> */
					parnt.canvas.xoffset = parnt.canvas.maxx - (parnt.canvas.width - parnt.canvas.names_width);
					needRedraw = true;
					break;
				case 74:	/* J */
				case 40:	/* DOWN */
					parnt.canvas.yoffset = parnt.canvas.maxy;
					needRedraw = true;
					break;
			}
		} else {
			switch(e.which) {
				case 72:	/* H */
				case 37:	/* <- */
					parnt.canvas.xoffset -= 100;
					needRedraw = true;
					break;
				case 75:	/* K */
				case 38:	/* UP */
					parnt.canvas.yoffset -= 20;
					needRedraw = true;
					break;
				case 76:	/* L */
				case 39:	/* -> */
					parnt.canvas.xoffset += 100;
					needRedraw = true;
					break;
				case 74:	/* J */
				case 40:	/* DOWN */
					parnt.canvas.yoffset += 20;
					needRedraw = true;
					break;
				case 84:	/* T */
					parnt.canvas.drawLabels = !parnt.canvas.drawLabels;
					needRedraw = true;
					break;
			}
		}

		if (parnt.canvas.xoffset < parnt.canvas.names_width)
			parnt.canvas.xoffset = parnt.canvas.names_width;
		if (parnt.canvas.xoffset > parnt.canvas.maxx)
			parnt.canvas.xoffset = parnt.canvas.maxx;
		/* limit up <-> down scrolling */
		if (parnt.canvas.yoffset > parnt.canvas.maxy)
			parnt.canvas.yoffset = parnt.canvas.maxy;
		if (parnt.canvas.yoffset < 40)
			parnt.canvas.yoffset = 40;

		if (needRedraw) {
			parnt.canvas.draw();
		}
	};
};

NetworkCanvas.Keyboard.prototype = {
	init: function() {
		$(document).keydown(this.down);
	}
};
