import { TimeSelection } from '../../types';
import makeAudioBuffer from '../utils/makeAudioBuffer';

export default (audioBuffers: AudioBuffer[], normalize: boolean, [selectionStartSamples, selectionEndSamples]: TimeSelection) => {
  if (selectionStartSamples === selectionEndSamples) {
    selectionStartSamples = 0;
    selectionEndSamples = Math.max(...audioBuffers.map((b) => b.length));
  }

  if (audioBuffers.length === 0) {
    throw new Error('No buffers provided to sum');
  }

  const outputBuffer = makeAudioBuffer({
    sampleRate: audioBuffers[0].sampleRate,
    length: selectionEndSamples - selectionStartSamples,
    numberOfChannels: audioBuffers[0].numberOfChannels
  });


  for (let b = 0; b < audioBuffers.length; b ++) {
    const buffer = audioBuffers[b];
    for (let c = 0; c < buffer.numberOfChannels; c ++) {
      const channelData = buffer.getChannelData(c);
      const outputChannelData = outputBuffer.getChannelData(c);
      for (let i = 0; i < channelData.length; i ++) {
        outputChannelData[i] += channelData[i];
      }
    }
  }

  if (normalize) {
    let maxAbsoluteSample = 0;

    for (let c = 0; c < outputBuffer.numberOfChannels; c ++) {
      const channelData = outputBuffer.getChannelData(c);
      for (let i = 0; i < channelData.length; i ++) {
        maxAbsoluteSample = Math.max(maxAbsoluteSample, Math.abs(channelData[i]));
      }
    }

    const amplification = 1/maxAbsoluteSample;
    for (let c = 0; c < outputBuffer.numberOfChannels; c ++) {
      const channelData = outputBuffer.getChannelData(c);
      for (let i = 0; i < channelData.length; i ++) {
        channelData[i] *= amplification;
      }
    }
  }

  return outputBuffer;
}
