<template>
  <f7-page name="detect">
    <!-- Top Navbar -->
    <f7-navbar :sliding="false" back-link="Back">
      <f7-nav-title sliding>{{ regions[activeRegion] }}</f7-nav-title>
      <f7-nav-right>
        <f7-link icon-ios="f7:menu" icon-md="material:settings" panel-open="right"></f7-link>
      </f7-nav-right>
    </f7-navbar>
    <f7-block class="detect-grid">
      <div class="image-container">
        <img v-if="imageView" :src="imageView" id="im-display" ref="image_src" style="flex: 1 1 0%; object-fit: contain; max-width: 100%; max-height: 100%; min-width: 0; min-height: 0;" />
        <img v-else src="../assets/icons/image.svg" id="im-display" ref="image_src" style="flex: 1 1 0%; object-fit: contain; max-width: 100%; max-height: 100%; min-width: 0; min-height: 0;" />
        <div ref="structure_box" style="border: solid 3px yellow; position: absolute; display: none; box-sizing: border-box;" />
      </div>
      <div v-if="resultData && resultData.detections" class="chip-results" style="grid-area: result-view; flex: 0 0 auto; align-self: center;">
        <f7-chip v-for="(result, idx) in resultData.detections" :class="(idx == selectedChip) ? 'selected-chip' : ''" :text="result.label" media=" " :tooltip="result.confidence.toFixed(1)" :media-bg-color="chipColor(result.confidence)" deleteable @click="selectChip(idx)" @delete="deleteChip(idx)" />
      </div>
      <f7-segmented class="image-menu" raised>
        <f7-button popover-open="#region-popover">
          <img v-if="activeRegion == 0" src="../assets/regions/thorax.svg" />
          <img v-else-if="activeRegion == 1" src="../assets/regions/abdpel.svg" />
          <img v-else-if="activeRegion == 2" src="../assets/regions/limb.svg" />
          <img v-else-if="activeRegion == 3" src="../assets/regions/headneck.svg" />
        </f7-button>
        <f7-button @click="selectImage">
          <img src="../assets/icons/image.svg" />
        </f7-button>
        <f7-button @click="setData" :class="(imageLoaded) ? '' : 'disabled'">
          <img src="../assets/icons/visibility.svg" />
        </f7-button>
        <f7-button class="disabled" @click="setData">
          <img src="../assets/icons/videocam.svg" />
        </f7-button>
      </f7-segmented>
      <input type="file" ref="image_chooser" @change="getImage()" accept="image/*" style="display: none;"/>
    </f7-block>

    <f7-panel right cover>
      <f7-page>
        <f7-navbar title="Detection Settings"></f7-navbar>
        <f7-list>
          <f7-list-input v-model:value="detectSettings.level" :label="`Confidence % threshold: ${detectSettings.level}`" type="range" />
          <f7-list-item accordion-item title="Structures">
            <f7-accordion-content>
              <f7-list>
                <f7-list-item checkbox checked checkbox-icon="end" title="All/none" @change="selectAll"></f7-list-item>
                <f7-list-item v-for="structure in detectSettings.filter" checkbox checkbox-icon="end" v-model:checked="structure.detect" :title="structure.name"></f7-list-item>
              </f7-list>
            </f7-accordion-content>
          </f7-list-item>
          <f7-list-item title="Turn on debugging">
            <f7-toggle v-model:checked="debugOn" style="margin-right: 16px;" />
          </f7-list-item>
        </f7-list>
        <f7-block v-if="debugOn" v-html="debugDisplay" />
      </f7-page>
    </f7-panel>
  </f7-page>
</template>

