import Effect from '../Effect';
import NumberSetting from '../Settings/NumberSetting';
import { modulo } from '../utils';

type DelaySettings = {
  delayTime: NumberSetting;
  feedback: NumberSetting;
}

export default class Delay extends Effect<DelaySettings> {
  history: Float32Array[] = [];
  getDefaultSettings() {
    return {
      delayTime: new NumberSetting(this.sampleRate),
      feedback: new NumberSetting(0),
    }
  }

  updateOutputSamples(inputSamples: Float32Array) {
    const delayTime = this.settings.delayTime.value;
    const feedback = this.settings.feedback.value;
    const readIndex = modulo((this.time - delayTime), delayTime);
    const writeIndex = modulo(this.time, delayTime);
    const delayedSamples = this.history[Math.round(readIndex)] || new Float32Array(this.numberOfChannels);
    this.history[Math.round(writeIndex)] = inputSamples.map((sample, index) => sample + (feedback * delayedSamples[index]))
    if (this.history.length > delayTime) {
      this.history.splice(0, this.history.length - delayTime);
    }
    for (let i = 0; i < this.numberOfChannels; i ++) {
      this.outputSamples[i] = delayedSamples[i];
    }
  }
}
