<!-- 
  标注组件1.0

  目录位置：AI智能化区域监控 -> 视频智能监控范围 -> 标注区域
  功能概述：引入轻量级图片2d标注组件canvas-select,通过添加透明图层,与rtsp视频流结合,实现视频监控区域标注
 -->
<template>
  <a-modal
    :keyboard="false"
    :maskClosable="false"
    :forceRender="true"
    :visible="visible"
    :title="title"
    width="1080px"
    @cancel="handleCancel"
    destroyOnClose
  >
    <a-row class="video_area">
      <canvas ref="canvas" class="container"></canvas>
      <div class="mpegPlayer" ref="mpegPlayer"></div>
    </a-row>
    <a-row class="operate_area">
      <div>
        <a-space :size="12">
          <a-button shape="round" size="middle" @click="change(0)"> <ApiOutlined /> 退出创建</a-button>
          <a-button type="primary" shape="circle" size="large" @click="change(1)" title="创建矩形">
            <img class="icon_style" src="./assets/rect_icon.png" />
          </a-button>
          <a-button type="primary" shape="circle" size="large" @click="change(2)" title="创建多边形">
            <img class="icon_style" src="./assets/polo_icon.png" />
          </a-button>
          <a-button type="primary" shape="circle" size="large" @click="change(3)" title="创建标记点">
            <img class="icon_style" src="./assets/point_icon.png" />
          </a-button>
          <a-button type="primary" shape="circle" size="large" @click="change(4)" title="创建线">
            <img class="icon_style" src="./assets/line_icon.png" />
          </a-button>
          <a-button type="primary" shape="circle" size="large" @click="change(5)" title="创建圆">
            <img class="icon_style" src="./assets/circle_icon.png" />
          </a-button>
          <a-button type="primary" shape="round" size="middle" @click="onFocus()"><AimOutlined />专注模式</a-button>
          <a-button type="primary" shape="round" size="middle" @click="lock()"><LinkOutlined />锁定/解锁</a-button>
          <a-button type="primary" shape="round" danger size="middle" @click="clear()"> <FormatPainterOutlined />清除标注 </a-button>
        </a-space>
      </div>
      <div>
        <a-card size="small" :bordered="false" style="width: 200px; height: 80px">
          <p>1.ESC键回退节点</p>
          <p>2.BackSpace键删除图形</p>
        </a-card>
      </div>
    </a-row>
    <template #footer="">
      <a-popconfirm title="是否保存标注?" ok-text="确认" cancel-text="取消" @confirm="handleOk()" @cancel="handleCancel">
        <a-button type="primary">保存</a-button>
      </a-popconfirm>
    </template>
  </a-modal>
