/**
 * The home controller
 * 
 * @param {$scope} $scope The $scope service from angular
 */
mainApp.controller('homeCtrl', ['$scope', 'Compute', '$rootScope', 'Loading', 'Identity', 'Image', function ($scope, Compute, $rootScope, Loading, Identity, Image)
{
	
	graph = new joint.dia.Graph;
	paper = new joint.dia.Paper({
					el: $('#graphHolder'),
					width: $('#graphHolder').width(),
					//height: test.height,
					model: graph,
					gridSize: 1,
					eractive: false
			});
	
	$scope.raiseShowMachineCreationEvent = function () {
			$rootScope.$broadcast("showMachineCreationEvent", Compute.getData().axioms);
	};
	
	var displayMachine = function () {
			
			var machineNames = [];
			var i = 0;
			$.each(Compute.getData().machines, function () {
					machineNames[i] = [this.name, this.id];
					i++;
			})
			var vmList = {
					'vms': machineNames
									/*'links': [
									['VM 1', 'VM 2', '', ''],
									['VM 2', 'VM 3', 'I3', 'I4'],
									['VM 1', 'VM 3', 'I5', 'I6'],
									['VM 2', 'VM 4', 'I5', 'I6'],
									['VM 4', 'VM 5', 'I5', 'I6'],
									['VM 4', 'VM 6', 'I5', 'I6'],
									['VM 4', 'VM 1', 'I5', 'I6'],
									['VM 7', 'VM 4', 'I5', 'I6'],
									['VM 7', 'VM 3', 'I5', 'I6'],
									['VM 6', 'VM 8', 'I5', 'I6'],
									['VM 3', 'VM 9', 'I5', 'I6'],
									['VM 3', 'VM 10', 'I5', 'I6']
									]*/
			};
			//Custom element for inserting html
			joint.shapes.html = {};
			joint.shapes.html.Element = joint.shapes.basic.Rect.extend({
					defaults: joint.util.deepSupplement({
							type: 'html.Element',
							attrs: {
									rect: {stroke: 'none', 'fill-opacity': 0}
							}
					}, joint.shapes.basic.Rect.prototype.defaults)
			});
	
			
			this.paper.$el.css('pointer-events', 'none');
			var cells = buildGraphFromAdjacencyList(vmList);
	
			this.graph.addCells(cells);
			console.log(this.graph);
			var test = joint.layout.DirectedGraph.layout(this.graph, {
					etLinkVertices: false,
					//Top to bottom generation
					ankDir: "TB",
					odeSep: 150,
					dgeSep: 150,
					ankSep: 50
			});
	
			this.paper.setDimensions(test.width, test.height);
	
			$(".Member").bind('click', function () {
					$scope.raiseShowMachineDetailsEvent($(this).attr('model-id'));
			});
	}
	
	// Function to call after pull all data about machines
	var callMeAfterPullData = function (data) {
			//$scope.machines=Compute.getData().machines;
			Loading.stop();
			displayMachine();
	};
	
	var tryToRetrieveData = function () {
			// If no data retrieve about machine and user is logged
			if (Compute.getData().machines == null && Identity.isAlreadyLogin()) {
					Loading.start(); // Show loading gif
					Compute.pullData(callMeAfterPullData); // Retrieve data and call the callback
			} else {
					// Else if user is logged and data is already retrieve
					// simply display data
					if (Identity.isAlreadyLogin()) {
							callMeAfterPullData(); // Display data
					}
			}
	};
	
	// On user login
	$scope.$on('loginEvent', function () {
			tryToRetrieveData();
	});
	
	// Function to call from view to display the details of a machine
	$scope.raiseShowMachineDetailsEvent = function (id) {
	
			// Stop loading gif and display overlay
			var callback = function () {
					Loading.stop();
					var data = Compute.getData();
	
					$rootScope.$broadcast("showMachineDetailsEvent", data.machines[id], data.axioms);
	
			};
			Loading.start(); // Show loading gif
			Compute.pullMachines(callback); // Retrieve machine info and display overlay
	};
	
	// Try to retrieve data for the first time
	tryToRetrieveData();
	
	
	
	//Read the adjacencyList and build the elements and the links according to it
	function buildGraphFromAdjacencyList(adjacencyList) {
	
			var elements = [];
			var links = [];
	
			_.each(adjacencyList['vms'], function (vm) {
					elements.push(makeElement(vm));
			});
			_.each(adjacencyList['links'], function (link) {
					links.push(makeLink(link[0], link[1], link[2], link[3]));
			});
			// Links must be added after all the elements. This is because when the links
			// are added to the graph, link source/target
			// elements must be in the graph already.
			return elements.concat(links);
	}
	
	// On user login
	$scope.$on('updateGraphEvent', function () {
		displayMachine()
	});
	//Return a new link linking the parent and child elements with the interfaces names given in parameters 
	function makeLink(parentElementLabel, childElementLabel, Iparent, Ichild) {
	
			return new joint.dia.Link({
					source: {id: parentElementLabel},
					target: {id: childElementLabel},
					labels: [
							{position: 20, attrs: {text: {text: Iparent}}},
							{position: -20, attrs: {text: {text: Ichild}}}
					]
			});
	}
	
	//Return a new element
	function makeElement(vm) {
			var label = vm[0];
	
			var maxLineLength = _.max(label.split('\n'), function (l) {
					return l.length;
			}).length;
	
			// Compute width/height of the rectangle based on the number 
			// of lines in the label and the letter size. 0.6 * letterSize is
			// an approximation of the monospace font letter width.
			var width = 130;
			var height = 80;
			var data = Compute.getData();
	
			if (data.machines[vm[1]].status == "ACTIVE") {
					return new joint.shapes.org.Member({
							id: vm[1],
							position: {x: 0, y: 0},
							attrs: {
									'.card': {fill: 'blue', stroke: 'none'},
									image: {'xlink:href': './images/ON.png', opacity: 0.7},
									//'.rank': { text: rank, fill: textColor, 'word-spacing': '-5px', 'letter-spacing': 0},
									'.name': {text: label, fill: 'white', 'font-size': 13, 'font-family': 'Arial', 'letter-spacing': 0}
							}
					});
			} else {
					return new joint.shapes.org.Member({
							id: vm[1],
							position: {x: 0, y: 0},
							attrs: {
									'.card': {fill: 'blue', stroke: 'none'},
									image: {'xlink:href': './images/OFF.png', opacity: 0.7},
									//'.rank': { text: rank, fill: textColor, 'word-spacing': '-5px', 'letter-spacing': 0},
									'.name': {text: label, fill: 'white', 'font-size': 13, 'font-family': 'Arial', 'letter-spacing': 0}
							}
					});
			}
	}
}]);