<style>
  .detect-grid {
    display: grid;
    grid-template-columns: 1fr;
    grid-template-rows: 1fr auto min-content;
    grid-template-areas: 
      "image-view"
      "result-view"
      "menu-view";
    justify-items: center;
    height: calc(100% - var(--f7-navbar-height) - var(--f7-safe-area-top) - var(--f7-safe-area-bottom));
    max-height: calc(100% - var(--f7-navbar-height) - var(--f7-safe-area-top) - var(--f7-safe-area-bottom));
  }

  .image-container {
    grid-area: image-view;
    max-width: 100%;
    max-height: 100%;
    min-width: 0;
    min-height: 0;
    position: relative;
    display: flex;
    align-self: stretch;
  }

  .chip-results {
    display: flex;
    flex-wrap: wrap;
    gap: 5px;
    padding: 10px;
    --f7-chip-border-radius: 16px;
    --f7-chip-media-size: 32px;
    --f7-chip-font-weight: normal;
  }

  .chip-results .chip {
    padding-left: 8px;
  }

  .selected-chip {
    font-weight: 500;
    box-shadow: 4px 4px 1px var(--f7-theme-color);
    transform: translate(-2px, -2px);
  }

  .image-menu {
    grid-area: menu-view;
    margin: 5px;
    width: 50%;
    max-width: 400px;
    min-width: 192px;
    flex: 0 0 auto;
  }

  .image-menu .button {
    aspect-ratio: 1;
    height: auto;
    padding: 5px;
  }

  .button > img {
    height: 100%;
  }

  @media (max-height: 450px) and (orientation: landscape) {
    .detect-grid {
      grid-template-columns: minmax(0,1fr) max-content auto;
      grid-template-rows: calc(100vh - var(--f7-navbar-height) - var(--f7-safe-area-top) - var(--f7-safe-area-bottom) - 64px);
      grid-template-areas: 
        "image-view result-view menu-view";
      justify-items: stretch;
      align-items: stretch;
      height: calc(100% - var(--f7-navbar-height) - var(--f7-safe-area-top) - var(--f7-safe-area-bottom));
      max-height: calc(100% - var(--f7-navbar-height) - var(--f7-safe-area-top) - var(--f7-safe-area-bottom));
      position: relative;
    }

    .chip-results {
      flex-direction: column;
      max-height: 100%;
      justify-self: start;
      flex-wrap: nowrap;
      overflow-y: scroll;
    }

    .image-container {
      flex-direction: column;
    }

    .image-menu {
      flex-direction: column;
      width: auto;
      min-width: 0;
      flex: 1 1 0%;
      max-height: 100%;
    }

    .image-menu .button {
      aspect-ratio: 1;
      width: auto;
      height: 100%;
      flex: 1 1 0%;
      border-bottom: 1px solid var(--f7-segmented-raised-divider-color);
    }

    .button > img {
      width:auto;
      height: 100%;
    }
  }
</style>

