import React, { Component } from 'react';
import PropTypes from 'prop-types';
import go from 'amos-gojs';
import classnames from 'classnames';

const goObj = go.GraphObject.make;
const deviceSource = '/src/assets/bizView/pams';

class TopologyComponent extends Component {

  constructor(props) {
    super(props);
    this.state = {
    };
    this.diagram = null; //gojs图
    this.goJsDiv = 'goJsDiv';
  }


  componentDidMount() {
    this.renderCanvas();
  }

  componentWillReceiveProps(nextprops) {
    const { topologyData } = nextprops;
    const { nodeData, linkData } = topologyData;
    if (nextprops.topologyData !== this.props.topologyData) {
      this.diagram.model =  goObj(go.GraphLinksModel,
        {
          linkFromPortIdProperty: 'fromPort',  // required information:
          linkToPortIdProperty: 'toPort',      // identifies data property names
          nodeDataArray: nodeData || [],
          linkDataArray: linkData || []
        });
    }
  }


  // this function is the Node.dragComputation, to limit the movement of the parts
  stayInFixedArea = (part, pt, gridpt) => {
    let diagram = part.diagram;
    if (diagram === null) {return pt;}
		// compute the document area without padding
    let v = diagram.documentBounds.copy();
    v.subtractMargin(diagram.padding);
		// get the bounds of the part being dragged
    let b = part.actualBounds;
    let loc = part.location;
		// now limit the location appropriately
    let x = Math.max(v.x, Math.min(pt.x, v.right - b.width)) + (loc.x - b.x);
    let y = Math.max(v.y, Math.min(pt.y, v.bottom - b.height)) + (loc.y - b.y);
    return new go.Point(x, y);
  }

  nodeSelectionChanged = (node) => {
    if (node.isSelected) {
      // 点击选择节点
      // console.log(node.data);
    }
  }

  // 设备资源图片
  getDeviceSource = (v) => {
    return `${deviceSource}/${v}.png`;
  }

  // 获取线颜色
  getLinkColor = (v) => {
    const dicParams = {
      0: '#19FF00', //正常
      1: '#959595', //未运行
      2: '#FF8800', //告警
      3: '#FF0000', //故障
      4: '#02E3FC', //MBFE 正常
      5: '#FFF948', //MBFE 告警
      6: '#FFAA00', //MBFE 故障
      7: '#00A2FF' //其他
    };
    return dicParams[v];
  }

  // 获取箭头
  getArrow = (v) => {
    console.log(v);
    return v;
  }

