import {Component, ElementRef, EventEmitter, HostListener, OnInit, Output, ViewChild} from '@angular/core';

declare let JTopo:any;
@Component({
    selector: 'smart-jtopo',
    templateUrl: './jtopo.component.html',
    styleUrls: []
})

/**
 * 提供拓扑图面板相关操作的函数集，编辑器继承其全部功能
 */
export class JtopoComponent implements OnInit{
    @Output() clickNode = new EventEmitter<any>();
    @Output() clickLink = new EventEmitter<any>();
    @ViewChild('topologyCanvas') topologyCanvas: ElementRef;
    @ViewChild('topologyBody') topologyBody: ElementRef;

    json = {
        "version": "0.4.8",
        "wheelZoom": "0.95",
        "id": "ST172.19.105.52015100809430700001",
        "childs": [
            {
                "id": "S172.19.105.52015100809430700002",
                "elementType": "scene",
                "translateX": "106.5",
                "translateY": "20",
                "scaleX": "1",
                "scaleY": "1",
                "childs": [
                    {
                        "id": "L172.19.105.52015100811153300001",
                        "elementType": "link",
                        "x": "0",
                        "y": "0",
                        "width": "32",
                        "height": "32",
                        "rotate": "0",
                        "scaleX": "1",
                        "scaleY": "1",
                        "text": "undefined",
                        "nodeSrc": "1136300297928.587",
                        "nodeDst": "1406176935353.6848",
                        "lineType": "line",
                        "zindex": "2"
                    },
                    {
                        "id": "L172.19.105.52015100811153300002",
                        "elementType": "link",
                        "x": "0",
                        "y": "0",
                        "width": "32",
                        "height": "32",
                        "rotate": "0",
                        "scaleX": "1",
                        "scaleY": "1",
                        "text": "undefined",
                        "nodeSrc": "1394105924967.951",
                        "nodeDst": "1136300297928.587",
                        "lineType": "line",
                        "zindex": "2"
                    },
                    {
                        "id": "L172.19.105.52015100811153300004",
                        "elementType": "link",
                        "x": "0",
                        "y": "0",
                        "width": "32",
                        "height": "32",
                        "rotate": "0",
                        "scaleX": "1",
                        "scaleY": "1",
                        "text": "undefined",
                        "nodeSrc": "564241624829.4331",
                        "nodeDst": "318016674603.1266",
                        "lineType": "line",
                        "zindex": "2"
                    },
                    {
                        "id": "L172.19.105.52015100811153300005",
                        "elementType": "link",
                        "x": "0",
                        "y": "0",
                        "width": "32",
                        "height": "32",
                        "rotate": "0",
                        "scaleX": "1",
                        "scaleY": "1",
                        "text": "undefined",
                        "nodeSrc": "1062340763210.1544",
                        "nodeDst": "564241624829.4331",
                        "lineType": "line",
                        "zindex": "2"
                    },
                    {
                        "id": "L172.19.105.52015100811153300006",
                        "elementType": "link",
                        "x": "0",
                        "y": "0",
                        "width": "32",
                        "height": "32",
                        "rotate": "0",
                        "scaleX": "1",
                        "scaleY": "1",
                        "text": "undefined",
                        "nodeSrc": "564241624829.4331",
                        "nodeDst": "488323736331.2087",
                        "lineType": "line",
                        "zindex": "2"
                    },
                    {
                        "id": "L172.19.105.52015100811153300007",
                        "elementType": "link",
                        "x": "0",
                        "y": "0",
                        "width": "32",
                        "height": "32",
                        "rotate": "0",
                        "scaleX": "1",
                        "scaleY": "1",
                        "text": "undefined",
                        "nodeSrc": "564241624829.4331",
                        "nodeDst": "827722371280.0199",
                        "lineType": "line",
                        "zindex": "2"
                    },
                    {
                        "id": "L172.19.105.52015100811153300008",
                        "elementType": "link",
                        "x": "0",
                        "y": "0",
                        "width": "32",
                        "height": "32",
                        "rotate": "0",
                        "scaleX": "1",
                        "scaleY": "1",
                        "text": "undefined",
                        "nodeSrc": "564241624829.4331",
                        "nodeDst": "1045863334277.662",
                        "lineType": "line",
                        "zindex": "2"
                    },
                    {
                        "id": "L172.19.105.52015100811153300009",
                        "elementType": "link",
                        "x": "0",
                        "y": "0",
                        "width": "32",
                        "height": "32",
                        "rotate": "0",
                        "scaleX": "1",
                        "scaleY": "1",
                        "text": "undefined",
                        "nodeSrc": "1262070648024.5728",
                        "nodeDst": "564241624829.4331",
                        "lineType": "line",
                        "zindex": "2"
                    },
                    {
                        "id": "L172.19.105.52015100811153300010",
                        "elementType": "link",
                        "x": "0",
                        "y": "0",
                        "width": "32",
                        "height": "32",
                        "rotate": "0",
                        "scaleX": "1",
                        "scaleY": "1",
                        "text": "undefined",
                        "nodeSrc": "1262070648024.5728",
                        "nodeDst": "1136300297928.587",
                        "lineType": "line",
                        "zindex": "2"
                    },
                    {
                        "id": "L172.19.105.52015100811214600001",
                        "elementType": "link",
                        "x": "0",
                        "y": "0",
                        "width": "32",
                        "height": "32",
                        "rotate": "0",
                        "scaleX": "1",
                        "scaleY": "1",
                        "text": "undefined",
                        "nodeSrc": "253209434749.73596",
                        "nodeDst": "564241624829.4331",
                        "lineType": "line",
                        "zindex": "2"
                    },
                    {
                        "id": "L172.19.105.52015100811214600002",
                        "elementType": "link",
                        "x": "0",
                        "y": "0",
                        "width": "32",
                        "height": "32",
                        "rotate": "0",
                        "scaleX": "1",
                        "scaleY": "1",
                        "text": "undefined",
                        "nodeSrc": "253209434749.73596",
                        "nodeDst": "1136300297928.587",
                        "lineType": "line",
                        "zindex": "2"
                    },
                    {
                        "id": "L172.19.105.52015100811214600003",
                        "elementType": "link",
                        "x": "0",
                        "y": "0",
                        "width": "32",
                        "height": "32",
                        "rotate": "0",
                        "scaleX": "1",
                        "scaleY": "1",
                        "text": "undefined",
                        "nodeSrc": "520008948580.8119",
                        "nodeDst": "564241624829.4331",
                        "lineType": "line",
                        "zindex": "2"
                    },
                    {
                        "id": "L172.19.105.52015100811214600004",
                        "elementType": "link",
                        "x": "0",
                        "y": "0",
                        "width": "32",
                        "height": "32",
                        "rotate": "0",
                        "scaleX": "1",
                        "scaleY": "1",
                        "text": "undefined",
                        "nodeSrc": "520008948580.8119",
                        "nodeDst": "1136300297928.587",
                        "lineType": "line",
                        "zindex": "2"
                    },
                    {
                        "id": "L172.19.105.52015100811512000002",
                        "elementType": "link",
                        "x": "0",
                        "y": "0",
                        "width": "32",
                        "height": "32",
                        "rotate": "0",
                        "scaleX": "1",
                        "scaleY": "1",
                        "text": "undefined",
                        "nodeSrc": "809054608657.865",
                        "nodeDst": "1394105924967.951",
                        "lineType": "line",
                        "zindex": "2"
                    },
                    {
                        "id": "L172.19.105.52015100811512000004",
                        "elementType": "link",
                        "x": "0",
                        "y": "0",
                        "width": "32",
                        "height": "32",
                        "rotate": "0",
                        "scaleX": "1",
                        "scaleY": "1",
                        "text": "undefined",
                        "nodeSrc": "1250687739831.9912",
                        "nodeDst": "1062340763210.1544",
                        "lineType": "line",
                        "zindex": "2"
                    },
                    {
                        "id": "L172.19.105.52015100911051100001",
                        "elementType": "link",
                        "x": "0",
                        "y": "0",
                        "width": "32",
                        "height": "32",
                        "rotate": "0",
                        "scaleX": "1",
                        "scaleY": "1",
                        "text": "undefined",
                        "nodeSrc": "564241624829.4331",
                        "nodeDst": "597645745716.1871",
                        "lineType": "line",
                        "zindex": "2"
                    },
                    {
                        "elementType": "node",
                        "x": "198",
                        "y": "315",
                        "width": "32",
                        "height": "32",
                        "rotate": "0",
                        "scaleX": "1",
                        "scaleY": "1",
                        "text": "attack-network",
                        "textPosition": "Bottom_Center",
                        "nodeId": "1136300297928.587",
                        "nodeType": "EC",
                        "nodeImage": "http://10.10.38.99:8888/file/icon/15474547275540202.png",
                        "zindex": "3"
                    },
                    {
                        "id": "N172.19.105.52015100809465000001",
                        "elementType": "node",
                        "x": "196",
                        "y": "242",
                        "width": "32",
                        "height": "32",
                        "rotate": "0",
                        "scaleX": "1",
                        "scaleY": "1",
                        "text": "attackr-router",
                        "textPosition": "Bottom_Center",
                        "nodeId": "1394105924967.951",
                        "nodeType": "VR",
                        "nodeImage": "http://10.10.38.99:8888/file/icon/15474547275540202.png",
                        "zindex": "3"
                    },
                    {
                        "id": "N172.19.105.52015100809500700002",
                        "elementType": "node",
                        "x": "104",
                        "y": "383.5",
                        "width": "32",
                        "height": "32",
                        "rotate": "0",
                        "scaleX": "1",
                        "scaleY": "1",
                        "text": "attack-client",
                        "textPosition": "Bottom_Center",
                        "nodeId": "1406176935353.6848",
                        "nodeType": "VM",
                        "nodeImage": "http://10.10.38.99:8888/file/icon/15474547275540202.png",
                        "zindex": "3"
                    },
                    {
                        "id": "N172.19.105.52015100810295700002",
                        "elementType": "node",
                        "x": "539",
                        "y": "321.5",
                        "width": "32",
                        "height": "32",
                        "rotate": "0",
                        "scaleX": "1",
                        "scaleY": "1",
                        "text": "intert-networker",
                        "textPosition": "Bottom_Center",
                        "nodeId": "564241624829.4331",
                        "nodeType": "EC",
                        "nodeImage": "http://10.10.38.99:8888/file/icon/15474547275540202.png",
                        "zindex": "3"
                    },
                    {
                        "id": "N172.19.105.52015100810320100002",
                        "elementType": "node",
                        "x": "719",
                        "y": "160.5",
                        "width": "32",
                        "height": "32",
                        "rotate": "0",
                        "scaleX": "1",
                        "scaleY": "1",
                        "text": "ws-manage",
                        "textPosition": "Bottom_Center",
                        "nodeId": "318016674603.1266",
                        "nodeType": "VM",
                        "nodeImage": "http://10.10.38.99:8888/file/icon/15474547275540202.png",
                        "zindex": "3"
                    },
                    {
                        "id": "N172.19.105.52015100810402700002",
                        "elementType": "node",
                        "x": "725",
                        "y": "225.5",
                        "width": "32",
                        "height": "32",
                        "rotate": "0",
                        "scaleX": "1",
                        "scaleY": "1",
                        "text": "ws-browser",
                        "textPosition": "Bottom_Center",
                        "nodeId": "488323736331.2087",
                        "nodeType": "VM",
                        "nodeImage": "http://10.10.38.99:8888/file/icon/15474547275540202.png",
                        "zindex": "3"
                    },
                    {
                        "id": "N172.19.105.52015100810461200002",
                        "elementType": "node",
                        "x": "726",
                        "y": "293.5",
                        "width": "32",
                        "height": "32",
                        "rotate": "0",
                        "scaleX": "1",
                        "scaleY": "1",
                        "text": "internal-mssql",
                        "textPosition": "Bottom_Center",
                        "nodeId": "827722371280.0199",
                        "nodeType": "VM",
                        "nodeImage": "http://10.10.38.99:8888/file/icon/15474547275540202.png",
                        "zindex": "3"
                    },
                    {
                        "id": "N172.19.105.52015100810485100002",
                        "elementType": "node",
                        "x": "726",
                        "y": "361.5",
                        "width": "32",
                        "height": "32",
                        "rotate": "0",
                        "scaleX": "1",
                        "scaleY": "1",
                        "text": "internal-ossec",
                        "textPosition": "Bottom_Center",
                        "nodeId": "1045863334277.662",
                        "nodeType": "VM",
                        "nodeImage": "http://10.10.38.99:8888/file/icon/15474547275540202.png",
                        "zindex": "3"
                    },
                    {
                        "id": "N172.19.105.52015100810523500002",
                        "elementType": "node",
                        "x": "369",
                        "y": "245.5",
                        "width": "32",
                        "height": "32",
                        "rotate": "0",
                        "scaleX": "1",
                        "scaleY": "1",
                        "text": "internet-www",
                        "textPosition": "Bottom_Center",
                        "nodeId": "1262070648024.5728",
                        "nodeType": "ECVR",
                        "nodeImage": "http://10.10.38.99:8888/file/icon/15474547275540202.png",
                        "zindex": "3"
                    },
                    {
                        "id": "N172.19.105.52015100811153300003",
                        "elementType": "node",
                        "x": "536",
                        "y": "237.5",
                        "width": "32",
                        "height": "32",
                        "rotate": "0",
                        "scaleX": "1",
                        "scaleY": "1",
                        "text": "intert-router",
                        "textPosition": "Bottom_Center",
                        "nodeId": "1062340763210.1544",
                        "nodeType": "VR",
                        "nodeImage": "http://10.10.38.99:8888/file/icon/15474547275540202.png",
                        "zindex": "3"
                    },
                    {
                        "id": "N172.19.105.52015100811163200002",
                        "elementType": "node",
                        "x": "367.5",
                        "y": "320",
                        "width": "32",
                        "height": "32",
                        "rotate": "0",
                        "scaleX": "1",
                        "scaleY": "1",
                        "text": "internet-blog",
                        "textPosition": "Bottom_Center",
                        "nodeId": "253209434749.73596",
                        "nodeType": "ECVR",
                        "nodeImage": "http://10.10.38.99:8888/file/icon/15474547275540202.png",
                        "zindex": "3"
                    },
                    {
                        "id": "N172.19.105.52015100811204100002",
                        "elementType": "node",
                        "x": "370.5",
                        "y": "403",
                        "width": "32",
                        "height": "32",
                        "rotate": "0",
                        "scaleX": "1",
                        "scaleY": "1",
                        "text": "internet-vpn",
                        "textPosition": "Bottom_Center",
                        "nodeId": "520008948580.8119",
                        "nodeType": "ECVR",
                        "nodeParams": {},
                        "nodeImage": "http://10.10.38.99:8888/file/icon/15474547275540202.png",
                        "zindex": "3"
                    },
                    {
                        "id": "N172.19.105.52015100811512000001",
                        "elementType": "node",
                        "x": "194.5",
                        "y": "166",
                        "width": "32",
                        "height": "32",
                        "rotate": "0",
                        "scaleX": "1",
                        "scaleY": "1",
                        "text": "attack-firewall",
                        "textPosition": "Bottom_Center",
                        "nodeId": "809054608657.865",
                        "nodeType": "FW",
                        "nodeParams": {},
                        "nodeImage": "http://10.10.38.99:8888/file/icon/15474547275540202.png",
                        "zindex": "3"
                    },
                    {
                        "id": "N172.19.105.52015100811512000003",
                        "elementType": "node",
                        "x": "534.5",
                        "y": "163",
                        "width": "32",
                        "height": "32",
                        "rotate": "0",
                        "scaleX": "1",
                        "scaleY": "1",
                        "text": "intert-firewall",
                        "textPosition": "Bottom_Center",
                        "nodeId": "1250687739831.9912",
                        "nodeType": "FW",
                        "nodeParams": {},
                        "nodeImage": "http://10.10.38.99:8888/file/icon/15474547275540202.png",
                        "zindex": "3"
                    },
                    {
                        "id": "N172.19.105.52015100911045400002",
                        "elementType": "node",
                        "x": "727.5",
                        "y": "430",
                        "width": "32",
                        "height": "32",
                        "rotate": "0",
                        "scaleX": "1",
                        "scaleY": "1",
                        "text": "defend-client",
                        "textPosition": "Bottom_Center",
                        "nodeId": "597645745716.1871",
                        "nodeType": "VM",
                        "nodeImage": "http://10.10.38.99:8888/file/icon/15474547275540202.png",
                        "zindex": "3"
                    }
                ]
            }
        ]
    };

