(function () {
  'use strict';

  angular.module('xos.serviceTopology')
  .directive('serviceCanvas', function(){
    return {
      restrict: 'E',
      scope: {},
      bindToController: true,
      controllerAs: 'vm',
      templateUrl: 'templates/topology_canvas.tpl.html',
      controller: function($element, $window, d3, serviceTopologyConfig, ServiceRelation, Slice, Instances, Subscribers){

        this.instances = [];
        this.slices = [];

        // count the mas depth of an object
        const depthOf = (obj) => {
          var depth = 0;
          if (obj.children) {
            obj.children.forEach(function (d) {
              var tmpDepth = depthOf(d);
              if (tmpDepth > depth) {
                depth = tmpDepth
              }
            })
          }
          return 1 + depth
        };

        const width = $window.innerWidth - serviceTopologyConfig.widthMargin;
        const height = $window.innerHeight - serviceTopologyConfig.heightMargin;

        const tree = d3.layout.tree()
          .size([height, width]);

        const diagonal = d3.svg.diagonal()
          .projection(d => [d.y, d.x]);

        const svg = d3.select($element[0])
          .append('svg')
          .style('width', `${$window.innerWidth}px`)
          .style('height', `${$window.innerHeight}px`)
          .append('g')
          .attr("transform", "translate(" + serviceTopologyConfig.widthMargin+ "," + serviceTopologyConfig.heightMargin + ")");;

        //const resizeCanvas = () => {
        //  var targetSize = svg.node().getBoundingClientRect();
        //
        //  d3.select(self.frameElement)
        //    .attr('width', `${targetSize.width}px`)
        //    .attr('height', `${targetSize.height}px`)
        //};
        //d3.select(window)
        //  .on('load', () => {
        //    resizeCanvas();
        //  });
        //d3.select(window)
        //  .on('resize', () => {
        //    resizeCanvas();
        //    update(root);
        //  });
        var root;
        var i = 0;
        var duration = 750;

        const draw = (tree) => {
          root = tree;
          root.x0 = $window.innerHeight / 2;
          root.y0 = 0;

          update(root);
        };

        function update(source) {

          const maxDepth = depthOf(source);

          // Compute the new tree layout.
          var nodes = tree.nodes(root).reverse(),
            links = tree.links(nodes);

          // Normalize for fixed-depth.
          nodes.forEach(function(d) {
            // position the child node horizontally
            d.y = d.depth * (($window.innerWidth - (serviceTopologyConfig.widthMargin * 2)) / maxDepth);
          });

          // Update the nodes…
          var node = svg.selectAll('g.node')
            .data(nodes, function(d) { return d.id || (d.id = ++i); });

          // Enter any new nodes at the parent's previous position.
          var nodeEnter = node.enter().append('g')
            .attr('class', 'node')
            .attr('transform', function(d) {
              // this is the starting position
              return 'translate(' + source.y0 + ',' + source.x0 + ')';
            });

          nodeEnter.append('circle')
            .attr('r', 1e-6)
            .style('fill', function(d) { return d._children ? 'lightsteelblue' : '#fff'; })
            .on('click', click);

          nodeEnter.append('text')
            .attr('x', function(d) { return d.children || d._children ? -13 : 13; })
            .attr('transform', function(d) {
              if((d.children || d._children) && d.parent || d._parent){
                return 'rotate(30)';
              }
              return;
            })
            .attr('dy', '.35em')
            .attr('text-anchor', function(d) { return d.children || d._children ? 'end' : 'start'; })
            .text(function(d) { return d.name; })
            .style('fill-opacity', 1e-6);

          // Transition nodes to their new position.
          var nodeUpdate = node.transition()
            .duration(duration)
            .attr('transform', function(d) {
              return 'translate(' + d.y + ',' + d.x + ')';
            });

          nodeUpdate.select('circle')
            .attr('r', 10)
            .style('fill', function(d) { return d._children ? 'lightsteelblue' : '#fff'; });

          nodeUpdate.select('text')
            .style('fill-opacity', 1);

          // Transition exiting nodes to the parent's new position.
          var nodeExit = node.exit().transition()
            .duration(duration)
            .attr('transform', function(d) { return 'translate(' + source.y + ',' + source.x + ')'; })
            .remove();

          nodeExit.select('circle')
            .attr('r', 1e-6);

          nodeExit.select('text')
            .style('fill-opacity', 1e-6);

          // Update the links…
          var link = svg.selectAll('path.link')
            .data(links, function(d) { return d.target.id; });

          // Enter any new links at the parent's previous position.
          link.enter().insert('path', 'g')
            .attr('class', 'link')
            .attr('d', function(d) {
              var o = {x: source.x0, y: source.y0};
              return diagonal({source: o, target: o});
            });

          // Transition links to their new position.
          link.transition()
            .duration(duration)
            .attr('d', diagonal);

          // Transition exiting nodes to the parent's new position.
          link.exit().transition()
            .duration(duration)
            .attr('d', function(d) {
              var o = {x: source.x, y: source.y};
              return diagonal({source: o, target: o});
            })
            .remove();

          // Stash the old positions for transition.
          nodes.forEach(function(d) {
            d.x0 = d.x;
            d.y0 = d.y;
          });
        }

        var _this = this;
        const click = function(d) {

          // empty panel
          _this.slices = [];
          _this.instances = [];

          var nodes = d3.selectAll('circle')
            .transition()
            .duration(duration)
            .attr('r', 10);

          d3.selectAll('rect.slice-detail')
            .remove();

          d3.selectAll('text.slice-name')
            .remove();

          var selectedNode = d3.select(this);

          selectedNode
            .transition()
            .duration(duration)
            .attr('r', 30);

          if(!d.service){
            return;
          }

          _this.selectedService = {
            id: d.id,
            name: d.name
          };

          Slice.query({service: d.service.id}).$promise
          .then(slices => {
            _this.slices = slices;

            if(slices.length > 0){
              const parentNode = d3.select(this.parentNode);

              parentNode
                .append('rect')
                .style('opacity', 0)
                .attr({
                  width: 150,
                  height: 50,
                  y: 35,
                  x: -75,
                  class: 'slice-detail'
                })
                .transition()
                .duration(duration)
                .style('opacity', 1);

              parentNode
                .append('text')
                .style('opacity', 0)
                .attr({
                  y: 65,
                  x: -60,
                  class: 'slice-name'
                })
                .text(() => {
                  if(slices[0]){
                    return slices[0].humanReadableName;
                  }

                  return '';
                })
                .transition()
                .duration(duration)
                .style('opacity', 1);
              }
          })
        };

        Subscribers.query().$promise
        .then((subscribers) => {
          this.subscribers = subscribers;
        });

        this.getInstances = (slice) => {
          Instances.query({slice: slice.id}).$promise
          .then((instances) => {
            this.selectedSlice = slice;
            this.instances = instances;
          })
        };

        this.getServiceChain = (subscriber) => {
          ServiceRelation.get(subscriber)
            .then((tree) => {
              draw(tree);
            });
        };
      }
    }
  });

}());