<template>
  <div id="app">
    <!-- 展示 -->
    <div id="openseadragon" />
    <!-- 参数调试 -->
    <div class="params">
      <label>
        <Input v-model="Width" readonly>
          <template #prepend>
            <span>CAD宽度</span>
          </template>
        </Input>
      </label>
      <label>
        <Input v-model="Height" readonly>
          <template #prepend>
            <span>CAD高度</span>
          </template>
        </Input>
      </label>
      <label>
        <Input v-model="scale" @on-blur="initViewer">
          <template #prepend>
            <span>隧道比例</span>
          </template>
        </Input>
      </label>
    </div>
    <div class="text">
      <p style="font-size: 17px">
        注：
      </p>
      <p>1. CAD宽高 = 切图宽高 * X_Y.JPG,自动计算</p>
      <p>2. 比例使用 1/比例</p>
    </div>
  </div>
</template>

<script setup>
import { onMounted, ref, watchEffect } from 'vue'
import { Input } from 'view-ui-plus'
import 'view-ui-plus/dist/styles/viewuiplus.css'
import OpenSeadragon from 'openseadragon'
import { svgOverlay } from '@/utils/openseadragon-svg-overlay'
import axios from '@/utils/axios'
// 数据
const scale = ref(0)
const Width = ref(process.env.imgSize.W)
const Height = ref(process.env.imgSize.H)
const SIZE = process.env.imgSize.S
let overlay = null
let viewer = null
const CADPATH = 'CAD_1/'
const SVGPATH = 'tunnel/1.svg'
const RINGWIDTH = 70
const STARTRing = 1
const TOTALRING = 8000
const currentRing = 4500
const MAXZOOM = process.env.imgSize.M
let tunnelPath = null

// 获取svg路径
const getTunnelPath = async () => {
  const txt = await axios.get(SVGPATH)
  const objE = document.createElement('div')
  objE.innerHTML = txt
  let svg = objE.lastElementChild
  svg = document.importNode(svg, true)
  const path = svg.getElementsByTagName('path')
  // 隧道比例默认SVG宽度
  const num = +svg.getAttribute('width').replace(/[^0-9]/gi, '')
  scale.value = num
  tunnelPath = path
}

/**
 * 获取角度
 * @params x0 上一环x
 * @params y0 上一环y
 * @params x1 当前环x
 * @params y2 当前环y
 * @returns [角度，x,y]
 */
const getDeg = (x0, y0, x1, y1) => {
  const x = (x0 + x1) / 2
  const y = (y0 + y1) / 2
  const xX = x1 - x0
  const yY = y0 - y1
  const degrees = Math.abs(
    (Math.asin(yY / Math.sqrt(yY * yY + xX * xX)) * 180) / Math.PI
  )
  let MyAngle
  if (xX >= 0 && yY >= 0) MyAngle = 270 + (90 - degrees)
  if (xX >= 0 && yY <= 0) MyAngle = degrees
  if (xX <= 0 && yY <= 0) MyAngle = 90 + (90 - degrees)
  if (xX <= 0 && yY >= 0) MyAngle = 180 + degrees
  return [ MyAngle, x, y ]
}

/**
 * 根据环号获取点位
 * @params sRing 开始环
 * @params eRing 结束环
 * @params path  隧道路径 默认上路径
 * @returns [{x,y}]
 */
const getPoint = (sRing, eRing, path = tunnelPath[0]) => {
  if (!path) return []
  const StartRingPnt = [] // 通风里程点位
  const length = path.getTotalLength()
  for (let k = sRing; k < eRing; k++) {
    const Pnts = path.getPointAtLength(length * (k / TOTALRING))
    StartRingPnt.push(Pnts)
  }
  return StartRingPnt
}

/**
 * 画通风管道
 * @params sRing 开始环
 * @params eRing 结束环
 * @params type 类型 1 直通道 | 2 转弯通道 默认转弯通道
 * @returns dom-line
 */