    utils;
    config = {
        // Stage属性
        stageFrames: 500,                       // 舞台播放的帧数/秒
        defaultScal: 0.95,                      // 鼠标滚轮缩放比例
        eagleEyeVsibleDefault: false,         // 是否显示鹰眼对象
        // Node属性
        nodeAlpha: 1,                           // 节点透明度,取值范围[0-1]
        nodeStrokeColor: '22,124,255',        // 节点描边的颜色
        nodeFillColor: '255,222,173',          // 节点填充颜色
        nodeShadow: false,                     // 节点是否显示阴影
        nodeShadowColor: 'rgba(0,0,0,0.5)',  // 节点阴影的颜色
        nodeFont: '12px Consolas',            // 节点字体
        nodeFontColor: 'black',               // 节点文字颜色,如"255,255,0"
        nodeDefaultWidth: 32,                 // 新建节点默认宽
        nodeDefaultHeight: 32,                // 新建节点默认高
        nodeBorderColor: 'black',            // 节点容器边框颜色,如"255,255,0"
        nodeBorderRadius: 30,                // 节点半径，非圆节点有此属性会变形
        nodeRotateValue: 0.5,                // 节点旋转的角度(弧度)
        nodeScale: 0.2,                       // 节点缩放幅度(此处保证X和Y均等缩放)
        // Link属性
        linkAlpha: 1,                         // 连线透明度,取值范围[0-1]
        linkStrokeColor: '0,0,0',     // 连线的颜色
        linkFillColor: '0,0,0',
        linkShadow: false,                   // 是否显示连线阴影
        linkShadowColor: 'rgba(0,0,0,0.5)',
        linkFont: '12px Consolas',           // 节点字体
        linkFontColor: 'black',              // 连线文字颜色,如"255,255,0"
        linkArrowsRadius: 0,                 // 线条箭头半径
        linkDefaultWidth: 3,                 // 连线宽度
        linkOffsetGap: 80,                   // 折线拐角处的长度
        linkDirection: 'vertical',        // 折线的方向
        // Container属性
        containerAlpha: 1,
        containerStrokeColor: '22,124,255',
        containerFillColor: '22,124,255',
        containerShadow: false,
        containerShadowColor: 'rgba(0,0,0,0.5)',
        containerFont: '12px Consolas',
        containerFontColor: 'black',
        containerBorderColor: 'black',
        containerBorderRadius: 30,

        arrowsRadius:null
    };

