<template>
  <div ref="viewport-fusion" class="viewport-wrapper" @mouseup="sliderMouseup" @mousemove="sliderMousemove"
    @mouseleave="sliderMouseleave" :style="{ color: series.Modality === 'PT' || isMip ? '#666' : '#ddd' }">
    <div v-if="series && taskInfo" class="left-top-text">
      <div v-if="taskInfo.IsExistsClinicalData && !isMip && !isFusion" class="cd-info"
        :title="$t('trials:reading:button:clinicalData')">
        <svg-icon style="cursor: pointer;" icon-class="documentation" class="svg-icon"
          @click.stop="viewCD(series.TaskInfo.VisitTaskId)" />
      </div>
      <h2 v-if="taskInfo.IsReadingShowSubjectInfo && series.TaskInfo" class="subject-info">
        {{ `${series.TaskInfo.SubjectCode} ${series.TaskInfo.TaskBlindName} ` }}
      </h2>
      <div v-if="!isMip && !isFusion">Series: #{{ series.SeriesNumber }}</div>
      <div v-if="series.Stack && !isMip">Image: #{{ `${series.SliceIndex + 1}/${series.Stack.length}` }}</div>
      <div v-if="!isMip && !isFusion">{{ series.Modality }}</div>
    </div>
    <!-- <div v-if="series && taskInfo && taskInfo.IsReadingTaskViewInOrder === 1 && series.TaskInfo && !isMip && !isFusion"
      class="top-center-tool">
      <div class="toggle-visit-container">
        <div class="arrw_icon"
          :style="{ cursor: series.TaskInfo.VisitTaskNum !== 0 ? 'pointer' : 'not-allowed', color: series.TaskInfo.VisitTaskNum !== 0 ? '#fff' : '#6b6b6b' }"
          @click.stop.prevent="toggleTask($event, series.TaskInfo.VisitTaskNum, -1)"
          @dblclick.stop="preventDefault($event)">
          <i class="el-icon-caret-left" />
        </div>
        <div class="arrow_text">
          {{ series.TaskInfo.TaskBlindName }}
        </div>
        <div class="arrw_icon"
          :style="{ cursor: series.TaskInfo.VisitTaskNum < taskInfo.VisitNum ? 'pointer' : 'not-allowed', color: series.TaskInfo.VisitTaskNum < taskInfo.VisitNum ? '#fff' : '#6b6b6b' }"
          @click.stop.prevent="toggleTask($event, series.TaskInfo.VisitTaskNum, 1)"
          @dblclick.stop="preventDefault($event)">
          <i class="el-icon-caret-right" />
        </div>
      </div>
    </div> -->
    <div v-if="series && !isMip && !isFusion" class="right-top-text">
      <div>{{ series.Description }}</div>
    </div>
    <div v-if="series" class="left-bottom-text">
      <div v-show="mousePosition.index.length > 0 && !isMip">
        Pos: {{ mousePosition.index[0] }}, {{ mousePosition.index[1] }}, {{ mousePosition.index[2] }}
      </div>
      <div
        v-if="(series.Modality === 'CT' || series.Modality === 'DR' || series.Modality === 'CR') && mousePosition.value && !isMip && !isFusion">
        HU: {{ mousePosition.value }}
      </div>
      <div v-else-if="(series.Modality === 'PT' && mousePosition.value) && !isMip && !isFusion">
        SUVbw(g/ml): {{ digitPlaces === -1 ? mousePosition.value.toFixed(3) : mousePosition.value.toFixed(digitPlaces)
        }}
      </div>
      <div v-else-if="mousePosition.value && !isMip && !isFusion">
        Density: {{ mousePosition.value }}
      </div>
      <div v-show="imageInfo.size && !isMip && !isFusion">
        W*H: {{ imageInfo.size }}
      </div>
    </div>
    <div v-if="series && !isMip" class="right-bottom-text">
      <div v-show="imageInfo.location && !isFusion">Location: {{ `${Number(imageInfo.location).toFixed(digitPlaces)} mm`
      }}</div>
      <div v-show="series.SliceThickness && !isFusion">Slice Thickness: {{
        `${Number(series.SliceThickness).toFixed(digitPlaces)} mm`
      }}</div>
      <div v-show="imageInfo.wwwc">WW/WL: {{ imageInfo.wwwc }}</div>
    </div>
    <div class="orientation-top" v-if="!isMip">
      {{ markers.top }}
    </div>
    <div class="orientation-right" v-if="!isMip">
      {{ markers.right }}
    </div>

    <div class="orientation-bottom" v-if="!isMip">
      {{ markers.bottom }}
    </div>
    <div class="orientation-left" v-if="!isMip">
      {{ markers.left }}
    </div>
    <div v-if="isFusion" class="color_bar">
      <canvas :id="`colorBar_Canvas_${viewportId}`" />
      <!-- <div id="colorBar_Canvas" />  -->
    </div>
    <div v-if="isMip" id="rotateBar" ref="rotateBar" class="rotate_slider_box" @click.stop="clickRotate($event)">
      <div id="rotateSlider" :style="{ left: rotateBarLeft + 'px' }" class="box" @click.stop.prevent="() => { return }"
        @mousedown.stop="rotateBarMousedown($event)" />
    </div>
    <div ref="sliderBox" class="right-slider-box" @click.stop="clickSlider($event)" v-show="!isMip">
      <div :style="{ top: sliderInfo.height + '%' }" class="slider" @click.stop.prevent="() => { return }"
        @mousedown.stop="sliderMousedown($event)" />
    </div>
  </div>