const drawLines = (sRing, eRing, type = 2, sRing2 = '22715.705078125,11780.609375', eRing2 = '23547.28515625,11636.23828125') => {
  // 通风里程点位
  const StartRingPnt = getPoint(sRing, eRing)
  // 添加通风管道=>转弯里程一定要是车行道开始里程
  const line = document.createElementNS('http://www.w3.org/2000/svg', 'polyline')
  line.setAttributeNS(null, 'fill', 'none')
  line.setAttributeNS(null, 'stroke', '#696969')
  line.setAttributeNS(null, 'stroke-width', 25)
  let txt2 = ''
  for (let k = 0; k < StartRingPnt.length; k++) {
    const el = StartRingPnt[k]
    if (type === 2) {
      if (k < StartRingPnt.length) {
        txt2 += `${el.x + RINGWIDTH / 2 - 20},${el.y + RINGWIDTH / 2 - 20} `
      } else {
        txt2 += `${el.x},${el.y} `
      }
    }
    if (type === 1) {
      txt2 += `${el.x - RINGWIDTH / 2},${el.y - RINGWIDTH / 2} `
    }
  }
  if (type === 2) txt2 += `${sRing2} ${eRing2}` // 另一个隧道开始点位
  line.setAttributeNS(null, 'transform', `translate(0 0) scale(${1 / scale.value})`)
  line.setAttributeNS(null, 'points', txt2)
  return line
}

/**
 * 画隧道
 * @params sRing 开始环
 * @params eRing 结束环
 * @params path 隧道路径
 * @returns obj-dom
 */
const drawTunnel = (sRing, eRing, path = tunnelPath[0]) => {
  // 未挖段->根据开始结束区分开挖和未开挖
  const StartRingPnt = getPoint(sRing, eRing)
  const line = document.createElementNS('http://www.w3.org/2000/svg', 'polyline')
  line.setAttributeNS(null, 'fill', 'none')
  line.setAttributeNS(null, 'stroke', '#696969')
  line.setAttributeNS(null, 'stroke-width', RINGWIDTH)
  let txt = ''
  for (let k = 0; k < StartRingPnt.length; k++) {
    const el = StartRingPnt[k]
    txt += `${el.x},${el.y} `
  }
  line.setAttributeNS(null, 'transform', `translate(0 0) scale(${1 / scale.value})`)
  line.setAttributeNS(null, 'points', txt)
  // 当前环
  const cRing = sRing >= 0 ? sRing : eRing
  const rect = document.createElementNS('http://www.w3.org/2000/svg', 'rect')
  const length = path.getTotalLength()
  const PrePnt = path.getPointAtLength(length * ((cRing - 1) / TOTALRING))
  const Pnt = path.getPointAtLength(length * (cRing / TOTALRING))
  const deg = getDeg(PrePnt.x, PrePnt.y, Pnt.x, Pnt.y)
  const ringWidth = (1 / TOTALRING) * length * STARTRing
  rect.setAttributeNS(null, 'x', deg[1] - ringWidth / 2)
  rect.setAttributeNS(null, 'y', deg[2] - RINGWIDTH / 2)
  rect.setAttributeNS(null, 'height', RINGWIDTH)
  rect.setAttributeNS(null, 'width', ringWidth)
  rect.setAttributeNS(null, 'fill', '#87CEFA')
  rect.setAttributeNS(null, 'transform', `translate(0 0) scale(${1 / scale.value}) rotate(${deg[0]} ${deg[1]} ${deg[2]})`)
  // 点击事件
  viewer.svgOverlay().onClick(rect, (e) => {
    console.log(666, e)
  })
  return { line, rect }
}

/**
 * 文字
 * @params cRing 当前环
 * @params path 隧道路径
 * @returns dom-text
 */
const drawText = (cRing, path = tunnelPath[0]) => {
  const length = path.getTotalLength()
  const PrePnt = path.getPointAtLength(length * ((cRing - 1) / TOTALRING))
  const Pnt = path.getPointAtLength(length * (cRing / TOTALRING))
  const deg = getDeg(PrePnt.x, PrePnt.y, Pnt.x, Pnt.y)
  const text = document.createElementNS('http://www.w3.org/2000/svg', 'text')
  text.innerHTML = '666666'
  text.setAttributeNS(null, 'x', Pnt.x)
  text.setAttributeNS(null, 'y', Pnt.y)
  text.setAttributeNS(null, 'fill', 'red')
  text.setAttribute('transform', `scale(${1 / scale.value}) rotate(${deg[0]} ${deg[1]} ${deg[2]}) `)
  return text
}