    // 布局参数
    layout = {};
    // 绘图区属性
    stage = null;
    scene = null;
    // 当前模式
    stageMode = 'edit';
    // 默认连线类型
    lineType = 'line';
    // 当前选择的节点对象
    currentNode = null;
    // 当前选择的连线对象
    currentLink = null;

    beginNode = null;
    link = null;
    isSelectedMode;

    tempNodeA = new JTopo.Node('tempA');
    tempNodeZ = new JTopo.Node('tempZ');

    constructor(){}

    ngOnInit(){
        this.init('assets/img/backimg.png',this.json);
    }

    /**
     * 编辑器初始化方法,根据请求返回结果加载空白的或者指定结构的拓扑编辑器
     * @param backImg     背景图片
     * @param topologyJson    拓扑JSON结构
     */
    init(backImg, topologyJson){
        if(!topologyJson){
            return;
        }
        let canvas = this.topologyCanvas.nativeElement;
        canvas.width = this.topologyBody.nativeElement.clientWidth;
        canvas.height = this.topologyBody.nativeElement.clientHeight;

        this.tempNodeA.setSize(1,1);
        this.tempNodeZ.setSize(1,1);

        let self = this;

        if(topologyJson === '-1'){
            this.stage = new JTopo.Stage(canvas);   //定义舞台对象
            this.scene = new JTopo.Scene(this.stage);   //定义场景对象
        }else{
            this.stage = JTopo.createStageFromJson(topologyJson,canvas);
            this.scene = this.stage.childs[0];
        }

        this.getAllNodes()[0].alarm = "告警";

        this.scene.mouseover(event=>{
            //进入某个节点
            // if(event.target != null && event.target instanceof JTopo.Node && event.target.nodeTooltip &&)
        });

        this.scene.click(event=>{
            if(!event.target){
                //单击空白处
                return;
            }
            if(event.target instanceof JTopo.Node && this.stageMode === 'normal'){

            }else if(event.target instanceof  JTopo.Node && this.stageMode === 'edit'){
            }else if(event.target instanceof  JTopo.Link && this.stageMode === 'normal'){

            }else if(event.target instanceof  JTopo.Link && this.stageMode === 'edit'){

            }
        });

        //双击编辑事件
        this.scene.dbclick(event=>{
            if(!event.target){
                //双击空白处
                return;
            }
            this.currentNode = event.target;

            if(event.target instanceof JTopo.Node && this.stageMode === 'normal'){

            }else if(event.target instanceof JTopo.Node && this.stageMode === 'edit'){
            }else if(event.target instanceof JTopo.Link && this.stageMode === 'normal'){

            }else if(event.target instanceof JTopo.Link && this.stageMode === 'edit'){
                console.log(event.target);
            }
        })

        //清楚起始节点不完整的拖放线
        this.scene.mousedown(event=>{
            if(!event.target){
                return;
            }
            if(this.link && !this.isSelectedMode && (event.target == null || event.target === this.beginNode || event.target === this.link)){
                this.scene.remove(this.link);
            }
        });

        //监听鼠标松开事件；
        //处理右键菜单、左键连线
        //event.button： 0-左键 1-中键 2-右键
        this.scene.mouseup(event=>{
            if (event.target && event.target instanceof JTopo.Node) {
                this.currentNode = event.target
            } else if (event.target && event.target instanceof JTopo.Link) {
                this.currentLink = event.target
            }
            if (event.target && event.target instanceof JTopo.Node && event.target.layout && event.target.layout.on && event.target.layout.type && event.target.layout.type !== 'auto') {
                JTopo.layout.layoutNode(this, event.target, true, event)
            }

            if(event.button === 0){
                if (event.target != null && event.target instanceof JTopo.Node && !this.isSelectedMode && this.stageMode === 'edit') {
                    if (this.beginNode == null) {
                        // 在起始节点处松开鼠标,创建动态的线条(临时节点A-Z)
                        this.beginNode = event.target;
                        if (this.lineType === 'line') {
                            // 直线
                            self.link = new JTopo.Link(self.tempNodeA, self.tempNodeZ);
                            self.link.lineType = 'line'
                        } else if (self.lineType === 'foldLine') {
                            // 折线
                            self.link = new JTopo.FoldLink(self.tempNodeA, self.tempNodeZ);
                            self.link.lineType = 'foldLine';
                            self.link.direction = self.config.linkDirection
                        } else if (self.lineType === 'flexLine') {
                            // 二次折线
                            self.link = new JTopo.FlexionalLink(self.tempNodeA, self.tempNodeZ);
                            self.link.direction = self.config.linkDirection;
                            self.link.lineType = 'flexLine'
                        } else if (self.lineType === 'curveLine') {
                            // 曲线
                            self.link = new JTopo.CurveLink(self.tempNodeA, self.tempNodeZ);
                            self.link.lineType = 'curveLine'
                        }
                        self.link.dashedPattern = 2;
                        self.link.lineWidth = self.config.linkDefaultWidth;
                        self.link.shadow = self.config.linkShadow;
                        self.link.strokeColor = JTopo.util.randomColor();
                        this.scene.add(self.link);
                        self.tempNodeA.setLocation(event.x, event.y);
                        self.tempNodeZ.setLocation(event.x, event.y);
                    } else if (event.target && event.target instanceof JTopo.Node && self.beginNode !== event.target) {
                        // 在终点节点处松开鼠标,则建立连线
                        let endNode = event.target;
                        let link;
                        if (self.lineType === 'line') {
                            link = new JTopo.Link(self.beginNode, endNode);
                            link.lineType = 'line'
                        } else if (self.lineType === 'foldLine') {
                            link = new JTopo.FoldLink(self.beginNode, endNode);
                            link.direction = self.config.linkDirection;
                            link.bundleOffset = self.config.linkOffsetGap;    // 折线拐角处的长度
                            link.lineType = 'foldLine'
                        } else if (self.lineType === 'flexLine') {
                            link = new JTopo.FlexionalLink(self.beginNode, endNode);
                            link.direction = self.config.linkDirection;
                            link.lineType = 'flexLine';
                            link.offsetGap = self.config.linkOffsetGap;
                        } else if (self.lineType === 'curveLine') {
                            link = new JTopo.CurveLink(self.beginNode, endNode);
                            link.lineType = 'curveLine';
                        }
                        // 保存线条所连接的两个节点ID
                        link.nodeSrc = self.beginNode.nodeId;
                        link.nodeDst = endNode.nodeId;
                        if (self.lineType !== 'curveLine') {
                            link.arrowsRadius = self.config.arrowsRadius;
                        }
                        link.strokeColor = self.config.linkStrokeColor;
                        link.lineWidth = self.config.linkDefaultWidth;
                        this.scene.add(link);
                        self.beginNode = null;
                        this.scene.remove(self.link);
                        self.link = null;
                    } else {
                        self.beginNode = null;
                    }
                } else {
                    if (this.link) {
                        console.log(this);
                        this.scene.remove(this.link);
                    }
                    this.beginNode = null;
                }
            }
        });

        //动态更新连线坐标
        this.scene.mousemove(event=>{
            if(!self.isSelectedMode && self.beginNode){
                self.tempNodeA.setLocation(event.x,event.y);
            }
        });

        this.scene.mousedrag(event=>{
            if (!self.isSelectedMode && self.beginNode) {
                self.tempNodeZ.setLocation(event.x, event.y)
            }
        });

        //鼠标移出舞台
        this.stage.mouseout(event=>{
            // 删掉节点带出来的连线
            if (self.link && !self.isSelectedMode && (event.target == null || event.target === self.beginNode || event.target === self.link)) {
                self.scene.remove(self.link)
            }
        })

        this.scene.background = backImg;

    }

