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


        $scope.raiseShowMachineCreationEvent = function (){
          $rootScope.$broadcast("showMachineCreationEvent");  
        };

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