<template>
  <div class="containers">
    <div class="canvas" id="canvas" ref="canvas" />
    <panel v-if="bpmnModeler" :xmlStr="xmlStr" :users="users" :roles="roles" :modeler="bpmnModeler" />
    <div class="toolbar">
      <a @click="save" title="download">保存</a>
      <!-- <a ref="saveDiagram" href="javascript:" title="download BPMN diagram">BPMN</a> -->
      <!-- <a ref="saveSvg" href="javascript:" title="download as SVG image">SVG</a> -->
    </div>
  </div>
</template>

<script>
import BpmnModeler from "bpmn-js/lib/Modeler"; // bpmn-js 设计器
import panel from "./PropertyPanel.vue"; // 属性面板
import translate from './customTranslate'
import BpmData from "./BpmData";
// import { v4 as uuidv4 } from 'uuid';
const id = `Process_${new Date().getTime()}${Math.floor(Math.random() * 1000)}`;
// const uuidName = uuidv4().replace(/-/g, '');
// const uuidEl = uuidv4().replace(/-/g, '');
export default {
  data() {
    return {
      bpmnModeler: null,
      element: null,
      bpmData: new BpmData(),
      xmlStr: "",
      viewer: null,
      baseXml: `
        <bpmn:definitions xmlns:bpmn="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:dc="http://www.omg.org/spec/DD/20100524/DC" xmlns:di="http://www.omg.org/spec/DD/20100524/DI" xmlns:camunda="http://camunda.org/schema/1.0/bpmn" id="Definitions_0001" targetNamespace="http://bpmn.io/schema/bpmn">
          <bpmn:process id="${id}" name="测试流程" isExecutable="true" camunda:historyTimeToLive="30">
            <bpmn:startEvent id="Event_0q2jipr">
              <bpmn:outgoing>Flow_08rsrwn</bpmn:outgoing>
            </bpmn:startEvent>
            <bpmn:sequenceFlow id="Flow_08rsrwn" sourceRef="Event_0q2jipr" targetRef="Activity_0xaoau1" />
            <bpmn:endEvent id="Event_0d86wvr">
              <bpmn:incoming>Flow_1b28yw8</bpmn:incoming>
            </bpmn:endEvent>
            <bpmn:sequenceFlow id="Flow_1b28yw8" sourceRef="Activity_0xaoau1" targetRef="Event_0d86wvr" />
            <bpmn:userTask id="Activity_0xaoau1">
              <bpmn:incoming>Flow_08rsrwn</bpmn:incoming>
              <bpmn:outgoing>Flow_1b28yw8</bpmn:outgoing>
            </bpmn:userTask>
          </bpmn:process>
          <bpmndi:BPMNDiagram id="BPMNDiagram_1">
            <bpmndi:BPMNPlane id="BPMNPlane_1" bpmnElement="${id}">
              <bpmndi:BPMNShape id="Event_0q2jipr_di" bpmnElement="Event_0q2jipr">
                <dc:Bounds x="392" y="232" width="36" height="36" />
              </bpmndi:BPMNShape>
              <bpmndi:BPMNShape id="Event_0d86wvr_di" bpmnElement="Event_0d86wvr">
                <dc:Bounds x="632" y="232" width="36" height="36" />
              </bpmndi:BPMNShape>
              <bpmndi:BPMNShape id="Activity_1tydg5i_di" bpmnElement="Activity_0xaoau1">
                <dc:Bounds x="480" y="210" width="100" height="80" />
              </bpmndi:BPMNShape>
              <bpmndi:BPMNEdge id="Flow_08rsrwn_di" bpmnElement="Flow_08rsrwn">
                <di:waypoint x="428" y="250" />
                <di:waypoint x="480" y="250" />
              </bpmndi:BPMNEdge>
              <bpmndi:BPMNEdge id="Flow_1b28yw8_di" bpmnElement="Flow_1b28yw8">
                <di:waypoint x="580" y="250" />
                <di:waypoint x="632" y="250" />
              </bpmndi:BPMNEdge>
            </bpmndi:BPMNPlane>
          </bpmndi:BPMNDiagram>
        </bpmn:definitions>
        `
    };
  },
  props: {
    users: {
      type: Array,
      required: true
    },
    roles: {
      type: Array,
      required: true
    },
    'bpmnXml':{
      type: String,
      default: ''
    }
  },
  components: {
    panel
  },
  watch: {
    bpmnXml: {
      handler: function(newVal, oldVal) {
        if (newVal && newVal !== oldVal) {
          //重新根据新的xml生成新的流程图
          console.log('流程图更新')
          if( this.bpmnModeler ) this.createNewDiagram();
        }
      },
      immediate: true
    }
  },
  mounted() {
    const canvas = this.$refs.canvas;
    let customTranslate = {
      translate: [ 'value', translate ]
    };
    // 生成实例
    this.bpmnModeler = new BpmnModeler({
      container: canvas,
      additionalModules: [
        customTranslate
      ]
    });
    // // 新增流程定义
    this.createNewDiagram();
  },
  methods: {
    createNewDiagram() {
      this.xmlStr = this.bpmnXml || this.baseXml;
      // 将字符串转换成图显示出来
      this.bpmnModeler.importXML(this.xmlStr);
    },
    async save(){
      this.bpmnModeler.saveXML({ format: true }).then(res => {
        this.$emit('save',res.xml)
      })
      // 
    },
    // 调整左侧工具栏排版
    adjustPalette() {
      try {
        // 获取 bpmn 设计器实例
        const canvas = this.$refs.canvas;
        const djsPalette = canvas.children[0].children[1].children[4];
        const djsPalStyle = {
          width: "130px",
          padding: "5px",
          background: "white",
          left: "20px",
          borderRadius: 0
        };
        for (var key in djsPalStyle) {
          djsPalette.style[key] = djsPalStyle[key];
        }
        const palette = djsPalette.children[0];
        const allGroups = palette.children;
        allGroups[0].style["display"] = "none";
        // 修改控件样式
        for (var gKey in allGroups) {
          const group = allGroups[gKey];
          for (var cKey in group.children) {
            const control = group.children[cKey];
            const controlStyle = {
              display: "flex",
              justifyContent: "flex-start",
              alignItems: "center",
              width: "100%",
              padding: "5px"
            };
            if (
              control.className &&
              control.dataset &&
              control.className.indexOf("entry") !== -1
            ) {
              const controlProps = this.bpmData.getControl(
                control.dataset.action
              );
              control.innerHTML = `<div style='font-size: 14px;font-weight:500;margin-left:15px;'>${
                controlProps["title"]
              }</div>`;
              for (var csKey in controlStyle) {
                control.style[csKey] = controlStyle[csKey];
              }
            }
          }
        }
      } catch (e) {
        console.log(e);
      }
    },
    // 下载为SVG格式,done是个函数，调用的时候传入的
    saveSVG(done) {
      // 把传入的done再传给bpmn原型的saveSVG函数调用
      this.bpmnModeler.saveSVG(done);
    },
    // 下载为SVG格式,done是个函数，调用的时候传入的
    saveDiagram(done) {
      // 把传入的done再传给bpmn原型的saveXML函数调用
      this.bpmnModeler.saveXML({ format: true }, (xml, err) =>{
        console.log('xml :>> ', xml);
        this.xmlStr = xml;
        // done(err, xml);
      });
    },
    // 当图发生改变的时候会调用这个函数，这个data就是图的xml
    setEncoded(link, name, data) {
      // 把xml转换为URI，下载要用到的
      const encodedData = encodeURIComponent(data);
      // 获取到图的xml，保存就是把这个xml提交给后台
      this.xmlStr = data;
      // 下载图的具体操作,改变a的属性，className令a标签可点击，href令能下载，download是下载的文件的名字
      if (data) {
        link.className = "active";
        link.href = "data:application/bpmn20-xml;charset=UTF-8," + encodedData;
        link.download = name;
      }
    }
  }
};
</script>

<style lang="scss">
@import "bpmn-js/dist/assets/diagram-js.css";
@import 'bpmn-js/dist/assets/bpmn-font/css/bpmn.css';
@import 'bpmn-js/dist/assets/bpmn-font/css/bpmn-codes.css';
@import 'bpmn-js/dist/assets/bpmn-font/css/bpmn-embedded.css'; // 样式
.containers {
  position: absolute;
  background-color: #ffffff;
  width: 100%;
  height: 100%;
  .canvas {
    width: 100%;
    height: 100%;
  }
  .panel {
    position: absolute;
    right: 0;
    top: 50px;
    width: 300px;
  }
  .bjs-powered-by {
    display: none;
  }
  .toolbar {
    position: absolute;
    top: 20px;
    right: 350px;
    a {
      text-decoration: none;
      margin: 5px;
      color: #409eff;
      cursor: pointer;
    }
  }
}
</style>