    //键盘事件
    @HostListener('window:keyup',['$event'])
    keyEvent(e:KeyboardEvent){
        if (e.shiftKey) {  // 组合键模式
            switch (e.which) {
                // 放大 ctrl+=
                case 187:
                case 61:
                    // 单个节点可以撤销操作
                    if (this.currentNode instanceof JTopo.Node) {
                        // 保存初始状态
                        this.utils.saveNodeInitState();
                        this.utils.scalingBig();
                        this.utils.saveNodeNewState();
                    } else {
                        this.utils.scalingBig();
                    }
                    break;
                // 缩小 ctrl+-
                case 189:
                case 173:
                    if (this.currentNode instanceof JTopo.Node) {
                        // 保存初始状态
                        this.utils.saveNodeInitState();
                        this.utils.scalingSmall();
                        this.utils.saveNodeNewState();
                    } else {
                        this.utils.scalingSmall();
                    }
                    break
                case 70:
                    // ctrl+f 全屏显示
                    this.utils.showInFullScreen(this.stage.canvas, 'RequestFullScreen')
                    break;
                case 72:
                    // h 帮助
                    // alert('帮助文档')
                    break;
                case 71:
                    // ctrl+g 居中显示
                    this.utils.showInCenter();
                    break;
                case 73:
                    // shif+I 逆时针旋转
                    if (this.currentNode instanceof JTopo.Node) {
                        this.utils.saveNodeInitState();
                        this.utils.rotateSub();
                        this.utils.saveNodeNewState();
                    }
                    break;
                case 67:
                    this.utils.cloneSelectedNodes();
                    break;
                case 80:
                    // ctrl + p
                    this.utils.showPic();
                    break;
                case 82:
                    // 单个节点重做
                    if (this.currentNode instanceof JTopo.Node) {
                        this.utils.reMakeNodeAction();
                    }
                    break;
                case 83:
                    // ctrl+s 保存
                    this.saveTopology(true);
                    break;
                case 85:
                    // shif+U 顺时针旋转
                    if (this.currentNode instanceof JTopo.Node) {
                        this.utils.saveNodeInitState();
                        this.utils.rotateAdd();
                        this.utils.saveNodeNewState()
                    }
                    break;
                case 87:
                    // alert('ctrl + w 另存为')
                    break
                case 89:
                    // ctrl+y
                    this.utils.clearTopology();
                    break
                case 90:
                    // 单个节点撤销
                    if (this.currentNode instanceof JTopo.Node) {
                        this.utils.cancleNodeAction()
                    }
                    break
            }
        } else if (e.which === 46) {              // 单独按下delete
            this.utils.deleteSelectedNodes()
        } else if (e.which === 17) {              // 单独按下ctrl
            this.isSelectedMode = true
        }
    }

