<template>
  <div class="camera-modal">
    <div class="camera-modal-content">
      <div class="take-photos">
        <video class="take-photos-videoStyle"
               ref="video"
               v-show="photoFlag"></video>
        <canvas ref="canvas"
                class="canvas-style"
                :width="photoWidth"
                :height="photoHeight"
                :style="{'width':photoWidth+'px','height':photoHeight+'px'}"
                v-show="!photoFlag && curCameraType !== 'fu'"></canvas>
        <canvas ref="canvasFu"
                class="canvas-style"
                :width="photoWidth"
                :height="photoHeight"
                :style="{'width':photoWidth+'px','height':photoHeight+'px'}"
                v-show="!photoFlag && curCameraType === 'fu'"></canvas>
        <!-- <img id="view1" src="http://127.0.0.1:38088/video=stream&camidx=0" alt="主摄像头" style="width: 550px; height: 338px" v-if="curCameraType === 'zhu'">
        <img id="view1" src="http://127.0.0.1:38088/video=stream&camidx=1" alt="副摄像头" style="width: 550px; height: 338px" v-if="curCameraType === 'fu'"> -->
        <div class="take-photos-btnGroup">
          文件名：
          <Input size="small"
                 style="width:200px;margin-right:20px;"
                 v-model="curFileName" />
          <Button type="primary"
                  class="btn-item"
                  @click="setImage">拍照</Button>
          <!-- <Button class="btn-item"
                  v-if="curCameraType ==='zhu'"
                  @click="rotate(90)">左旋转90°</Button>
          <Button class="btn-item"
                  v-if="curCameraType ==='zhu'"
                  @click="rotate(270)">右旋转90</Button> -->
        </div>
        <div class="take-photos-set">
          <span class="take-photos-set-title">摄像头</span>
          <Select v-model="curCamera"
                  style="width:200px"
                  transfer
                  @on-change="handleBtnClick('camera')">
            <Option v-for="item in cameraList"
                    :value="item.value"
                    :key="item.value">{{ item.label }}</Option>
          </Select>
          <span class="take-photos-set-title">分辨率</span>
          <Select v-model="curFBL"
                  style="width:200px"
                  transfer
                  @on-change="handleSelectClick('FBL')">
            <Option v-for="item in FBLList"
                    :value="item.value"
                    :key="item.value">{{ item.label }}</Option>
          </Select>
        </div>
      </div>
      <div class="camera-modal-photos"
           v-if="pictureSrcList.length > 0">
        <div class="finished-photos">
          <div class="photo-item"
               v-for="(item,index) in pictureSrcList"
               :key='index'>
            <div class="photo-item-img"
                 @click="handleImgClick('preview',index,item)">
              <img :ref="`imgShow${index}`"
                   style="width:100%; height:200px;display:block"
                   :src='item.src' />
            </div>

            <div class="photo-item-icon">
              <Input style="width:200px;float:left;"
                     size="small"
                     v-model="item.fileName"
                     @on-blur="handleFileNameChange(item)" />
              <Tooltip content="上移"
                       placement="top"
                       transfer>
                <Icon type="md-arrow-up"
                      @click="handleImgClick('up',index,item)"
                      size="18" />
              </Tooltip>
              <Tooltip content="下移"
                       placement="top"
                       transfer>
                <Icon type="md-arrow-down"
                      @click="handleImgClick('down',index,item)"
                      size="18" />
              </Tooltip>
              <Tooltip content="删除"
                       placement="top"
                       transfer>
                <Icon type="ios-trash-outline"
                      @click="handleImgClick('del',index,item)"
                      size="18" />
              </Tooltip>
            </div>
          </div>
        </div>
        <div class="save-photos">
          <Button type="primary"
                  class="save-photos-btn"
                  @click="handleBtnClick('save')">确定</Button>
          <span v-if="this.pictureSrcList.length>0"
                class="footer-spanStyle">共{{this.pictureSrcList.length}}张
          </span>
          <!--
            <div class="save-photos-checked">
              <Checkbox v-model="autoCompress">保存前压缩</Checkbox>
            </div>
          -->
        </div>
      </div>
      <div class="no-take-photos"
           v-if="pictureSrcList.length===0">
        <span class="no-take-photos-tips">暂无照片</span>
      </div>
      <div ref="hiddenDiv"
           class="preview-photo"
           @click="handleImgClick('preview')">
        <div class="preview-photo-pre"
             @click.stop="handleBtnClick('pre')">
          <Icon class="preview-photo-pre-icon"
                type="ios-arrow-back"
                size="48" />
        </div>
        <div class="preview-photo-body">
          <img ref="previewPhoto"
               class="preview-photo-body-imgStyle" />
        </div>
        <div class="preview-photo-back"
             @click.stop="handleBtnClick('back')">
          <Icon class="preview-photo-back-icon"
                type="ios-arrow-forward"
                size="48" />
        </div>
        <img ref="oldImg"
             v-show='false' />
      </div>
    </div>
  </div>