/**
 * 文字自身旋转
 * @params cRing 当前环
 * @params path 隧道路径
 * @returns dom-text
 */
const drawText2 = (cRing, path = tunnelPath[0]) => {
  const length = path.getTotalLength()
  const Pnt = path.getPointAtLength(length * (cRing / TOTALRING))
  const text = document.createElementNS('http://www.w3.org/2000/svg', 'text')
  text.innerHTML = '555555'
  text.setAttributeNS(null, 'x', Pnt.x)
  text.setAttributeNS(null, 'y', Pnt.y)
  text.setAttributeNS(null, 'fill', 'red')
  // 测试自身旋转
  text.setAttribute('transform', `scale(${1 / scale.value}) rotate(${80} ${Pnt.x} ${Pnt.y}) `)
  return text
}

// 初始化
svgOverlay(OpenSeadragon)
const initViewer = async () => {
  if (viewer) {
    viewer.destroy()
    viewer = null
    overlay = null
  }
  // 获取CAD切图地址
  viewer = OpenSeadragon({
    id: 'openseadragon',
    prefixUrl: '/planIcon/',
    showNavigationControl: true,
    showZoomControl: false,
    showHomeControl: false,
    showFullPageControl: false,
    showFlipControl: false,
    showRotationControl: false,
    zoomPerClick: 1,
    navigationControlAnchor: OpenSeadragon.ControlAnchor.TOP_LEFT,
    showNavigator: true,
    navigatorPosition: 'BOTTOM_RIGHT',
    navigatorSizeRatio: 0.125,
    minZoomLevel: 1,
    maxZoomLevel: MAXZOOM,
    defaultZoomLevel: 4,
    debugMode: false,
    visibilityRatio: 1.0,
    constrainDuringPan: false,
    tileSources: {
      height: Height.value,
      width: Width.value,
      tileSize: SIZE,
      minLevel: 9,
      maxLevel: 15,
      getTileUrl(level, x, y) {
        level -= 9
        level = 2 ** level
        // return `http://cp.caner.top:9080/public/admin/cad_config/CAD_1/${level}/${x}_${y}.jpg`
        return `${CADPATH + level}/${x}_${y}.jpg`
      }
    }
  })
  overlay = viewer.svgOverlay().node()
  // 添加隧道
  const { line, rect } = drawTunnel(currentRing, TOTALRING)
  overlay.append(line)
  overlay.append(rect)
  // 添加通风管道
  const line2 = drawLines(3798.5 - 150, 3798.5)
  overlay.append(line2)
  // 添加直通隧道
  const line3 = drawLines(150, 1500, 1)
  overlay.append(line3)
  // 添加wenz
  const txt = drawText(currentRing)
  const txt2 = drawText2(currentRing)
  overlay.append(txt)
  overlay.append(txt2)
}

// 监听缩放
watchEffect(() => {
  console.log('scale 被修改', scale.value)
})

// 生命周期
onMounted(async () => {
  await getTunnelPath()
  initViewer()
})
</script>
<style lang="less" scoped>
#app {
  width: 1000px;
  height: 800px;
  margin: 0 auto;
  text-align: center;
  color: #2c3e50;
  user-select: none;
  #openseadragon {
    width: 1000px;
    height: 600px;
    border: solid 1px #ccc;
  }
  .params {
    width: 100%;
    display: flex;
    margin-top: 10px;
    // justify-content: center;
    & > label {
      margin-right: 10px;
    }
  }
  .text {
    color: red;
    font-size: 13px;
    margin-top: 10px;
    text-align: left;
    & > p:not(:first-child) {
      text-indent: 20px;
    }
  }
}
</style>
<style>
.openseadragon-canvas {
  outline: none !important;
}
</style>