    /**
     * 图元拖放功能实现
     * @param modeDiv 备选列表中的元素(各种样式的节点)
     * @param drawArea 舞台区域
     */
    drag(modeDiv, drawArea, text){
        if(!text){
            text = '';
        }
        let self = this;
        // 拖拽开始,携带必要的参数
        modeDiv.ondragstart =  (event)=> {
            event = event || window.event;
            let dragSrc = this;
            // let backImg = $(dragSrc).find('img').eq(0).attr('src')
            // backImg = backImg.substring(backImg.lastIndexOf('/') + 1)
            // let nodeType = $(this).attr('topo-nodetype')
            try {
                // IE只允许KEY为text和URL
                // event.dataTransfer.setData('text', backImg + ';' + text + ';' + nodeType)
            } catch (ex) {
                console.log(ex)
            }
        };
        // 阻止默认事件
        drawArea.ondragover =  (event)=> {
            event.preventDefault();
            return false
        };
        // 创建节点
        drawArea.ondrop = (event)=> {
            // 只读模式
            if (this.stageMode === "normal") {
                return;
            }

            event = event || window.event;
            let data = event.dataTransfer.getData('text');
            let img, text, nodeType;
            if (data) {
                let datas = data.split(';');
                if (datas && datas.length === 3) {
                    img = datas[0];
                    text = datas[1];
                    nodeType = datas[2];
                    let node = new JTopo.Node();
                    node.fontColor = self.config.nodeFontColor;
                    // 节点坐标
                    node.setBound((event.layerX ? event.layerX : event.offsetX) - self.scene.translateX - self.config.nodeDefaultWidth / 2,
                        (event.layerY ? event.layerY : event.offsetY) - self.scene.translateY - self.config.nodeDefaultHeight / 2, self.config.nodeDefaultWidth, self.config.nodeDefaultHeight);
                    // 节点图片
                    node.setImage( img);
                    // 节点数据
                    node.nodeId = generateUUID;
                    node.nodeType = nodeType;
                    node.text = text;
                    node.nodeImage = img;
                    self.scene.add(node);
                    self.currentNode = node;
                }
            }
        }
    }

