<template>
  <div class="dcm-tag">
    <el-input
      v-model="search"
      size="mini"
      :placeholder="$t('trials:dicom-tag:keywords')"
      style="width:200px"
    />

    <el-table
      :data="filterList(list)"
      row-key="id"
      default-expand-all
      :tree-props="{children: 'child', hasChildren: 'hasChildren'}"
      :default-sort="{prop: 'tagCode', order: 'ascending'}"
      height="500"
    >
      <el-table-column
        prop="tagCode"
        label="Tag"
        min-width="120"
        sortable
      />
      <el-table-column
        prop="tagName"
        label="Description"
        min-width="150"
        show-overflow-tooltip
        sortable
      />
      <el-table-column
        prop="vr"
        label="VR"
        min-width="50"
        show-overflow-tooltip
        sortable
      />
      <el-table-column
        prop="tagLength"
        label="Length"
        min-width="80"
        show-overflow-tooltip
        sortable
      />
      <el-table-column
        prop="value"
        label="Value"
        min-width="200"
        show-overflow-tooltip
        sortable
      />
    </el-table>
  </div>
</template>
<script>
import TAG_DICT from './dataDictionary'
import * as cornerstone from 'cornerstone-core'
import dicomParser from 'dicom-parser'
export default {
  name: 'DicomTags',
  props: {
    imageId: {
      type: String,
      required: true
    }
  },
  data() {
    return {
      list: [],
      idx: 0,
      search: ''
    }
  },
  async mounted() {
    const image = await cornerstone.loadAndCacheImage(this.imageId)
    var dataSet = dicomParser.parseDicom(image.data.byteArray)
    var output = []
    this.dumpDataSet(dataSet, output)
    this.list = output
  },
  methods: {
    filterList(list) {
      if (list.length === 0) return []
      if (!this.search) {
        return list
      } else {
        const search = isNaN(parseFloat(this.search)) ? this.search.toLowerCase() : String(this.search)
        const arr = list.filter(data => {
          if (data.tagCode && data.tagCode.toLowerCase().includes(search)) {
            return data
          } else if (data.tagName && data.tagName.toLowerCase().includes(search)) {
            return data
          } else if (data.value) {
            let v = ''
            if (!isNaN(parseFloat(data.value))) {
              v = String(data.value)
            } else {
              v = data.value.toLowerCase()
            }
            if (v.includes(search)) {
              return data
            }
          }
        })
        return arr
      }
    },
    dumpDataSet(dataSet, output) {
      try {
        for (const propertyName in dataSet.elements) {
          const elementObject = {} 
          const element = dataSet.elements[propertyName]
          const tag = this.getTag(element.tag)
          elementObject.id = `${this.idx++}${new Date().getTime()}`
          if (!tag) {
            const group = element.tag.substring(1, 5)
            const el = element.tag.substring(5, 9)
            elementObject.tagCode = ('(' + group + ',' + el + ')').toUpperCase()
          } else {
            elementObject.tagCode = tag ? tag.tag : ''
            elementObject.tagName = tag ? tag.name : ''
          }

          elementObject.tagLength = element.length
          elementObject.value = ''
          elementObject.child = []

          if (element.items) {
            element.items.forEach(item => {
              const childOutput = []
              this.dumpDataSet(item.dataSet, childOutput)
              elementObject.child.push(...childOutput)
            })
          } else if (element.fragments) {
            // 多帧处理
          } else {
            var vr
            if (element.vr !== undefined) {
              vr = element.vr
            } else {
              if (tag !== undefined) {
                vr = tag.vr
              }
            }
            elementObject.vr = vr
            if (element.length < 128) {
              // const str = dataSet.string(propertyName)
              // if (elementObject.tagCode === 'x00280010') {
              //   console.log(str)
              // }
              // const stringIsAscii = this.isASCII(str)
              // if (stringIsAscii && str !== undefined) {
              //   elementObject.value = str
              // }

              if (element.vr === undefined && tag === undefined) {
                if (element.length === 2) {
                  elementObject.value = dataSet.uint16(propertyName)
                } else if (element.length === 4) {
                  elementObject.value = dataSet.uint32(propertyName)
                }
                const str = dataSet.string(propertyName)
                const stringIsAscii = this.isASCII(str)

                if (stringIsAscii) {
                  if (str !== undefined) {
                    elementObject.value = str
                  }
                } else {
                  if (element.length !== 2 && element.length !== 4) {
                    // elementObject.value = 'binary data'
                  }
                }
              } else {
                if (this.isStringVr(vr)) {
                  const str = dataSet.string(propertyName)
                  const stringIsAscii = this.isASCII(str)

                  if (stringIsAscii) {
                    if (str !== undefined) {
                      elementObject.value = str
                    }
                  } else {
                    elementObject.value = dataSet.string(propertyName)
                    // if (element.length !== 2 && element.length !== 4) {
                    //   // elementObject.value = 'binary data'
                    // }
                  }
                } else if (vr === 'US') {
                  let text = dataSet.uint16(propertyName)
                  for (let i = 1; i < dataSet.elements[propertyName].length / 2; i++) {
                    text += '\\' + dataSet.uint16(propertyName, i)
                  }
                  elementObject.value = text
                } else if (vr === 'SS') {
                  let text = dataSet.int16(propertyName)
                  for (let i = 1; i < dataSet.elements[propertyName].length / 2; i++) {
                    text += '\\' + dataSet.int16(propertyName, i)
                  }
                  elementObject.value = text
                } else if (vr === 'UL') {
                  let text = dataSet.uint32(propertyName)
                  for (let i = 1; i < dataSet.elements[propertyName].length / 4; i++) {
                    text += '\\' + dataSet.uint32(propertyName, i)
                  }
                  elementObject.value = text
                } else if (vr === 'SL') {
                  let text = dataSet.int32(propertyName)
                  for (let i = 1; i < dataSet.elements[propertyName].length / 4; i++) {
                    text += '\\' + dataSet.int32(propertyName, i)
                  }
                  elementObject.value = text
                } else if (vr === 'FD') {
                  let text = dataSet.double(propertyName)
                  for (let i = 1; i < dataSet.elements[propertyName].length / 8; i++) {
                    text += '\\' + dataSet.double(propertyName, i)
                  }
                  elementObject.value = text
                } else if (vr === 'FL') {
                  let text = dataSet.float(propertyName)
                  for (let i = 1; i < dataSet.elements[propertyName].length / 4; i++) {
                    text += '\\' + dataSet.float(propertyName, i)
                  }
                  elementObject.value = text
                } else if (vr === 'OB' || vr === 'OW' || vr === 'UN' || vr === 'OF' || vr === 'UT') {
                  if (element.length === 2) {
                    elementObject.value = dataSet.uint16(propertyName)
                  } else if (element.length === 4) {
                    elementObject.value = dataSet.uint32(propertyName)
                  } else {

                  }
                } else if (vr === 'AT') {
                  // var group = dataSet.uint16(propertyName, 0);
                  // var groupHexStr = ("0000" + group.toString(16)).substr(-4);
                  // var element = dataSet.uint16(propertyName, 1);
                  // var elementHexStr = ("0000" + element.toString(16)).substr(-4);
                  // text += "x" + groupHexStr + elementHexStr;
                } else if (vr === 'SQ') {
                } else {
                  // no display code for VR yet, sorry!
                }
              }
            }
          }

          output.push(elementObject)
        }
      } catch (err) {
        const ex = {
          exception: err,
          output: output
        }
        console.log(ex)
      }
    },
    getTag(tag) {
      var group = tag.substring(1, 5)
      var element = tag.substring(5, 9)
      var tagIndex = ('(' + group + ',' + element + ')').toUpperCase()
      var attr = TAG_DICT[tagIndex]
      return attr
    },
    isASCII(str) {
      return /^[\x00-\x7F]*$/.test(str)
    },
    isStringVr(vr) {
      if (vr === 'AT' || vr === 'FL' || vr === 'FD' || vr === 'OB' || vr === 'OF' || vr === 'OW' || vr === 'SI' || vr === 'SQ' || vr === 'SS' || vr === 'UL' || vr === 'US') {
        return false
      }
      return true
    }
  }
}
</script>
<style lang="scss" scoped>
.dcm-tag{
  // user-select: none;
  ::-webkit-scrollbar {
    width: 8px;
    height: 15px;
  }
  ::-webkit-scrollbar-thumb {
    border-radius: 10px;
    background: #d0d0d0;
  }
}
</style>
