/*
AVATAR
This file contains javascript logic for the karma chart
It uses the Raphael library to render a chart
*/

Raphael.fn.drawGrid = function (x, y, w, h, wv, hv, color) {
	color = color || "#000";
	var path = ["M", x, y, "L", x + w, y, x + w, y + h, x, y + h, x, y],
	rowHeight = h / hv,
	columnWidth = w / wv;
	for (var i = 1; i < hv; i++) {
		path = path.concat(["M", x, y + i * rowHeight, "L", x + w, y + i * rowHeight]);
	}
	for (var i = 1; i < wv; i++) {
		path = path.concat(["M", x + i * columnWidth, y, "L", x + i * columnWidth, y + h]);
	}
	return this.path(path.join(",")).attr({stroke: color});
};

$(function () {
	$("#data").css({
		position: "absolute",
		left: "-9999em",
		top: "-9999em"
	});
});

window.onload = function () {

	// Grab the data
	var labels = [],
	data = [],
	offsets = [];

	// this array will contain the labels that are used to display details when a user hovers over a plot point
	$("#data tfoot th").each(function () {
		labels.push($(this).html());
	});

	// this array contains the actual karma value that are used to plot the points
	$("#data tbody td").each(function () {
		data.push($(this).html());
	});

	// this array contains the karma direction (up or down) which is used to render red or green dots
	$("#data tbody td").each(function () {
		offsets.push($(this).attr('class'));
	});

	// Draw
	var width = 498,
	height = 170,
	leftgutter = 0,
	bottomgutter = 50,
	topgutter = 20,
	colorhue = .2 || Math.random(),
	color = "hsb(" + [colorhue, 1, .75] + ")",
	r = Raphael("holder", width, height),
	txt = {font: '12px Arial', fill: "#fff"},
	txt1 = {font: '10px Arial', fill: "#fff"},
	txt2 = {font: '12px Arial', fill: "#fff", "text-anchor": "start"},
	txt3 = { font: '11px Arial', fill: "#fff", "text-anchor": "start"},
	max = Math.max.apply(Math, data),
	min = Math.min.apply(Math, data),
	range = max - min,
	Y = (height - bottomgutter - topgutter) / (max);
	X = 25.21; // distance between plot points ( = total grid width / number of cells)
	
	// draw a background grid with a height of 100px, this makes it easy to normalize our values to this scale
	// 19 grid cells equals 20 plot points!
	r.drawGrid(leftgutter + X * .5, topgutter, 19 * X, height - topgutter - bottomgutter, 19, 10, "#eee");
	var path = r.path().attr({stroke: color, "stroke-width": 2, "stroke-linejoin": "round"}),
	bgp = r.path().attr({stroke: "none", opacity: .3, fill: color}).moveTo(leftgutter + X * .5, height - bottomgutter),
	frame = r.rect(10, 10, 100, 20, 5).attr({fill: "#000", stroke: "#474747", "stroke-width": 2}).hide(),
	label = [],
	is_label_visible = false,
	leave_timer,
	blanket = r.set();

	// label[0] is the text block that appears when hovering over a plot point
	label[0] = r.text(60, 10, "").attr(txt).hide();

	// event description label that will change on hover of the plot point. It is placed in a fixed position below the grid
	txtEvent = r.text(10, 145, "Hover the graph to see the activities and rewards").attr(txt2).attr({fill: '#333'}).show();
	// event date and karma delta lavel that will change on hover of the plot point. It is placed in a fixed position below the grid
	txtDate = r.text(10, 160, "Currently showing " + labels.length + " activities").attr(txt3).attr({fill: '#999'}).show();

	// loop through labels
	for (var i = 0, ii = labels.length; i < ii; i++) {
		var y = Math.round(((max - data[i])/range)*100) + topgutter,	// normalize data value and plot it into our grid
		x = Math.round(leftgutter + X * (i + .5)),
		t = r.text(x, height - 6, labels[i]).attr(txt).toBack();
		bgp[i == 0 ? "lineTo" : "cplineTo"](x, y, 10);
		path[i == 0 ? "moveTo" : "cplineTo"](x, y, 10);
		var dot = r.circle(x, y, 5).attr({fill:offsets[i] == 'ko_up' ? color : '#971616', stroke: "#fff"});
		blanket.push(r.rect(leftgutter + X * i, 0, X, height - bottomgutter).attr({stroke: "none", fill: "#fff", opacity: 0}));
		var rect = blanket[blanket.length - 1];
		(function (x, y, data, lbl, dot) {
			var timer, i = 0;
			$(rect.node).hover(function () {
				clearTimeout(leave_timer);
				var newcoord = {x: +x + 7.5, y: y - 19};
				if (newcoord.x + 100 > width) {
					newcoord.x -= 114;
				}

				frame.show().animate({x: newcoord.x, y: newcoord.y}, 200 * is_label_visible);

				// parse the event text and event date from the labels
				// since IE reads tags in uppercase, we will do an extra check where needed
				var caps = false;
				var fullTxt = lbl.split("<small>");
				if (!fullTxt[1]) { fullTxt = lbl.split("<SMALL>"); // IE treats this differently
				caps = true;
				}
				var mainTxt = fullTxt[0];
				var subTxt = caps? fullTxt[1].split("</SMALL>"):fullTxt[1].split("</small>");
				subTxt = subTxt[0];
				
				txtEvent.attr({text: mainTxt}).show();
				txtDate.attr({text: subTxt}).show();

				label[0].attr({text: data + " karma"}).show().animateWith(frame, {x: +newcoord.x + 50, y: +newcoord.y + 12}, 200 * is_label_visible);
				dot.attr("r", 7);
				is_label_visible = true;
			}, function () {
				dot.attr("r", 5);
				leave_timer = setTimeout(function () {
					frame.hide();
					label[0].hide();
					is_label_visible = false;
					// r.safari();
				}, 1);
			});
		})(x, y, data[i], labels[i], dot);
	}
	bgp.lineTo(x, height - bottomgutter).andClose();
	frame.toFront();
	label[0].toFront();
	blanket.toFront();
	// only show the graph after rendering, otherwise the plain data table will be visible for a while
	$("#holder").show();
};