    /**
     * 保存序列化的拓扑图成json
     */
    saveTopology(url){
        let self = this;
        // 保存container状态
        let containers = this.getContainers();
        for (let c = 0; c < containers.length; c++) {
            let temp = [];
            let nodes = containers[c].childs;
            for (let n = 0; n < nodes.length; n++) {
                if (nodes[n] instanceof JTopo.Node) {
                    temp.push(nodes[n].nodeId)
                }
            }
            containers[c].childNodes = temp.join(',')
        }
        // 获取json
        let topologyJSON = this.stage.toJson();
    }

    /**
     * 重置拓扑图
     */
    resetTopology(){

    }

    /**
     * 传入JSON形式的拓扑图数据,绘制拓扑图。如果数据结构不正确,返回空拓扑图
     * @param topologyJson json形式的拓扑结构数据
     * @param backImg 拓扑图的背景图片
     */
    loadTopologyByJson(topologyJson, backImg){
        this.init(backImg,topologyJson);
    }

    //工具方法
    /**
     * 清空所有节点
     */
    deleteAllNodes(){
        this.stage.childs.forEach(s=>{
            s.clear();
        });

        this.beginNode = null;
        this.link = null;
    }

    //编辑模式
    editTopology(){
        this.stageMode = 'edit';
        console.log(this);
    }

