/*global $:false, _:false, Morris:false, CodeMirror:false, __report:false, __history:false */
/*jshint browser:true*/

$(function() {
	'use strict';

  // bootstrap popover
	$('[rel=popover]').popover();

	_.templateSettings = {
		interpolate: /\{\{(.+?)\}\}/g
	};

	function focusFragment() {
		$('.plato-mark').removeClass('focus');
		var markId = window.location.hash.substr(1);
		if (markId) $('.' + markId).addClass('focus');
		return focusFragment;
	}

	window.onhashchange = focusFragment();

	var srcEl = document.getElementById('file-source');

	var options = {
		lineNumbers: true,
		gutters: ['plato-gutter-jshint', 'plato-gutter-complexity'],
		readOnly: 'nocursor'
	};


	var cm = CodeMirror.fromTextArea(srcEl, options);

	var byComplexity = [],
		bySloc = [];

	var popoverTemplate = _.template($('#complexity-popover-template').text());
	var gutterIcon = $('<a><i class="plato-gutter-icon icon-cog"></i></a>');

	var popovers = cm.operation(function() {
		var queuedPopovers = [];
		__report.complexity.functions.forEach(function(fn, i) {
			byComplexity.push({
				label: fn.name,
				value: fn.complexity.cyclomatic
			});
			bySloc.push({
				label: fn.name,
				value: fn.complexity.sloc.physical,
				formatter: function(x) {
					return x + ' lines';
				}
			});

			var name = fn.name === '<anonymous>' ? 'function\\s*\\([^)]*\\)' : fn.name;
			var line = fn.line - 1;
			var className = 'plato-mark-fn-' + i;
			var gutter = {
				gutterId: 'plato-gutter-complexity',
				el: gutterIcon.clone().attr('name', className)[0]
			};
			var popover = {
				type: 'popover',
				title: fn.name === '<anonymous>' ? '&lt;anonymous&gt;' : 'function ' + fn.name + '',
				content: popoverTemplate(fn)
			};

			console.log(fn);

			console.log(line,name, className, gutter, popover);

			queuedPopovers.push(cm.markPopoverText({
				line: line,
				ch: 0
			}, name, className, gutter, popover));
		});
		return queuedPopovers;
	});

	popovers.forEach(function(fn) {
		fn();
	});

	var scrollToLine = function(i) {
		var origScroll = [window.pageXOffset, window.pageYOffset];
		window.location.hash = '#plato-mark-fn-' + i;
		window.scrollTo(origScroll[0], origScroll[1]);
		var line = __report.complexity.functions[i].line;
		var coords = cm.charCoords({
			line: line,
			ch: 0
		});
		$('body,html').animate({
			scrollTop: coords.top - 50
		}, 250);
	};

  // yield to the browser
	setTimeout(function() {
		drawFunctionCharts([{
			element: 'fn-by-complexity',
			data: byComplexity
		}, {
			element: 'fn-by-sloc',
			data: bySloc
		}]);
		drawHistoricalCharts(__history);
	}, 0);

	cm.operation(function() {
		addLintMessages(__report);
	});


	function drawFunctionCharts(charts) {
		charts.forEach(function(chart) {
			Morris.Donut(chart).on('click', scrollToLine);
		});
	}

	function drawHistoricalCharts(history) {
		$('.historical.chart').empty();
		var data = _.map(history, function(record) {
			var date = new Date(record.date);
			return {
				date: date.getFullYear() + '-' + (date.getMonth() + 1) + '-' + date.getDate(),
				maintainability: parseFloat(record.maintainability).toFixed(2),
				sloc: record.sloc
			};
		}).slice(-20);
		Morris.Line({
			element: 'chart_historical_sloc',
			data: data,
			xkey: 'date',
			ykeys: ['sloc'],
			labels: ['Lines of Code'],
			parseTime: false
		});
		Morris.Line({
			element: 'chart_historical_maint',
			data: data,
			xkey: 'date',
			ykeys: ['maintainability'],
			labels: ['Maintainability'],
			ymax: 100,
			parseTime: false
		});
	}

	function addLintMessages(report) {
		var lines = {};

		console.log(report);

		report.eslint.messages.forEach(function(message) {
			var text = 'Column: ' + message.column + ' "' + message.message + '"';
			if (_.isArray(message.line)) {
				message.line.forEach(function(line) {
					if (!lines[line]) lines[line] = '';
					lines[line] += '<div class="plato-jshint-message text-' + message.severity + '">' + text + '</div>';
				});
			} else {
				if (!lines[message.line]) lines[message.line] = '';
				lines[message.line] += '<div class="plato-jshint-message text-' + message.severity + '">' + text + '</div>';
			}
		});
		var marker = document.createElement('a');
		marker.innerHTML = '<i class="plato-gutter-icon icon-eye-open"></i>';
		Object.keys(lines).forEach(function(line) {
			var lineWidget = document.createElement('div');
			lineWidget.innerHTML = lines[line];
			cm.setGutterMarker(line - 1, 'plato-gutter-jshint', marker.cloneNode(true));
			cm.addLineWidget(line - 1, lineWidget);
		});
	}
});
