/**
 * 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)
{
	// 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();
	

	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)
		});
		
		var graph = new joint.dia.Graph;
		var paper = new joint.dia.Paper({
			el: $('#graphHolder'),
			width: $('#graphHolder').width(),
			//height: test.height,
			model: graph,
			gridSize: 1,
			eractive: false
		});
		paper.$el.css('pointer-events', 'none');
		var cells = buildGraphFromAdjacencyList(vmList);
		
		graph.addCells(cells);
		var test = joint.layout.DirectedGraph.layout(graph, {
			etLinkVertices: false,
			//Top to bottom generation
			ankDir: "TB",
			odeSep: 150,
			dgeSep: 150,
			ankSep: 50
		});
		
		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);
	}
	
	//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();

		//console.log(data.machines[vm[1]]);

		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 }
				}
			});
		}
	}
}]);