    //只读模式
    normalTopology(){

        this.stageMode = 'normal';
    }

    //添加节点
    addNode(img,text){
        if(this.stageMode === 'normal'){
            return;
        }
        if(!img){
            img  = 'icon_virtual_host.png';  //默认图片
        }
        if(!text){
            text = '主机';
        }
        let node = new JTopo.Node();
        node.fontColor = this.config.nodeFontColor;
        //节点坐标
        node.setBound(20,20,50,50);
        //默认图片
        node.setImage(img);
        //节点数据
        node.nodeId = generateUUID;
        node.text = text;
        node.nodeImage = img;
        this.scene.add(node);
    }

    //获取所以容器的内容
    getContainers(){
        let containers = [];
        this.stage.childs.forEach( (s) =>{
            s.childs.forEach((n)=> {
                if(n.elementType === 'container') {
                    containers.push(n)
                }
            })
        });
        return containers;
    }

    // 获取所有节点
    getAllNodes() {
        return this.stage.find('node');
    }

    // 获取所有选择的节点实例
    getSelectedNodes() {
        let selectedNodes = [];
        let nodes = this.scene.selectedElements;
        nodes.forEach( (n)=> {
            if (n.elementType === 'node') {
                selectedNodes.push(n)
            }
        });
        return selectedNodes
    }

    // 节点分组合并
    toMerge() {
        let selectedNodes = this.getSelectedNodes();
        // 不指定布局的时候,容器的布局为自动(容器边界随元素变化）
        let container = new JTopo.Container();
        container.textPosition = 'Top_Center';
        container.fontColor = this.config.nodeFontColor;
        container.borderColor = this.config.nodeBorderColor;
        container.borderRadius = this.config.nodeBorderRadius;
        this.scene.add(container);
        selectedNodes.forEach( (n)=> {
            container.add(n)
        })
    }

    // 分组拆除
    toSplit() {
        if (this.currentNode instanceof JTopo.Container) {
            this.currentNode.removeAll();
            this.scene.remove(this.currentNode)
        }
    }

    // 删除连线
    deleteLine() {
        if (this.currentNode instanceof JTopo.Link) {
            this.scene.remove(this.currentNode);
            // if (this.currentNode.id)
            //     this.deleteNodeById(this.currentNode.id, "link");
            this.currentNode = null;
        }
    }

    // 删除节点
    deleteNode(n) {
        this.scene.remove(n);
        // if (n.id)
        //     this.deleteNodeById(n.id, n.elementType, n.dataType);
        this.currentNode = null;
        // 连线重置
        this.beginNode = null;
        if (this.link) {
            this.scene.remove(this.link)
        }
        this.link = null
    }

    // 删除选择的节点
    deleteSelectedNodes() {
        if (this.stageMode !== 'edit') {
            return false
        }
        let self = this;
        let nodes = this.scene.selectedElements;
        if (nodes && nodes.length > 0) {
            for (let i = 0; i < nodes.length; i++) {
                self.deleteNode(nodes[i])
            }
        }
    }

    //设置
    // 放大
    scalingBig() {
        if (this.currentNode instanceof JTopo.Node) {
            this.currentNode.scaleX += this.config.nodeScale;
            this.currentNode.scaleY += this.config.nodeScale;
        } else {
            this.stage.zoomOut(this.stage.wheelZoom)
        }
    }

    // 缩小
    scalingSmall() {
        if (this.currentNode instanceof JTopo.Node) {
            this.currentNode.scaleX -= this.config.nodeScale;
            this.currentNode.scaleY -= this.config.nodeScale
        } else {
            this.stage.zoomIn(this.stage.wheelZoom);
        }
    }

    // 顺时针旋转
    rotateAdd() {
        if (this.currentNode instanceof JTopo.Node) {
            this.currentNode.rotate += this.config.nodeRotateValue
        }
    }