<script>
  import { f7 } from 'framework7-vue'

  export default {
    props: {
      f7route: Object,
    },
    data () {
      return {
        regions: ['Thorax','Abdomen/Pelvis','Limbs','Head and Neck'],
        resultData: {},
        selectedChip: -1,
        activeRegion: 4,
        imageRegion: '',
        imageLoaded: false,
        imageView: '',
        reader: new FileReader(),
        detectorName: '',
        detectSettings: {
          level: 50,
          filter: []
          },
        serverSettings: {},
        debugOn: true,
        debugText: ['Variables loaded']
      }
    },
    created () {
      switch (this.f7route.params.region) {
        case 'thorax':
        this.activeRegion = 0
        this.detectorName = 'thorax'
          break;
        case 'abdomen':
        this.activeRegion = 1
        this.detectorName = 'combined'
          break;
        case 'limbs':
        this.activeRegion = 2
        this.detectorName = 'defaultNew'
          break;
        case 'head':
        this.activeRegion = 3
          break;
      }
      var loadServerSettings = localStorage.getItem('serverSettings')
      if (loadServerSettings) this.serverSettings = JSON.parse(loadServerSettings)
      var self = this
      if (this.serverSettings && this.serverSettings.use) {
        var modelURL = `http://${this.serverSettings.address}:${this.serverSettings.port}/detectors`
        var xhr = new XMLHttpRequest()
        xhr.open("GET", modelURL)
        xhr.setRequestHeader('Content-Type', 'application/json')
        xhr.onload = function () {
          if (self.debugOn) self.debugText.push(xhr.response) //DEBUG ANDROID BUILD
          if (this.status !== 200) {
            //this.response.text().then(function(message){alert(message)})
            self.debugText.push(xhr.response)
            console.log(xhr.response)
            return;
          }
          var detectors = JSON.parse(xhr.response).detectors
          self.detectSettings.filter = detectors
            .find( d => { return d.name == self.detectorName } ).labels
            .filter( l => { return l != "" } ).sort()
            .map( l => { return {'name': l, 'detect': true} } )
        }
        xhr.send()
      }
    },
    computed: {
      debugDisplay () {
        return this.debugText.join('<br/>')
      }
    },
    methods: {
      chipColor (confVal) {
        if (confVal >= 90) return 'green'
        if (confVal >= 70) return 'lime'
        return 'yellow'
      },
      setData () {
        var self = this
        if (this.serverSettings && this.serverSettings.use) {
          var modelURL = `http://${this.serverSettings.address}:${this.serverSettings.port}/detect`
          var xhr = new XMLHttpRequest()
          xhr.open("POST", modelURL)
          xhr.setRequestHeader('Content-Type', 'application/json')
          xhr.onload = function () {
            if (self.debugOn) self.debugText.push(xhr.response)
            if (this.status !== 200) {
              //this.response.text().then(function(message){alert(message)})
              self.debugText.push(xhr.response)
              console.log(xhr.response)
              return;
            }
            self.resultData = JSON.parse(xhr.response)
          }
          
          var detectStructures = {}
          if (this.detectSettings.filter.every( s => { return s.detect } )) {
            detectStructures['*'] = this.detectSettings.level
          } else {
            this.detectSettings.filter.forEach( s => {
              if (s.detect) detectStructures[s.name] = this.detectSettings.level
            })
          }
          var doodsData = {
            "detector_name": this.detectorName,
            "detect": detectStructures,
            "data": this.reader.result.split(',')[1]
          }

          xhr.send(JSON.stringify(doodsData))
        } else {
          //TODO
          f7.dialog.alert('Using built-in model')
        }
      },
      selectAll (ev) {
        if (ev.target.checked) {
          this.detectSettings.filter.forEach( s => s.detect = true )
        } else {
          this.detectSettings.filter.forEach( s => s.detect = false )
        }
      },
      selectImage () {
        var loadResult = this.$refs.image_chooser.click()
      },
      selectChip ( iChip ) {
        var imgWidth
        var imgHeight

        this.selectedChip = iChip
        const box = this.$refs.structure_box
        const img = this.$refs.image_src
        var imgAspect = img.naturalWidth / img.naturalHeight
        var rendAspect = img.offsetWidth / img.offsetHeight
        if (imgAspect >= rendAspect) {
          imgWidth = img.offsetWidth
          imgHeight = img.offsetWidth / imgAspect
        } else {
          imgWidth = img.offsetHeight * imgAspect
          imgHeight = img.offsetHeight
        }
        box.style.display = 'block'
        box.style.left = `${(img.offsetWidth - imgWidth) / 2 + this.resultData.detections[iChip].left * imgWidth}px`
        box.style.top = `${(img.offsetHeight - imgHeight) / 2 + this.resultData.detections[iChip].top * imgHeight}px`
        box.style.width = `${(Math.min(this.resultData.detections[iChip].right, 1) - Math.max(this.resultData.detections[iChip].left, 0)) * imgWidth}px`
        box.style.height = `${(Math.min(this.resultData.detections[iChip].bottom, 1) - Math.max(this.resultData.detections[iChip].top, 0)) * imgHeight}px`
      },
      deleteChip ( iChip ) {
        f7.dialog.confirm(`${this.resultData.detections[iChip].label} is identified with ${this.resultData.detections[iChip].confidence.toFixed(1)}% confidence. Are you sure you want to delete it?`, () => {
          this.resultData.detections.splice(iChip, 1)
          this.selectedChip = -1
          const box = this.$refs.structure_box
          box.style.display = 'none'
        });
      },
      getImage () {
        var self = this
        const searchImage = this.$refs.image_chooser.files[0]
        let loadImage =new Promise((resolve, reject) => {
          this.imageView = URL.createObjectURL(searchImage)
          this.reader.readAsDataURL(searchImage)
          resolve()
        })
        loadImage.then(() => {
          this.imageLoaded = true
          this.resultData = {}
          this.selectedChip = -1
          const box = this.$refs.structure_box
          box.style.display = 'none'
        }).catch((e) => {
          console.log(e.message)
          f7.dialog.alert('Error loading image')
        })
      }
    }
  }
</script>