</template>
<script>
// import * as cornerstonejs from '@cornerstonejs/core'
import {
  // RenderingEngine,
  Enums,
  // imageLoader,
  metaData,
  getRenderingEngine,
  volumeLoader,
  // eventTarget,
  utilities as csUtils,
} from '@cornerstonejs/core'
import * as cornerstoneTools from '@cornerstonejs/tools'
import { utilities as cstUtils } from '@cornerstonejs/tools';
import cornerstoneDICOMImageLoader from '@cornerstonejs/dicom-image-loader';
import vtkColorMaps from '@kitware/vtk.js/Rendering/Core/ColorTransferFunction/ColorMaps'
import { createImageIdsAndCacheMetaData } from '@/views/trials/trials-panel/reading/dicoms/components/Fusion/js/createImageIdsAndCacheMetaData'
import setCtTransferFunctionForVolumeActor from '@/views/trials/trials-panel/reading/dicoms/components/Fusion/js/setCtTransferFunctionForVolumeActor'
import setPetTransferFunctionForVolumeActor from '@/views/trials/trials-panel/reading/dicoms/components/Fusion/js/setPetTransferFunctionForVolumeActor'
import { setPetColorMapTransferFunctionForVolumeActor } from '@/views/trials/trials-panel/reading/dicoms/components/Fusion/js/setPetColorMapTransferFunctionForVolumeActor'
const {
  ToolGroupManager,
  MIPJumpToClickTool,
  VolumeRotateTool,
  Enums: csToolsEnums,
} = cornerstoneTools
const { BlendModes, OrientationAxis } = Enums;
const { MouseBindings } = csToolsEnums
const { getColormap, getColormapNames } = csUtils.colormap;
const { ViewportColorbar } = cstUtils.voi.colorbar;
const { ColorbarRangeTextPosition } = cstUtils.voi.colorbar.Enums;
import { vec3, mat4 } from 'gl-matrix'
export default {
  name: 'ImageViewport',
  props: {
    renderingEngineId: {
      type: String,
      required: true
    },
    viewportId: {
      type: String,
      required: true
    },
    viewportIndex: {
      type: Number,
      required: true
    },
  },
  data() {
    return {
      element: '',
      series: {},
      ctSeries: {},
      petSeries: {},
      isFusion: false,
      isMip: false,
      taskInfo: null,
      sliderInfo: {
        oldB: null,
        oldM: null,
        isMove: false,
        height: 0
      },
      mousePosition: {
        index: [],
        value: null,
        modalityUnit: '',
        world: []
      },
      imageInfo: {
        zoom: null,
        size: null,
        location: null,
        sliceThickness: null,
        wwwc: null
      },
      digitPlaces: 2,
      orientationMarkers: [],
      originalMarkers: [],
      markers: { top: '', right: '', bottom: '', left: '' },
      playClipState: false,
      wwwcIdx: 2,
      presetName: '',
      volumeId: null,
      defaultWindowLevel: {},
      Colorbar: null,
      rotateAngle: 0,
      rotateBarLeft: 0,
      rotateBarInfo: {
        initX: null,
        initLeft: null,
        isMove: false
      },
      ptVolumeId: null,
    }
  },
  mounted() {
    this.taskInfo = JSON.parse(localStorage.getItem('taskInfo'))
    const digitPlaces = Number(localStorage.getItem('digitPlaces'))
    this.digitPlaces = digitPlaces === -1 ? this.digitPlaces : digitPlaces
    this.$nextTick(() => {
      this.initViewport()
    })
  },
  methods: {
    initViewport() {
      this.element = this.$refs['viewport-fusion']
      const resizeObserver = new ResizeObserver(() => {
        const renderingEngine = getRenderingEngine(this.renderingEngineId)
        if (renderingEngine) {
          renderingEngine.resize(true, false)
        }
      })
      this.element.oncontextmenu = (e) => e.preventDefault()
      // resizeObserver.observe(this.element)
      this.element.addEventListener("CORNERSTONE_VOLUME_NEW_IMAGE", this.stackNewImage)
      this.element.addEventListener('CORNERSTONE_VOI_MODIFIED', this.voiModified)

      this.element.addEventListener('CORNERSTONE_TOOLS_MOUSE_MOVE', this.cornerstoneToolsMouseMove)
      this.element.addEventListener(cornerstoneTools.Enums.Events.MOUSE_WHEEL, this.handletoolsMouseWheel)
      this.element.addEventListener('mouseleave', () => {
        this.mousePosition.index = []
        this.mousePosition.value = null
      })
      document.addEventListener('mouseup', () => {
        this.sliderMouseup()
        if (this.isMip) {
          this.rotateBarMouseup()
        }
      })
      document.addEventListener('mousemove', (e) => {
        this.sliderMousemove(e)
        if (this.isMip) {
          this.rotateBarMousemove(e)
        }
      })
      // console.log(cornerstoneTools)
      // element.addEventListener('CORNERSTONE_STACK_NEW_IMAGE', this.stackNewImage)
    },
    stackNewImage(e) {
      const { detail } = e
      this.series.SliceIndex = detail.imageIndex
      this.sliderInfo.height = detail.imageIndex * 100 / detail.numberOfSlices
      const renderingEngine = getRenderingEngine(this.renderingEngineId)
      const viewport = renderingEngine.getViewport(this.viewportId)
      const zoom = viewport.getZoom()
      this.imageInfo.zoom = zoom.toFixed(4)
      let imageId = viewport.getCurrentImageId()
      if (imageId) {
        const imagePlaneModule = metaData.get('imagePlaneModule', imageId)
        this.imageInfo.size = `${imagePlaneModule.columns}*${imagePlaneModule.rows}`
        this.imageInfo.location = imagePlaneModule.sliceLocation
        this.getOrientationMarker()
        // this.$emit('renderAnnotations', this.series)
        let properties = viewport.getProperties()
        if (this.isFusion) {
          properties = viewport.getProperties(this.ptVolumeId)
        }

        if (properties && properties.voiRange) {
          var { lower, upper } = properties.voiRange
          const windowWidth = upper - lower
          const windowCenter = (upper + lower) / 2
          this.defaultWindowLevel.windowWidth = windowWidth
          this.defaultWindowLevel.windowCenter = windowCenter
          this.imageInfo.wwwc = `${Math.round(windowWidth)}/${Math.round(windowCenter)}`
        }
        // const toolGroupId = `viewport-${this.viewportIndex}`
        // const toolGroup = ToolGroupManager.getToolGroup(toolGroupId)
        // toolGroup.setToolEnabled('ScaleOverlay')
      }

    },
    setFullScreen(index) {
      setTimeout(() => {
        const renderingEngine = getRenderingEngine(this.renderingEngineId)
        const viewport = renderingEngine.getViewport(
          this.viewportId
        )
        csUtils.jumpToSlice(viewport.element, { imageIndex: index })
        viewport.render()
      })
    },
    voiModified(e) {
      const renderingEngine = getRenderingEngine(this.renderingEngineId)
      const viewport = renderingEngine.getViewport(this.viewportId)
      let properties = viewport.getProperties()
      if (this.isFusion) {
        properties = viewport.getProperties(this.volumeId)
      }
      if (properties && properties.voiRange) {
        var { lower, upper } = properties.voiRange
        const { windowWidth, windowCenter } = csUtils.windowLevel.toWindowLevel(
          lower,
          upper
        )
        this.imageInfo.wwwc = `${Math.round(windowWidth)}/${Math.round(windowCenter)}`
        this.$emit('upperRangeChange', Math.round(windowWidth))
      }
    },
    getOrientationMarker() {
      const renderingEngine = getRenderingEngine(this.renderingEngineId)
      const viewport = renderingEngine.getViewport(this.viewportId)
      const { viewUp, viewPlaneNormal } = viewport.getCamera()

      const viewRight = vec3.create()
      vec3.cross(viewRight, viewUp, viewPlaneNormal)

      const columnCosines = [-viewUp[0], -viewUp[1], -viewUp[2]]
      const rowCosines = viewRight
      const rowString = cornerstoneTools.utilities.orientation.getOrientationStringLPS(rowCosines)
      const columnString = cornerstoneTools.utilities.orientation.getOrientationStringLPS(columnCosines)
      const oppositeRowString = cornerstoneTools.utilities.orientation.invertOrientationStringLPS(rowString)
      const oppositeColumnString = cornerstoneTools.utilities.orientation.invertOrientationStringLPS(columnString)
      this.markers.top = oppositeColumnString
      this.markers.right = rowString
      this.markers.bottom = columnString
      this.markers.left = oppositeRowString
      this.orientationMarkers = [oppositeColumnString, rowString, columnString, oppositeRowString]
      if (this.originalMarkers.length === 0) {
        this.originalMarkers = [...this.orientationMarkers]
      }
    },
    setMarkers() {
      const markers = [...this.orientationMarkers]
      for (const key in this.markers) {
        const v = markers.shift(0)
        this.markers[key] = v
      }
    },
    resetOrientationMarkers() {
      if (this.originalMarkers.length > 0) {
        this.orientationMarkers = [...this.originalMarkers]
        this.setMarkers()
      }
    },
    rotateOrientationMarkers(type) {
      if (this.orientationMarkers.length > 0) {
        if (type === 1) {
          this.resetOrientationMarkers()
          return
        }
        const markers = [...this.orientationMarkers]
        if (type === 2) {
          // 垂直翻转
          this.orientationMarkers[0] = markers[2]
          this.orientationMarkers[2] = markers[0]
        } else if (type === 3) {
          // 水平翻转
          this.orientationMarkers[1] = markers[3]
          this.orientationMarkers[3] = markers[1]
        } else if (type === 4) {
          // 左转90度
          this.orientationMarkers = markers.slice(1, 4).concat(markers[0])
        } else if (type === 5) {
          // 右转90度
          this.orientationMarkers = [markers[3]].concat(markers.slice(0, 3))
        }
        this.setMarkers()
      }
    },
    toggleClipPlay(isPlay, framesPerSecond) {
      this.playClipState = isPlay
      const renderingEngine = getRenderingEngine(this.renderingEngineId)
      const viewport = renderingEngine.getViewport(this.viewportId)

      if (isPlay) {
        cornerstoneTools.utilities.cine.playClip(viewport.element, { framesPerSecond, loop: false })
      } else {
        cornerstoneTools.utilities.cine.stopClip(viewport.element)
      }
    },
    scrollPage(type) {
      const renderingEngine = getRenderingEngine(this.renderingEngineId)
      const viewport = renderingEngine.getViewport(this.viewportId)
      const currentImageIdIndex = viewport.getCurrentImageIdIndex()
      const numImages = viewport.getImageIds().length
      let newImageIdIndex = null
      if (type === 0) {
        newImageIdIndex = 0
      } else if (type === -1) {
        newImageIdIndex = currentImageIdIndex === 0 ? currentImageIdIndex : currentImageIdIndex - 1
      } else if (type === 1) {
        newImageIdIndex = currentImageIdIndex === numImages - 1 ? currentImageIdIndex : currentImageIdIndex + 1
      } else if (type === 99999) {
        newImageIdIndex = numImages - 1
      }
      // viewport.setImageIdIndex(newImageIdIndex)
      csUtils.jumpToSlice(viewport.element, { imageIndex: newImageIdIndex })
      cornerstoneTools.utilities.cine.stopClip(viewport.element)
    },
    setZoom(ratio) {
      const renderingEngine = getRenderingEngine(this.renderingEngineId)
      const viewport = renderingEngine.getViewport(this.viewportId)

      const zoom = viewport.getZoom()
      if (ratio > 0) {
        viewport.setZoom(zoom * 1.05)
      } else {
        viewport.setZoom(zoom / 1.05)
      }
      viewport.render()
    },
    resize(forceFitToWindow) {
      console.log('resize: ', forceFitToWindow)
      const renderingEngine = getRenderingEngine(this.renderingEngineId)
      const viewport = renderingEngine.getViewport(this.viewportId)
      if (!forceFitToWindow) {
        viewport.setZoom(0.5)
        viewport.render()
      } else {
        viewport.setZoom(1)
        viewport.render()
      }
    },
    voiChange(v) {
      const renderingEngine = getRenderingEngine(this.renderingEngineId)
      const voiRange = { lower: 0, upper: v }
      const viewport = renderingEngine.getViewport(this.viewportId)
      if (!viewport) return
      let volumeId = this.isFusion ? this.ptVolumeId : this.volumeId
      const viewportsContainingVolumeUID = csUtils.getViewportsWithVolumeId(
        volumeId,
        viewport.renderingEngineId
      )

      viewport.setProperties({ voiRange }, volumeId)
      viewportsContainingVolumeUID.forEach((vp) => {
        vp.render()
        // this.$refs[vp.id].voiModified()
        this.voiModified()
      })
    },
    renderColorBar(presetName) {
      var colorMap = null
      this.Colorbar = null
      if (presetName === 'hsv') {
        colorMap = vtkColorMaps.getPresetByName(presetName)
      } else {
        colorMap = getColormap(presetName)
      }
      if (!colorMap) return false
      // let colormaps = getColormapNames().map(name => getColormap(name))
      // console.log(colormaps)
      // const canvas = document.getElementById('colorBar_Canvas')
      // this.Colorbar = new ViewportColorbar({
      //   id: this.volumeId,
      //   element: this.element,
      //   container: canvas,
      //   colormaps,
      //   activeColormapName: presetName,
      //   ticks: {
      //     position: ColorbarRangeTextPosition.Left,
      //     style: {
      //       font: '12px Arial',
      //       color: '#fff',
      //       maxNumTicks: 8,
      //       tickSize: 5,
      //       tickWidth: 1,
      //       labelMargin: 3,
      //     },
      //   },
      // });
      const rgbPoints = colorMap.RGBPoints
      const canvas = document.getElementById(`colorBar_Canvas_${this.viewportId}`)
      if (!canvas) return false
      const ctx = canvas.getContext('2d')
      const canvasWidth = 160
      const canvasHeight = 5
      const rectWidth = 160
      const rectHeight = canvasHeight
      canvas.width = canvasWidth
      canvas.height = canvasHeight
      const gradient = ctx.createLinearGradient(0, 0, rectWidth, 0)
      for (let i = 0; i < rgbPoints.length; i += 4) {
        let position = 0
        if (rgbPoints[0] === -1) {
          position = (rgbPoints[i] + 1) / 2
        } else {
          position = rgbPoints[i]
        }
        const color = `rgb(${parseInt(rgbPoints[i + 1] * 255)}, ${parseInt(rgbPoints[i + 2] * 255)}, ${parseInt(rgbPoints[i + 3] * 255)})`
        gradient.addColorStop(position, color)
      }
      ctx.fillStyle = gradient
      ctx.fillRect(0, 0, rectWidth, rectHeight)
    },
    setPreset(presetName) {
      this.presetName = presetName
    },
    setColorMap(presetName) {
      if (this.Colorbar) {
        this.Colorbar.activeColormapName = presetName;
      }
      const renderingEngine = getRenderingEngine(this.renderingEngineId)
      const viewport = renderingEngine.getViewport(this.viewportId)
      viewport.setProperties({ colormap: { name: presetName } }, this.volumeId)
      viewport.render()
    },
    async prefetchMetadataInformation(imageIdsToPrefetch) {
      let taskPromises = []
      for (let i = 0; i < imageIdsToPrefetch.length; i++) {
        taskPromises.push(cornerstoneDICOMImageLoader.wadouri.loadImage(imageIdsToPrefetch[i]).promise)
        if (taskPromises.length >= 6 || i === imageIdsToPrefetch.length - 1) {
          await Promise.all(taskPromises)
          taskPromises = []
        }
      }
    },
    async createImageIdsAndCacheMetaData(obj) {
      await createImageIdsAndCacheMetaData({
        modality: obj.Modality,
        imageIds: obj.ImageIds
      })
    },
    async setSeriesInfo(obj, option = {}) {
      try {
        let { data, volumeId } = obj
        if (this.series && data.Id === this.series.Id && data.Description === this.series.Description) {
          data.SliceIndex = this.series.SliceIndex
        }
        this.ptVolumeId = null
        this.series = {}
        let { isFusion, isMip, colorMap } = option
        this.isFusion = isFusion;
        this.isMip = isMip;
        const renderingEngine = getRenderingEngine(this.renderingEngineId)
        const viewport = renderingEngine.getViewport(this.viewportId)
        if (this.isFusion) {
          this.$nextTick(() => {
            this.renderColorBar(this.presetName)
          })
          let { ct, data, ctVolumeId, ptVolumeId, fusionVolumeId } = obj
          this.series = { ...data }
          this.ctSeries = { ...ct }
          this.petSeries = { ...data }
          // const maxCount = Math.max(this.ctSeries.ImageIds.length, this.petSeries.ImageIds.length)
          // this.$set(this.ctSeries, 'imageMaxLength', maxCount)
          // this.$set(this.petSeries, 'imageMaxLength', maxCount)
          // await this.createImageIdsAndCacheMetaData(this.ctSeries)
          // await this.createImageIdsAndCacheMetaData(this.petSeries)
          this.volumeId = ptVolumeId
          this.ptVolumeId = fusionVolumeId
          await viewport
            .setVolumes([
              {
                volumeId: this.ptVolumeId, callback: (r) => {
                  setPetColorMapTransferFunctionForVolumeActor(r)
                  console.log("融合pet渲染成功");
                }
              },
              {
                volumeId: ctVolumeId, callback: (r) => {
                  setCtTransferFunctionForVolumeActor(r)
                  console.log("融合ct渲染成功")
                }
              },
              {
                volumeId: this.volumeId, callback: (r) => {
                  setPetColorMapTransferFunctionForVolumeActor(r)
                  console.log("融合pet渲染成功");
                }
              },
            ]).then(res => {
              if (colorMap) {
                this.setColorMap(this.presetName)
              }
            })
        } else {
          this.series = { ...data }
          this.volumeId = volumeId
          if (this.isMip) {
            let { volume } = obj
            const ptVolumeDimensions = volume.dimensions;
            const slabThickness = Math.sqrt(
              ptVolumeDimensions[0] * ptVolumeDimensions[0] +
              ptVolumeDimensions[1] * ptVolumeDimensions[1] +
              ptVolumeDimensions[2] * ptVolumeDimensions[2]
            );
            viewport
              .setVolumes([{
                volumeId: this.volumeId,
                callback: (r) => {
                  setPetColorMapTransferFunctionForVolumeActor(r)
                  console.log("mip渲染成功")
                },
                slabThickness,
                blendMode: BlendModes.MAXIMUM_INTENSITY_BLEND,
                defaultOptions: {
                  orientation: OrientationAxis.CORONAL
                }
              }]).then(res => {
                if (colorMap) {
                  this.setColorMap(this.presetName)
                }
              })
          } else {
            viewport
              .setVolumes([{
                volumeId: this.volumeId, callback: (r) => {
                  if (this.series.Modality === 'PT') {
                    setPetColorMapTransferFunctionForVolumeActor(r, true)
                  } else {
                    setCtTransferFunctionForVolumeActor(r)
                  }
                  console.log("渲染成功")
                }
              }]).then(res => {
                if (colorMap) {
                  this.setColorMap(this.presetName)
                }
              })
          }

        }
        viewport.render()
      } catch (e) {
        console.log(e)
      }

    },
    cornerstoneToolsMouseMove(e) {
      const { currentPoints } = e.detail
      const worldPoint = currentPoints.world
      const renderingEngine = getRenderingEngine(this.renderingEngineId)
      const viewport = renderingEngine.getViewport(this.viewportId)
      const imageData = viewport.getImageData()
      if (!imageData) return
      const index = imageData.imageData.worldToIndex(worldPoint)
      index[0] = Math.floor(index[0])
      index[1] = Math.floor(index[1])
      index[2] = Math.floor(index[2])
      this.mousePosition.index = index
    },
    toggleTask(evt, visitTaskNum, i) {
      this.$emit('activeViewport', this.viewportIndex)
      const num = visitTaskNum + i
      if (num >= 0 && num <= this.taskInfo.VisitNum) {
        this.$emit('toggleTaskByViewport', { series: this.series, visitTaskNum: num })
      }

      evt.stopImmediatePropagation()
      evt.stopPropagation()
      evt.preventDefault()
    },
    viewCD(taskId) {
      this.$emit('previewCD', taskId)
    },
    setWwwcIdx(idx) {
      this.wwwcIdx = idx
    },
    clickSlider(e) {
      const height = e.offsetY * 100 / this.$refs['sliderBox'].clientHeight
      this.sliderInfo.height = height
      let sliceIdx = Math.trunc(this.series.Stack.length * height / 100)
      sliceIdx = sliceIdx >= this.series.Stack.length ? this.series.Stack.length - 1 : sliceIdx < 0 ? 0 : sliceIdx
      const renderingEngine = getRenderingEngine(this.renderingEngineId)
      const viewport = renderingEngine.getViewport(
        this.viewportId
      )
      // viewport.setImageIdIndex(sliceIdx)
      csUtils.jumpToSlice(viewport.element, { imageIndex: sliceIdx })
      viewport.render()
    },
    sliderMouseup(e) {
      this.sliderInfo.isMove = false
    },
    sliderMousedown(e) {
      const boxHeight = this.$refs['sliderBox'].clientHeight
      this.sliderInfo.oldB = parseInt(e.srcElement.style.top) * boxHeight / 100
      this.sliderInfo.oldM = e.clientY
      this.sliderInfo.isMove = true
      e.stopImmediatePropagation()
      e.stopPropagation()
      e.preventDefault()
    },
    sliderMousemove(e) {
      if (!this.sliderInfo.isMove) return
      const delta = this.sliderInfo.oldB - (this.sliderInfo.oldM - e.clientY)
      const boxHeight = this.$refs['sliderBox'].clientHeight
      if (delta < 0) return
      if (delta > boxHeight) return
      const height = delta * 100 / boxHeight
      let sliceIdx = Math.trunc(this.series.Stack.length * height / 100)
      sliceIdx = sliceIdx >= this.series.Stack.length ? this.series.Stack.length - 1 : sliceIdx < 0 ? 0 : sliceIdx
      this.sliderInfo.height = height
      const renderingEngine = getRenderingEngine(this.renderingEngineId)
      const viewport = renderingEngine.getViewport(
        this.viewportId
      )
      // viewport.setImageIdIndex(sliceIdx)
      csUtils.jumpToSlice(viewport.element, { imageIndex: sliceIdx })
      viewport.render()
    },
    sliderMouseleave(e) {
      if (!this.sliderInfo.isMove) return
      this.sliderInfo.isMove = false
    },
    handletoolsMouseWheel(e) {
      const { viewportId, wheel } = e.detail
      if (this.isMip) {
        const container = document.getElementById('rotateBar')
        const slider = document.getElementById('rotateSlider')
        const containerWidth = container.offsetWidth
        const sliderWidth = slider.offsetWidth
        const maxX = containerWidth - sliderWidth
        const { direction } = wheel

        var x = Math.trunc(30 * ((containerWidth - sliderWidth) / 360))
        if (direction > 0 && (this.rotateBarLeft + x) > maxX) {
          this.rotateBarLeft = x - (containerWidth - sliderWidth - this.rotateBarLeft)
        } else if (direction < 0 && (this.rotateBarLeft < x)) {
          this.rotateBarLeft = containerWidth - (x - this.rotateBarLeft + sliderWidth)
        } else {
          this.rotateBarLeft = x * direction + this.rotateBarLeft
        }
      }
    },
    rotateBarMouseup(e) {
      this.rotateBarInfo.isMove = false
    },
    rotateBarMousemove(e) {
      // 滚动旋转
      if (!this.rotateBarInfo.isMove) return
      const container = document.getElementById('rotateBar')
      const slider = document.getElementById('rotateSlider')
      const containerWidth = container.offsetWidth
      const sliderWidth = slider.offsetWidth
      let x = Math.trunc(e.clientX - this.rotateBarInfo.initX + this.rotateBarInfo.initLeft)
      if (x < 0) x = 0
      if (x > containerWidth - sliderWidth) x = containerWidth - sliderWidth
      const deltaX = x - this.rotateBarLeft
      const angle = Math.sin((deltaX * (360 / (containerWidth - sliderWidth))) * Math.PI / 180)
      this.rotate(angle)
      this.rotateBarLeft = x
    },
    rotateBarMousedown(e) {
      this.rotateBarInfo.initLeft = e.srcElement.offsetLeft
      this.rotateBarInfo.initX = e.clientX
      this.rotateBarInfo.isMove = true
      e.stopImmediatePropagation()
      e.stopPropagation()
      e.preventDefault()
    },
    rotate(angle) {
      let renderingEngine = getRenderingEngine(this.renderingEngineId)
      let viewport = renderingEngine.getViewport(this.viewportId)
      const camera = viewport.getCamera()
      const { viewUp, position, focalPoint } = camera
      const [cx, cy, cz] = focalPoint
      const [ax, ay, az] = [0, 0, 1]
      const newPosition = [0, 0, 0]
      const newFocalPoint = [0, 0, 0]
      const newViewUp = [0, 0, 0]

      const transform = mat4.identity(new Float32Array(16))
      mat4.translate(transform, transform, [cx, cy, cz])
      mat4.rotate(transform, transform, angle, [ax, ay, az])
      mat4.translate(transform, transform, [-cx, -cy, -cz])
      vec3.transformMat4(newPosition, position, transform)
      vec3.transformMat4(newFocalPoint, focalPoint, transform)

      mat4.identity(transform)
      mat4.rotate(transform, transform, angle, [ax, ay, az])
      vec3.transformMat4(newViewUp, viewUp, transform)

      viewport.setCamera({
        position: newPosition,
        viewUp: newViewUp,
        focalPoint: newFocalPoint
      })

      viewport.render()
    },
    clickRotate(e) {
      // console.log('clickRotate')
      const container = document.getElementById('rotateBar')
      const containerWidth = container.offsetWidth
      const slider = document.getElementById('rotateSlider')
      const sliderWidth = slider.offsetWidth
      const x = Math.trunc(e.offsetX)
      const deltaX = x - this.rotateBarLeft
      const angle = Math.sin((deltaX * (360 / (containerWidth - sliderWidth))) * Math.PI / 180)
      this.rotate(angle)
      this.rotateBarLeft = x
    },
    preventDefault(e) {
      e.stopImmediatePropagation()
      e.stopPropagation()
      e.preventDefault()
    }
  }
}
</script>
<style lang="scss" scoped>
.viewport-wrapper {
  width: 100%;
  height: 100%;
  position: relative;

  .left-top-text {
    position: absolute;
    left: 5px;
    top: 5px;
    // color: #ddd; 
    z-index: 1;
    font-size: 12px;

    .cd-info {
      // color: #ddd; 
      font-size: 18px;
    }

    .subject-info {
      color: #f44336;
      padding: 5px 0px;
      margin: 0;
    }
  }

  .top-center-tool {
    position: absolute;
    left: 50%;
    top: 5px;
    transform: translateX(-50%);
    z-index: 1;

    .toggle-visit-container {
      display: flex;
    }

    .arrw_icon {
      width: 20px;
      height: 20px;
      background-color: #3f3f3f;
      text-align: center;
      line-height: 20px;
      border-radius: 10%;
    }

    .arrow_text {
      height: 20px;
      line-height: 20px;
      background-color: #00000057;
      color: #fff;
      padding: 0 10px;
      font-size: 14px;
    }
  }

  .right-top-text {
    position: absolute;
    right: 5px;
    top: 5px;
    // color: #ddd;
    z-index: 1;
    font-size: 12px;
  }

  .left-bottom-text {
    position: absolute;
    left: 5px;
    bottom: 5px;
    // color: #ddd;
    z-index: 1;
    font-size: 12px;
  }

  .right-bottom-text {
    position: absolute;
    right: 5px;
    bottom: 5px;
    // color: #ddd;
    z-index: 1;
    font-size: 12px;
  }

  .right-slider-box {
    position: absolute;
    right: 1px;
    height: calc(100% - 140px);
    transform: translateY(-50%);
    top: calc(50% - 30px);
    width: 10px;
    background: #333;
    z-index: 1;
    cursor: pointer;
  }

  .right-slider-box:after {
    content: '';
    position: absolute;
    bottom: -20px;
    left: 0;
    height: 20px;
    width: 100%;
    background: #333;
  }

  .slider {
    height: 20px;
    width: 100%;
    position: absolute;
    top: 0;
    z-index: 10;
    background: #9e9e9e;
    cursor: move
  }

  .orientation-top {
    position: absolute;
    left: 50%;
    top: 30px;
    color: #f44336;
    transform: translateX(-50%);
    z-index: 1;
  }

  .orientation-bottom {
    position: absolute;
    left: 50%;
    bottom: 15px;
    color: #f44336;
    transform: translateX(-50%);
    z-index: 1;
  }

  .orientation-left {
    position: absolute;
    top: 50%;
    left: 15px;
    color: #f44336;
    transform: translateY(-50%);
    z-index: 1;
  }

  .orientation-right {
    position: absolute;
    top: 50%;
    right: 15px;
    color: #f44336;
    transform: translateY(-50%);
    z-index: 1;
  }
}

.color_bar {
  position: absolute;
  transform: rotate(-90deg);
  transform-origin: right;
  left: -150px;
  top: 30%;
  z-index: 1;
}

.rotate_slider_box {
  position: absolute;
  width: 380px;
  height: 10px;
  bottom: 5px;
  left: 50%;
  transform: translateX(-50%);
  background: #333;
  z-index: 10;
  cursor: pointer;

  .box {
    z-index: 10;
    background: #9e9e9e;
    height: 100%;
    width: 20px;
    position: absolute;
    top: 0;
    cursor: move
  }
}
</style>