    // 逆时针旋转
    rotateSub() {
        if (this.currentNode instanceof JTopo.Node) {
            this.currentNode.rotate -= this.config.nodeRotateValue
        }
    }

    // 清空编辑器
    clearTopology() {
        // 删除节点表对应的节点记录
        this.deleteAllNodes()
    }

    // 拓扑图预览
    showPic() {
        this.stage.saveImageInfo()
    }

    exportAsImage() {
        this.stage.exportAsImage()
    }

    setEditMode() {
        this.stageMode = 'edit'
    }

    setNormalMode() {
        this.stageMode = 'normal'
    }

    // 复制节点
    cloneNode(n) {
        if (n instanceof JTopo.Node) {
            let newNode = new JTopo.Node();
            n.serializedProperties.forEach( (i)=> {
                // 只复制虚拟机的模板属性
                // if (i == "templateId" && n.dataType != "VM") return true;
                newNode[i] = n[i]
            })
            newNode.nodeId = generateUUID;
            newNode.alpha = this.config.nodeAlpha;
            newNode.strokeColor = this.config.nodeStrokeColor;
            newNode.fillColor = this.config.nodeFillColor;
            newNode.shadow = this.config.nodeShadow;
            newNode.shadowColor = this.config.nodeShadowColor;
            newNode.font = this.config.nodeFont;
            newNode.fontColor = this.config.nodeFontColor;
            newNode.borderRadius = null;
            newNode.layout = n.layout;
            newNode.selected = false;
            // var deviceNum = ++this.modeIdIndex;
            // newNode.deviceId = "device" + deviceNum;
            newNode.setLocation(n.x + n.width, n.y + n.height);
            newNode.text = n.text;
            newNode.setImage(n.image);
            this.scene.add(newNode);
        }
    }

    // 复制选择的节点
    cloneSelectedNodes() {
        let self = this;
        let nodes = this.scene.selectedElements;
        nodes.forEach((n)=> {
            if (n.elementType === 'node') {
                self.cloneNode(n)
            }
        })
    }

    // 全屏显示
    showInFullScreen(element, method) {
        let usablePrefixMethod;
        ['webkit', 'moz', 'ms', 'o', ''].forEach( (prefix)=> {
                if (usablePrefixMethod) {
                    return
                }
                if (prefix === '') {
                    // 无前缀，方法首字母小写
                    // method = method.slice(0, 1).toLowerCase() + method.slice(1)
                }
                let typePrefixMethod = typeof element[prefix + method];
                if (typePrefixMethod + '' !== 'undefined') {
                    if (typePrefixMethod === 'function') {
                        usablePrefixMethod = element[prefix + method]();
                    } else {
                        usablePrefixMethod = element[prefix + method];
                    }
                }
            }
        )
        return usablePrefixMethod
    }

    // 居中显示
    showInCenter() {
        this.stage.centerAndZoom()
    }

    // 根据指定的key返回节点实例
    getNodeByKey(key, value) {
        let node = null
        this.stage.childs.forEach( (s)=> {
            s.childs.forEach( (n)=> {
                if (n.elementType === 'node' && n[key] === value) {
                    node = n
                    return node
                }
            })
        });
        return node
    }

    // 撤销对节点的操作
    cancleNodeAction() {
        if (this.currentNode.currStep <= 0) {
            return
        }
        --this.currentNode.currStep;
        for (let p in this.currentNode) {
            if (p !== 'currStep') {
                this.currentNode[p] = (this.currentNode.historyStack[this.currentNode.currStep])[p]
            }
        }
    }

    // 重做节点操作
    reMakeNodeAction() {
        if (this.currentNode.currStep >= this.currentNode.maxHistoryStep ||
            this.currentNode.currStep >= this.currentNode.historyStack.length - 1) {
            return
        }
        this.currentNode.currStep++
        for (let q in this.currentNode) {
            if (q !== 'currStep') {
                this.currentNode[q] = (this.currentNode.historyStack[this.currentNode.currStep])[q]
            }
        }
    }

    // 保存节点新的状态
    saveNodeNewState() {
        // 如果历史栈超过最大可记录历史长度，丢弃第一个元素
        if (this.currentNode.historyStack.length >= this.currentNode.maxHistoryStep + 1) {
            this.currentNode.historyStack.shift()
        }
        this.currentNode.historyStack.push(JTopo.util.clone(this.currentNode))
        this.currentNode.currStep = this.currentNode.historyStack.length - 1
    }

    // 保存节点初始状态,便于回退
    saveNodeInitState() {
        if (!this.currentNode.hasInitStateSaved) {
            this.currentNode.historyStack.push(JTopo.util.clone(this.currentNode))
            this.currentNode.hasInitStateSaved = true
        }
    }

    // 取消出参数节点外所有节点的选中状态
    unSelectAllNodeExcept(node) {
        this.stage.childs.forEach( (s)=> {
            s.childs.forEach( (n)=> {
                // id属性无有效值，说明该节点没有保存到数据库
                if (n.nodeId !== node.nodeId) {
                    n.selected = false
                }
            })
        })
    }
}

export class generateUUID{
    constructor(){
        let d = new Date().getTime();
        let uuid = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g,  (c)=> {
            let r = (d + Math.random() * 16) % 16 | 0;
            d = Math.floor(d / 16);
            return (c === 'x' ? r : (r & 0x3 | 0x8)).toString(16)
        });
        return uuid
    }

}
