/*
 * Copyright 2017-present Open Networking Foundation

 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at

 * http://www.apache.org/licenses/LICENSE-2.0

 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

import * as d3 from 'd3';
import * as _ from 'lodash';
import {IXosSgNode} from '../../interfaces';
import {XosServiceGraphConfig as config} from '../../graph.config';
import {IXosServiceGraphIcons} from '../d3-helpers/graph-icons.service';
import {IXosGraphHelpers} from '../d3-helpers/graph-elements.helpers';

export interface IXosNodeRenderer {
  renderNodes(forceLayout: d3.forceLayout, nodeContainer: d3.Selection, nodes: IXosSgNode[]): void;
}

export class XosNodeRenderer {

  static $inject = [
    'XosServiceGraphIcons',
    'XosGraphHelpers'
  ];

  private drag;

  constructor (
    private XosServiceGraphIcons: IXosServiceGraphIcons,
    private XosGraphHelpers: IXosGraphHelpers
  ) {}

  public renderNodes(forceLayout: any, nodeContainer: any, nodes: IXosSgNode[]): void {

    this.drag = forceLayout.drag()
      .on('dragstart', (n: IXosSgNode) => {
        n.fixed =  true;
      });

    const node = nodeContainer
      .selectAll('g.node')
      .data(nodes, n => n.id);

    node
      .call(this.drag);

    const entering = node.enter()
      .append('g')
      .attr({
        id: n => n.id,
        class: n => `node ${n.type} ${this.XosGraphHelpers.parseElemClasses(n.d3Class)}`,
      });

    this.renderServiceNodes(entering.filter('.service'));
    this.renderServiceInstanceNodes(entering.filter('.serviceinstance'));

    node.exit().remove();
  }

  private renderServiceNodes(nodes: d3.selection) {

    nodes
      .append('rect')
      .attr({
        rx: config.node.radius,
        ry: config.node.radius
      });

    nodes
      .append('path')
      .attr({
        d: this.XosServiceGraphIcons.get('service').path,
        transform: this.XosServiceGraphIcons.get('service').transform,
        class: 'icon'
      });

    this.positionServiceNodeGroup(nodes);
    this.handleLabels(nodes);
  }

  private renderServiceInstanceNodes(nodes: d3.selection) {
    nodes.append('rect')
      .attr({
        width: 40,
        height: 40,
        x: -20,
        y: -20,
        transform: `rotate(45)`
      });

    nodes
      .append('path')
      .attr({
        d: this.XosServiceGraphIcons.get('serviceinstance').path,
        class: 'icon'
      });

    this.positionServiceInstanceNodeGroup(nodes);
    this.handleLabels(nodes); // eventually improve, padding top is wrong
  }

  private positionServiceNodeGroup(nodes: d3.selection) {
    const self = this;
    nodes.each(function (d: IXosSgNode) {
      const node = d3.select(this);
      const rect = node.select('rect');
      const icon = node.select('path');
      const bbox = self.XosGraphHelpers.getSiblingIconBBox(rect.node());

      rect
        .attr({
          width: bbox.width + config.node.padding,
          height: bbox.height + config.node.padding,
          x: - (config.node.padding / 2),
          y: - (config.node.padding / 2),
          transform: `translate(${-bbox.width / 2}, ${-bbox.height / 2})`
        });

      icon
        .attr({
          transform: `translate(${-bbox.width / 2}, ${-bbox.height / 2})`
        });
    });
  }

  private positionServiceInstanceNodeGroup(nodes: d3.selection) {
    const self = this;
    nodes.each(function (d: IXosSgNode) {
      const node = d3.select(this);
      const rect = node.select('rect');
      const icon = node.select('path');
      const bbox = self.XosGraphHelpers.getSiblingIconBBox(rect.node());
      const size = _.max([bbox.width, bbox.height]); // NOTE we need it to be a square
      rect
        .attr({
          width: size + config.node.padding,
          height: size + config.node.padding,
          x: - (config.node.padding / 2),
          y: - (config.node.padding / 2),
          transform: `rotate(45), translate(${-bbox.width / 2}, ${-bbox.height / 2})`
        });

      icon
        .attr({
          transform: `translate(${-bbox.width / 2}, ${-bbox.height / 2})`
        });
    });
  }

  private handleLabels(nodes: d3.selection) {
    const self = this;
    // if (this.userConfig.labels) {

      // group to contain label text and wrapper
      const label = nodes.append('g')
        .attr({
          class: 'label'
        });

      // setting up the wrapper
      label
        .append('rect')
        .attr({
          class: 'label-wrapper',
          rx: config.node.radius,
          ry: config.node.radius
        });

      // adding text
      label
        .append('text')
        .text(n => this.getNodeLabel(n))
        .attr({
          'opacity': 0,
          'text-anchor': 'left',
          'alignment-baseline': 'bottom',
          'font-size': config.node.text,
          y: config.node.text * 0.78
        })
        .transition()
        .duration(config.duration)
        .attr({
          opacity: 1
        });

      // resize and position label
      label.each(function() {
        const text = d3.select(this).select('text').node();
        const rect = d3.select(this).select('rect');
        const iconRect = d3.select(this.parentNode).select('rect').node();
        const icon = self.XosGraphHelpers.getBBox(iconRect);
        const bbox = self.XosGraphHelpers.getBBox(text);

        // scale the rectangle around the label to fit the text
        rect
          .attr({
            width: bbox.width + config.node.padding,
            height: config.node.text - 2 + config.node.padding,
            x: -(config.node.padding / 2),
            y: -(config.node.padding / 2),
          });

        // translate the lable group to the correct position
        d3.select(this)
          .attr({
            transform: function() {
              const label = self.XosGraphHelpers.getBBox(this);
              const x = - (label.width - config.node.padding) / 2;
              const y = (icon.height / 2) + config.node.padding;
              return `translate(${x}, ${y})`;
            }
          });
      });
    // }
    // else {
    //   node.selectAll('text')
    //     .transition()
    //     .duration(this.duration)
    //     .attr({
    //       opacity: 0
    //     })
    //     .remove();
    // }
  }

  private getNodeLabel(n: any): string {
    return n.data.name ? n.data.name.toUpperCase() : n.data.id;
    // return n.data.name ? n.data.name.toUpperCase() + ` - ${n.data.id}` : n.data.id;
  }
}