</template>

<script>
import cameraModal from './vuc-camera.js'
// import photoCompress from '../../photoCompress.js'
import XEUtils from 'xe-utils'
import axios from 'axios'
export default {
  name: 'VucCamera',
  data () {
    return {
      thisCancas: null,
      thisContext: null,
      thisVideo: null,
      curStream: null,
      curCamera: '',
      cameraList: [],
      curFBL: '1920*1080',
      photoFlag: true,
      FBLList: [
        {
          value: '1920*1080',
          label: '1920*1080'
        },
        {
          value: '3840*2160',
          label: '3840*2160'
        },
        {
          value: '3264*2448',
          label: '3264*2448'
        }
      ],
      photoWidth: 0,
      photoHeight: 0,
      pictureSrcList: [],
      previewPhoto: {},
      showPreview: false,
      autoCompress: false, // 自动压缩 默认为true
      targetWidth: 1280,
      targetHeight: 720,
      curPreviewIndex: 0,
      curFileName: XEUtils.toDateString(new Date(), 'yyyyMMddHHssmm'),
      curCameraType: '',
      rotateFlag: true // false时会旋转90度
    }
  },
  props: {
    // autoZipImg: {
    //   type: Boolean,
    //   default: false
    // }
  },
  computed: {
    currentInfo () {
      return {
        curCamera: this.curCamera,
        curFBL: this.curFBL
      }
    }
  },
  watch: {
    currentInfo: {
      handler (val) {
        const { curCamera, curFBL } = val
        if (curCamera && curFBL) {
          localStorage.setItem('fjDevice', JSON.stringify(val))
        }
      },
      deep: true,
      immediate: true
    }
  },
  mounted () {
    this.setInitPage()
    // this.openZhu()
  },
  methods: {
    setInitPage () {
      navigator.mediaDevices.enumerateDevices().then((deviceInfos) => {
        this.getDevices(deviceInfos)
      }).then(() => {
        if (localStorage.getItem('MERGEVERSION') === 'ZZGAJ') {
          this.rotateFlag = false
        }
        this.getCompetence()
      })
    },
    // 获取电脑的摄像头设备
    getDevices (deviceInfos) {
      for (let i = 0; i < deviceInfos.length; ++i) {
        let deviceInfo = deviceInfos[i]
        let item = {}
        item.value = deviceInfo.deviceId
        if (deviceInfo.kind === 'videoinput') {
          item.label = deviceInfo.label || `camera ${i}`
          // 取到高拍仪两个摄像头
          item.type = item.label.slice(item.label.length - 10, item.label.length - 6)
          this.cameraList.push(item)
        }
      }
      const info = localStorage.getItem('fjDevice')
      let label
      if (info) {
        const { curCamera, curFBL } = JSON.parse(info)
        const val = this.cameraList.find(item => item.value === curCamera)

        this.curCamera = val ? curCamera : this.cameraList[0].value
        this.curFBL = curFBL
        label = this.curFBL.split('*')
      } else {
        this.curCamera = this.cameraList[0].value
        this.curFBL = this.FBLList[0].value
        label = this.FBLList[0].label.split('*')
      }
      this.photoWidth = Number(label[0])
      this.photoHeight = Number(label[1])
    },
    //  调用摄像头
    getCompetence () {
      this.curCameraType = ''
      let s = 0
      let buffer = ''
      this.cameraList.forEach((item, index) => {
        if (this.curCamera === item.value) {
          buffer = item.type
          this.cameraList.forEach((item, index) => {
            if (buffer === item.type) {
              s += 1
            }
          })
          if (s < 2) {
            this.curCameraType = ''
          } else {
            if (item.label.indexOf('CAM2') === -1) {
              this.curCameraType = 'zhu'
            } else {
              this.curCameraType = 'fu'
            }
          }
        }
      })
      this.thisCancas = this.curCameraType !== 'fu' ? this.$refs.canvas : this.$refs.canvasFu
      this.thisContext = this.thisCancas.getContext('2d')
      if (this.curCameraType === 'zhu' && !this.rotateFlag) {
        this.thisContext.scale(0.56, 0.56)
        this.thisContext.translate((this.photoWidth + this.photoHeight)/1.3, 0)
        this.thisContext.rotate(90*Math.PI/180)
        this.rotateFlag = true
      }
      this.thisVideo = this.$refs.video
      if (this.curStream != null) {
        try {
          this.curStream.stop()
        } catch (e) {
          this.curStream.getVideoTracks()[0].stop()
        }
      }
      // 旧版本浏览器可能根本不支持mediaDevices，首先设置一个空对象
      if (navigator.mediaDevices === undefined) {
        navigator.mediaDevices = {}
      }
      // 一些浏览器实现了部分mediaDevices，我们不能只分配一个对象
      // 使用getUserMedia，因为它会覆盖现有的属性。
      // 这里，如果缺少getUserMedia属性，就添加它。
      if (navigator.mediaDevices.getUserMedia === undefined) {
        navigator.mediaDevices.getUserMedia = (constraints) => {
          // 首先获取现存的getUserMedia(如果存在)
          let getUserMedia = navigator.webkitGetUserMedia || navigator.mozGetUserMedia || navigator.getUserMedia
          // 有些浏览器不支持，会返回错误信息
          // 保持接口一致
          if (!getUserMedia) {
            return Promise.reject(new Error('getUserMedia is not implemented in this browser'))
          }
          // 否则，使用Promise将调用包装到旧的navigator.getUserMedia
          return new Promise((resolve, reject) => {
            getUserMedia.call(navigator, constraints, resolve, reject)
          })
        }
      }
      let constraints = {
        audio: false,
        video: {
          optional: [
            { sourceId: this.curCamera },
            { minWidth: this.photoWidth },
            { maxWidth: this.photoWidth },
            { minHeight: this.photoHeight },
            { maxHeight: this.photoHeight }
          ]
        }
      }
      navigator.mediaDevices.getUserMedia(constraints).then((stream) => {
        // 旧的浏览器可能没有srcObject
        if ('srcObject' in this.thisVideo) {
          this.thisVideo.srcObject = stream
          this.curStream = stream
        } else {
          // 避免在新的浏览器中使用它，因为它正在被弃用。
          this.thisVideo.src = window.URL.createObjectURL(stream)
          this.curStream = stream
        }
        this.thisVideo.onloadedmetadata = (e) => {
          this.thisVideo.play()
        }
      }).catch(err => {
      })
    },
    // @function  绘制图片
    setImage () {
      if (this.pictureSrcList.length >= 50) {
        this.$fn.error({ title: '错误提示', desc: '数量过多,请先上传后再继续拍照' })
      }
      // let nowTime = new Date().Format('yyyyMMdd')
      // if (nowTime > '20220930' && localStorage.getItem('MERGEVERSION') === 'ZZGAJ') {
      //   return this.$fn.error({ title: '错误提示', desc: '请先购买正版授权' })
      // }
      // if (nowTime > '20221130' && localStorage.getItem('MERGEVERSION') !== 'ZZGAJ') {
      //   return this.$fn.error({ title: '错误提示', desc: '请先购买正版授权' })
      // }
      this.photoFlag = false
      // if (this.curCameraType) {
      //   this.paizhao()
      //   this.photoFlag = true
      // } else {
      // 点击，canvas画图
      this.thisContext.drawImage(this.thisVideo, 0, 0, this.photoWidth, this.photoHeight)
      if (!this.curFileName) {
        this.curFileName = XEUtils.toDateString(new Date(), 'yyyyMMddHHssmm')
      }
      // 获取照片大小
      this.thisCancas.toBlob((res) => {
      // let imgfile = new File([res], `图片${this.pictureSrcList.length + 1}.jpg`, {
      //   type: 'image/jpg'
      // })
        let imgfile = new File([res], `${this.curFileName}.jpg`, {
          type: 'image/jpg'
        })
        // if (this.autoZipImg && localStorage.getItem('MERGEVERSION') !== 'ZZGAJ') {
        //   const compressFile = await photoCompress(imgfile, {
        //     mimeType: imgfile.type,
        //     width: 1500,
        //     height: 1500,
        //     quality: 0.7
        //   })
        //   imgfile = new File([compressFile], imgfile.name, {
        //     type: imgfile.type
        //   })
        // }
        let imgSrc = window.URL.createObjectURL(res)
        this.pictureSrcList.push({ file: imgfile, src: imgSrc, fileName: this.curFileName })
        this.$emit('complete', imgfile)
        this.curFileName = XEUtils.toDateString(new Date(), 'yyyyMMddHHssmm')
      }, 'image/jpg')
      this.photoFlag = true
      // }
    },
    // 切换分辨率
    handleSelectClick () {
      let array = this.curFBL.split('*')
      this.targetWidth = Number(array[0]) / 1.5
      this.targetHeight = Number(array[1]) / 1.5
      this.handleBtnClick('FBL')
    },
    // 打开高拍仪摄像头
    openZhu() {
      axios.request({
        url: 'http://127.0.0.1:38088/video=stream&camidx=0?1',
        headers: { 
          'Accept': 'image/avif,image/webp,image/apng,image/svg+xml,image/*,*/*;q=0.8',
          'Sec-Fetch-Dest': 'image',
          'Sec-Fetch-Mode': 'no-cors'
        },
        method: 'get', 
        waitfor: true
      })
    },
    // 高拍仪旋转
    rotate(angle) {
      let req = new XMLHttpRequest()
      let params = { 'camidx': this.curCameraType === 'zhu' ? '0' : '1', 'rotate': String(angle) }
      req.open('POST', `http://127.0.0.1:38088/video=rotate`, true)
      req.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded')
      req.onload = function () {
        const res = JSON.parse(req.response)
        if (res.status === 200) {} else {}
      }
      req.send(JSON.stringify(params))
      // req.send()
    },
    // 拍照
    paizhao() {
      let data = {
        'filepath': 'base64',
        'rotate': '0',
        'cutpage': '0',
        'camidx': this.curCameraType === 'zhu' ? '0' : '1',
        'ColorMode': '0',
        'quality': '3'
      }
      let req = new XMLHttpRequest()
      req.open('POST', `http://127.0.0.1:38088/video=grabimage`, true)
      req.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded')
      const _this = this
      req.onload = function () {
        const res = JSON.parse(req.response)
        let resp = _this.base64ToBlob('data:image/jpg;base64,' + res.photoBase64)
        let imgfile = new File([resp], `图片${_this.pictureSrcList.length + 1}.jpg`, {
          type: 'image/jpg'
        })
        let imgSrc = window.URL.createObjectURL(resp)
        _this.pictureSrcList.push({ file: imgfile, src: imgSrc })
        _this.$emit('complete', imgfile)
      }
      req.send(JSON.stringify(data))
      // req.send()
    },
    base64ToBlob (baseUrl) {
      let arr = baseUrl.split(',')
      let mime = arr[0].match(/:(.*?);/)[1]
      let bstr = atob(arr[1])
      let n = bstr.length
      let u8arr = new Uint8Array(n)
      while (n--) {
        u8arr[n] = bstr.charCodeAt(n)
      }
      return new Blob([u8arr], { type: mime })
    }
  },
  destroyed () {
    try {
      this.curStream.stop() // 关闭摄像头（如果此方法不存在，则调用下面的方法）
    } catch (e) {
      this.curStream.getVideoTracks()[0].stop()
    }
  },
  mixins: [cameraModal]
}
</script>
<style lang="less">
@import './vuc-camera.less';
</style>