  renderCanvas = () => {
    const { topologyData, nodeSelectionLinkChanged } = this.props;
    const { nodeData, linkData } = topologyData;
    this.diagram = goObj(go.Diagram, this.goJsDiv, {
      // allowHorizontalScroll: false,  // disallow scrolling or panning
      // allowVerticalScroll: false,
      allowZoom: false,              // disallow zooming
      initialContentAlignment: go.Spot.Center,
      'undoManager.isEnabled': true, //// enable undo & redo 是否可撤回
      'animationManager.isEnabled': false, // 过渡动画
      // fixedBounds: new go.Rect(0, 0, this.refs.goJsDiv.clientWidth, this.refs.goJsDiv.clientHeight),
      ModelChanged: (e) => {     // just for demonstration purposes,
        if (e.isTransactionFinished) {  // show the model data in the page's TextArea
          // console.log(e.model.toJson(), 'model');
          this.props.nodeChange(e);
        }
      }
    });

    this.diagram.nodeTemplateMap.add('Circle',
      goObj(go.Node, 'Vertical',
        {
          selectionObjectName: 'ICON',
          locationObjectName: 'ICON'
        },
        new go.Binding('position', 'loc', go.Point.parse).makeTwoWay(go.Point.stringify),
        goObj(go.Panel, 'Auto',
          goObj(go.Shape, 'Circle', { name: 'ICON',portId: '',
            width: 22, height: 22, strokeWidth: 0,fill: '#009dd9' },
            ),
        ),
      goObj(go.TextBlock,
        { margin: 15,cursor: 'pointer',font: '15px sans-serif' },
        new go.Binding('text', 'text' )),
        {
          selectionAdornmentTemplate:
              goObj(go.Adornment, 'Auto',
                goObj(go.Shape, 'Circle',
                { fill: null, stroke: '#fbfb7b', strokeWidth: 3 }),
                goObj(go.Placeholder)
              )  // end Adornment
        },
    ));

    this.diagram.nodeTemplateMap.add('Picture',
      goObj(go.Node, 'Vertical',
        {
          locationSpot: go.Spot.Center,
          locationObjectName: 'ICON',
          selectionObjectName: 'ICON'
          // dragComputation: this.stayInFixedArea
        },
        new go.Binding('position', 'loc', go.Point.parse).makeTwoWay(go.Point.stringify),
        goObj(go.Picture,
          {
            name: 'ICON',
            margin: 5,
            width: 50,
            height: 50,
            cursor: 'pointer'
          },
          new go.Binding('source','source',(v) => this.getDeviceSource(v)),
          new go.Binding('portId', 'singlePort')
        ),
        goObj(go.TextBlock, '无',
          { margin: 3, stroke: 'black', font: '14px sans-serif' },
          new go.Binding('text')),
        {
          selectionAdornmentTemplate:
              goObj(go.Adornment, 'Auto',
                goObj(go.Shape,
                { fill: null, stroke: '#fbfb7b', strokeWidth: 3 }),
                goObj(go.Placeholder)
              )  // end Adornment
        },
        {
          toolTip: // define a tooltip for each node that displays the color as text
            goObj('ToolTip',
              goObj(go.TextBlock, { margin: 4 },
                new go.Binding('text'))
            )  // end of Adornment
        }
      )
    );

    this.diagram.nodeTemplateMap.add('Double',
      goObj(go.Node, 'Vertical',
        {
          locationSpot: go.Spot.Center,
          locationObjectName: 'ICON',
          selectionObjectName: 'ICON'
          // dragComputation: this.stayInFixedArea
        },
        new go.Binding('position', 'loc', go.Point.parse).makeTwoWay(go.Point.stringify),
        goObj(go.Panel, 'Spot',
        goObj(go.Shape, 'Rectangle',
        { fill: 'lightgreen', stroke: null, width: 1, height: 1 }),
          goObj(go.Picture,
            {
              name: 'ICON',
              margin: 5,
              width: 50,
              height: 50,
              cursor: 'pointer'
            },
            new go.Binding('source','source',(v) => this.getDeviceSource(v))
          ),
          goObj(go.Shape,
          { width: 6, height: 6, portId: '',fill: null,stroke: 'rgba(84,113,255,1)',alignment: new go.Spot(1, 1, -29, 0) },
            new go.Binding('portId', 'leftPort')
          ),
          goObj(go.Shape,
          { width: 6, height: 6, portId: '',fill: null,stroke: 'rgba(84,113,255,1)',alignment: new go.Spot(1, 1, 27, 0) },
          new go.Binding('portId', 'rightPort')
          )
        ),
        {
          selectionAdornmentTemplate:
              goObj(go.Adornment, 'Auto',
                goObj(go.Shape,
                { fill: null, stroke: '#fbfb7b', strokeWidth: 3 }),
                goObj(go.Placeholder)
              )  // end Adornment
        },
        {
          toolTip: // define a tooltip for each node that displays the color as text
            goObj('ToolTip',
              goObj(go.TextBlock, { margin: 4 },
                new go.Binding('text'))
            )  // end of Adornment
        },
      goObj(go.TextBlock, '无',
          { margin: 3, stroke: 'black', font: '14px sans-serif' },
          new go.Binding('text')),
      )
    );

    this.diagram.groupTemplate = goObj(go.Group, 'Vertical',
      {
        resizable: true,
        locationObjectName: 'SHAPE',
        resizeObjectName: 'SHAPE',
        selectionObjectName: 'SHAPE'
        // dragComputation: this.stayInFixedArea,
        // selectionChanged: this.nodeSelectionChanged
      },
      new go.Binding('position', 'loc', go.Point.parse).makeTwoWay(go.Point.stringify),
      goObj(go.TextBlock,         // group title
        {
          width: 100,
          height: 24,
          font: 'Bold 14px Sans-Serif',
          stroke: 'white',
          background: '#1c9ad2',
          margin: 5,
          textAlign: 'center',
          verticalAlignment: go.Spot.Center
        },
      new go.Binding('text')),
      goObj(go.Shape, 'Rectangle',
        {
          name: 'SHAPE',
          parameter1: 14,
          fill: 'rgba(185,185,185,0.2)',
          stroke: 'rgba(28,154,210,1)',
          strokeWidth: 1
        },
        new go.Binding('desiredSize', 'size', go.Size.parse).makeTwoWay(go.Size.stringify),
      )
    );

    this.diagram.linkTemplate =
      goObj(go.Link,
        { selectionChanged: nodeSelectionLinkChanged },
        goObj(go.Shape, { strokeWidth: 2, stroke: 'rgba(0,255,8,1)' },
          new go.Binding('stroke', 'warnState', (v) => this.getLinkColor(v))
        ),
        goObj(go.Shape, { toArrow: 'Standard', fill: '#3d6fc2',stroke: '#3d6fc2' },
          new go.Binding('visible', 'hasArrow'),
          new go.Binding('stroke', 'warnState', (v) => this.getLinkColor(v)),
          new go.Binding('fill', 'warnState', (v) => this.getLinkColor(v)),
        ),
      );
    this.diagram.model =  goObj(go.GraphLinksModel,
      {
        linkFromPortIdProperty: 'fromPort',  // required information:
        linkToPortIdProperty: 'toPort',      // identifies data property names
        nodeDataArray: nodeData || [],
        linkDataArray: linkData || []
      });
  }

  render() {
    const { className,style } = this.props;
    return (
      <div ref={(c) => { this.goJsDiv = c; }} style={style} className={classnames('topology-pas', className)} ></div>
    );
  }
}

TopologyComponent.propTypes = {
  className: PropTypes.string,
  style: PropTypes.object,
  topologyData: PropTypes.object,
  nodeSelectionLinkChanged: PropTypes.func,
  nodeChange: PropTypes.func
};

TopologyComponent.defaultProps = {
  style: { height: '100%' },
  topologyData: {
    nodeData: [],
    linkData: []
  }
};

export default TopologyComponent;
