<template>
  <div>
    <h1>Dynamic Patches in parallel mit knistern</h1>
    <p>In diesem Test funktioniert die Messung der Störwerte sowie eine Umwandlung nach StevensLoudness. Verwendet wird hier eine AudioBufferSourceNode pro Band.</p>
    <div>
      <label for="patchCount">Number of Patches:</label>
      <input
        id="patchCount"
        v-model.number="patchCount"
        type="number"
        min="1"
        max="20"
        :disabled="isStarted"
      >
    </div>
    <button :disabled="isStarted" @click="startAllPatches">Start All Patches</button>
    <table v-if="isStarted">
      <thead>
        <tr>
          <th v-for="index in patchCount" :key="index">Patch {{ index }}</th>
        </tr>
      </thead>
      <tbody>
        <tr>
          <td v-for="(value, index) in controlValues" :key="index">{{ formatValue(value.value) }}  </td>
        </tr>
        <tr>
          <td v-for="(value, index) in controlValues" :key="index">{{ formatValue(dBToStevensLoudness(value?.value)) }}  </td>
        </tr>
        <!--
        <tr>
          <td v-for="(value, index) in controlValues" :key="index"> <AudioTagWebAudio :src="audioSources[index]" :volume="dBToStevensLoudness(value?.value)" /> </td>
        </tr>
        -->
      </tbody>
    </table>

    <AudioTagWebAudio
      v-for="index in patchCount"
      :key="index"
      :ref="el => { if (el) audioRefs[index - 1] = el }"
      :src="audioSources.at(index-1)"
      :volume="dBToStevensLoudness(controlValues[index])"
    />

    <RNBOControlValue
      v-for="index in patchCount"
      :key="index"
      :ref="el => { if (el) rnboRefs[index - 1] = el }"
      :center-frequency="centerFrequencies.at(index-1)"
      @control-value-change="updateValueTable(index - 1, $event)"
    />
  </div>
</template>

<script setup>
import { ref, onMounted, watch } from 'vue'
import RNBOControlValue from '@/components/experiments/tests/ControlValues/RNBOControlValue.vue'
import AudioTagWebAudio from '~/components/experiments/AudioTagWebAudio.vue'
import { calculateNormalizedVolume } from '~/lib/AudioFunctions'

const patchCount = ref(9)
const controlValues = ref([])
const rnboRefs = ref([])
const audioRefs = ref([])
const isStarted = ref(false)
const centerFrequencies = ref([63, 125, 250, 500, 1000, 2000, 4000, 8000, 16000])
const audioSources = ref(
  [
    'https://192.168.188.182:3000/masking/bands/Quellrauschen63.wav',
    'https://192.168.188.182:3000/masking/bands/Quellrauschen125.wav',
    'https://192.168.188.182:3000/masking/bands/Quellrauschen250.wav',
    'https://192.168.188.182:3000/masking/bands/Quellrauschen500.wav',
    'https://192.168.188.182:3000/masking/bands/Quellrauschen1000.wav',
    'https://192.168.188.182:3000/masking/bands/Quellrauschen2000.wav',
    'https://192.168.188.182:3000/masking/bands/Quellrauschen4000.wav',
    'https://192.168.188.182:3000/masking/bands/Quellrauschen8000.wav',
    'https://192.168.188.182:3000/masking/bands/Quellrauschen16000.wav'
  ])
const updateValueTable = (index, value) => {
  controlValues.value[index] = value
}

const startAllPatches = () => {
  isStarted.value = true
  rnboRefs.value.forEach((rnbo) => {
    if (rnbo && typeof rnbo.testControlValuesDevice === 'function') {
      rnbo.testControlValuesDevice()
    }
  })
  audioRefs.value.forEach((audio) => {
    useNuxtApp().$logger.log('AudioRef = ', { audio })
  })
}

const formatValue = (value) => {
  return Number(value).toFixed(2)
}

const mapLinearRange = (
  value,
  inMin,
  inMax,
  outMin,
  outMax
) => {
  const clamped = Math.max(inMin, Math.min(value, inMax)) // optional: clamp
  return ((clamped - inMin) / (inMax - inMin)) * (outMax - outMin) + outMin
}

const dBToStevensLoudness = (db) => {
  return calculateNormalizedVolume(db)
}

watch(patchCount, (newCount) => {
  controlValues.value = new Array(newCount).fill(0)
  rnboRefs.value = new Array(newCount).fill(null)
})
onMounted(() => {
  controlValues.value = new Array(patchCount.value).fill(0)
  rnboRefs.value = new Array(patchCount.value).fill(null)
})
</script>

<style scoped>
table {
  width: 100%;
  border-collapse: collapse;
  margin-top: 20px;
}

th, td {
  border: 1px solid #ddd;
  padding: 8px;
  text-align: center;
}

th {
  background-color: #f2f2f2;
}

button, input {
  margin: 10px;
  padding: 10px;
  font-size: 16px;
}
button {
  cursor: pointer;
}

input:disabled, button:disabled {
  opacity: 0.5;
  cursor: not-allowed;
}
</style>
