<template>
  <div class="player">
    <div class="slider-wrapper">
      <div v-if="muted" @click="toggleMute">
        <img style="width: 25px" src="~/assets/image/noiseicon_muted.svg">
      </div>
      <div v-else @click="toggleMute">
        <img style="width: 25px" src="~/assets/image/noiseicon.svg">
      </div>
      <div class="slider">
        <input
          id="gain-control-noise"
          v-model="volume"
          type="range"
          min="0"
          max="1"
          step="0.005"
          @wheel.prevent="changeVolumeOnWheel"
        >

        <span class="slider-progress-bar" :style="{ width: `${volume * 100}%` }" />
      </div>
    </div>
    <NoiseControlledWebAudio3Band
      v-for="(frequency, index) in frequencies"
      ref="Player"
      :key="frequency"
      :master-attack="masterAttack"
      :master-release="masterRelease"
      :center-frequency="frequency"
      :master-gain="masterGain"
      :q-factor="qFactors[index]"
      @ready="onBandReady"
      @update:mid-volume="controlMusicGain"
    />
  </div>
</template>
<script lang="ts">

import { useAudioStore } from '../../stores/audio'
import { useMicStore } from '~/stores/microphone'
import type { Microphone } from '~/stores/interfaces/Microphone'
import NoiseControlledWebAudio3Band from '~/components/experiments/tests/ControlValues/NoiseControlledWebAudio3Band'

export default {
  name: 'AdaptiveNoiseGain',
  components: {
    NoiseControlledWebAudio3Band
  },
  emits: ['musicGain'],
  setup () {
    const masterGain = ref(useAudioStore().getMasterGainNoise())
    const player = ref(null)
    const { t } = useI18n()
    const frequencies = ref([150, 1500, 8000])
    const qFactors = ref([0.8, 0.9, 0.6])
    const loadedBands = ref(0)
    const muted = computed(() => useAudioStore().getNoiseVolume < 0.01)
    let oldVolume = 0

    const route = useRoute()
    const isExperimentsRoute = computed(() => route.path.match(/\/[a-z]{2}\/experiments/))

    const masterAttack = ref(120000 * 2) // Beispielwert in Samples
    const masterRelease = ref(144000 * 2)

    const loading = computed(() => loadedBands.value < frequencies.value.length)

    const onBandReady = () => {
      loadedBands.value++
    }
    const toggleMute = () => {
      if (!muted.value) {
        oldVolume = masterGain.value.gain.value
        masterGain.value.gain.linearRampToValueAtTime(0, masterGain.value.context.currentTime + 0.4)
        useAudioStore().setNoiseVolume(0)
      } else if (oldVolume > 0) {
        masterGain.value.gain.linearRampToValueAtTime(oldVolume, masterGain.value.context.currentTime + 0.4)
        useAudioStore().setNoiseVolume(oldVolume)
      } else {
        masterGain.value.gain.linearRampToValueAtTime(1, masterGain.value.context.currentTime + 0.4)
        useAudioStore().setNoiseVolume(1)
      }
    }

    return {
      frequencies,
      loading,
      onBandReady,
      t,
      loadedBands,
      masterAttack,
      masterRelease,
      isExperimentsRoute,
      qFactors,
      masterGain,
      toggleMute,
      muted,
      player
    }
  },
  data () {
    return {
      audioContext: useAudioStore().getContext(),
      musicReady: false,
      tropics_src: window.location.origin + useRuntimeConfig().public.tracks.masking_src as string,
      fading: false,
      connected: false,
      volume: useAudioStore().noiseVolume,
      previousVolume: useAudioStore().noiseVolume
    }
  },
  onMounted () {
  },
  watch: {
    volume (newVolume: number) {
      const audioStore = useAudioStore()
      audioStore.setNoiseVolume(newVolume)
      if (!isNaN(newVolume)) { audioStore.getMasterGainNoise().gain.linearRampToValueAtTime(newVolume, 0.125) }
      const m = this.muted
    }
  },
  beforeUnmount () {
    const micro = useMicStore().getMicrophone() as Microphone
    micro.microphoneStream?.getTracks().forEach(m => m.stop())
  },
  methods: {
    changeVolumeOnWheel (event:WheelEvent) {
      // Adjust volume on wheel scroll
      const gainValue = this.volume
      const deltaY = event.deltaY
      if (deltaY < 0) {
        const volumeAdd = (Math.min(1, gainValue + 0.02))
        this.volume = volumeAdd
      } else {
        const volumeCut = (Math.max(0, gainValue - 0.02))
        this.volume = volumeCut
      }
    },
    controlMusicGain (value: string) {
      this.$emit('musicGain', value)
    },
    handleCanPlayNoise () {
      // useNuxtApp().$logger.log('NoiseElemeint has now playingstate: ' + state)
      this.musicReady = true
    },

    readyForWebaudio () {
      if (!this.musicReady) {
        // useNuxtApp().$logger.log('music not ready')
        return false
      }
      return true
    }
  }
}

</script>