</template>
<script lang="ts" setup>
  import { ref, getCurrentInstance, onMounted, onBeforeUnmount, nextTick, watch } from 'vue';
  import { ApiOutlined, FormatPainterOutlined, AimOutlined, LinkOutlined } from '@ant-design/icons-vue';
  const { proxy }: any = getCurrentInstance();
  const props = defineProps({
    title: {
      type: String,
      default: '区域标注',
    },
    visible: {
      type: Boolean,
      default: true,
    },
    // rtsp视频流地址
    videoUrl: {
      type: String,
      default: '',
    },
    // 绘制数据——回显
    labelData: {
      type: String,
      default: '',
    },
    // 点位数据——传递
    locationData: {
      type: String,
      default: '',
    },
  });

  const emit = defineEmits(['update:label-data', 'update:location-data']);

  /* 播放rtsp视频相关 */
  import MpegPlayer from 'jsmpeg-player';
  const { ipcRenderer } = require('electron');
  // DOM承载实例
  const mpegPlayer = ref();
  // 参数配置对象
  const playOption = ref({
    decodeFirstFrame: true,
  });
  // 消息
  const msg = ref('');
  // 播放容器
  let player: any = ref(null);
  // 开启播放
  const open = () => {
    const res = ipcRenderer.sendSync('openRtsp', props.videoUrl);
    if (res.code === 200) {
      player.value = new MpegPlayer.VideoElement(mpegPlayer.value, res.ws, playOption);
    }
    msg.value = res.msg;
  };
  // 关闭播放
  const close = () => {
    const res = ipcRenderer.sendSync('closeRtsp', props.videoUrl);
    msg.value = res.msg;
  };

  /* 标注区域相关 */
  // 导入2d绘图插件canvas-Select
  import CanvasSelect from 'canvas-select';
  // canvas实例
  const canvas = ref(null);
  // 导入透明静态图片
  const hideUrl = new URL('./assets/hide.png', import.meta.url).href;
  // 标注实例
  let instance: any = ref(null);
  // 图形标注列表
  const option: any = ref([]);

  // 选择绘制工具
  function change(num: any) {
    instance.createType = num;
  }
  // 清除标注数据
  function clear() {
    instance.setData([]);
  }
  // 专注模式
  function onFocus() {
    instance.setFocusMode(!instance.focusMode);
  }
  // 锁定/解锁画布
  function lock() {
    instance.lock = !instance.lock;
  }
  // 保存数据
  function save() {
    /* 保存绘制数据，用于回显 */
    // 清除所有激活状态
    instance.dataset.forEach((item) => {
      item.active = false;
    });
    // 更新标注数据到表单
    emit('update:label-data', JSON.stringify(instance.dataset));
    /* 保存区域界限节点数据，用于后端分析 */
    // 二次处理
    const newData = instance.dataset.map((item) => {
      let typeString;
      switch (item.type) {
        case 1:
          typeString = 'rect';
          break;
        case 2:
          typeString = 'polygon';
          break;
        case 3:
          typeString = 'dot';
          break;
        case 4:
          typeString = 'line';
          break;
        case 5:
          typeString = 'circle';
          break;
        default:
          typeString = '';
      }

      const newShape: any = {
        type: typeString,
        coor: item.coor,
      };

      if (item.type === 5) {
        // 如果type为5（circle），则添加radius属性
        newShape.radius = item.radius;
      }

      return newShape;
    });
    // 更新节点数据到表单
    emit('update:location-data', JSON.stringify(newData));
  }
  // 删除选中图形 backspace / 回退绘制节点 esc
  function changeSelect(event) {
    if (event.keyCode == 8) {
      // 删除选中图形
      instance.dataset = instance.dataset.filter((item) => !item.active);
      // 更新视图
      instance.update();
    } else if (event.keyCode == 27) {
      // 是否节点已删除完毕
      let delete_status = 0;
      // 回退绘制节点
      instance.dataset.forEach((item) => {
        if (item.active === true && item.creating === true) {
          // 矩形
          if (item.type == 1) {
            if (item.coor.length > 1) {
              // 回退
              item.coor = [];
              // 删除完毕
              delete_status = 1;
            }
          }
          // 圆形
          else if (item.type == 5) {
            if (item.coor.length > 1) {
              // 回退
              item.coor = [];
              item.radius = 0;
              // 删除完毕
              delete_status = 1;
            }
          }
          // 其他图形
          else {
            if (item.coor.length > 1) {
              // 回退上一个节点
              item.coor.pop();
            } else {
              // 删除完毕
              delete_status = 1;
            }
          }
          // 更新视图
          instance.update();
        }
      });
      if (delete_status === 1) {
        // 删除残余数据
        instance.dataset = instance.dataset.filter((item) => !item.active);
        // 更新视图
        instance.update();
      }
    }
  }

  onMounted(() => {
    // 播放视频
    open();
    // 添加键盘事件监听
    document.addEventListener('keydown', changeSelect);
    // 载入绘图数据
    if (props.labelData == '') {
      option.value = [];
    } else {
      option.value = JSON.parse(props.labelData);
    }
    // 创建实例
    instance = new CanvasSelect('.container', hideUrl);
    // 标签最大长度
    instance.labelMaxLen = 10;
    // 禁用滚动缩放
    instance.scrollZoom = false;
    // 图形数据赋值到实例
    instance.setData(option.value);
    // 形状边线宽度
    instance.lineWidth = 2;
    // 标签字体
    instance.labelFont = '12px Arial';
    // 标签填充颜色
    instance.labelFillStyle = '#fa4545';
    // 标签文字颜色
    instance.textFillStyle = '#fff';
    // 控制点半径
    instance.ctrlRadius = 4;
    // 图片加载完成
    instance.on('load', (src: any) => {
      // console.log('image load', src);
    });

    // 添加
    instance.on('add', (info: any) => {
      // 添加默认标签
      switch (instance.createType) {
        case 1:
          info.label = '矩形防区';
          break;
        case 2:
          info.label = '多边形防区';
          break;
        case 3:
          info.label = '标记点位';
          break;
        case 4:
          info.label = '报警界线';
          break;
        case 5:
          info.label = '圆形防区';
          break;
        default:
          info.label = '未定义';
      }
      // 更新画布
      instance.update();
    });
    // 删除 - 弃用内置删除方法
    // instance.on('delete', (info: any) => {
    //   console.log('删除', info);
    // });
    // 选中
    instance.on('select', (shape: any) => {
      // console.log('选中', shape);
    });
    // 更新
    instance.on('updated', (result: any) => {
      // console.log('更新', result);
    });
  });
  // 在组件卸载时移除事件监听
  // 考虑到你想要的是在页面卸载前移除事件监听，因此这里使用了`beforeUnmount`
  // 如果你希望在页面卸载后再移除事件监听，可以使用`onUnmounted`
  onBeforeUnmount(() => {
    document.removeEventListener('keydown', changeSelect);
  });
  // 确定
  async function handleOk() {
    // 保存提交
    save();
    // 关闭窗口
    handleCancel();
  }
  // 取消
  function handleCancel() {
    nextTick(() => {
      // 关闭窗口
      proxy.$parent.videoVisible = false;
      // 关闭播放
      close();
    });
  }
</script>
<style lang="less" scoped>
  .video_area {
    width: 100%;
    height: 580px;
    margin: 0 auto;
    position: relative;
    background: #000;
    .container {
      width: 1080px;
      height: 580px;
      position: absolute;
      z-index: 9999;
      left: 0;
      top: 0;
    }
    .mpegPlayer {
      width: 100%;
      height: 100%;
      background: #000;
    }
  }
  .operate_area {
    width: 100%;
    display: flex;
    align-items: center;
    justify-content: space-evenly;
    .icon_style {
      width: 24px;
      height: 24px;
      margin: 0 auto;
    }
  }
</style>
