#include "sfxCoreNeuralAmpModeler.h"

#ifdef SHR3D_SFX_CORE_NEURALAMPMODELER

#include "NeuralAmpModeler.h"

#include "../../global.h"
#include "../../file.h"

#include <memory>

void SfxCoreNeuralAmpModeler::init()
{
  const std::vector<std::u8string> files = File::filesInDirectory(Settings::pathNam.c_str());
  for (const std::u8string& file : files)
  {
    if (File::extension(file.c_str()) == std::u8string(u8".wav"))
      Global::NeuralAmpModeler_IrFiles.push_back(file);
    else if (File::extension(file.c_str()) == std::u8string(u8".nam"))
      Global::NeuralAmpModeler_NamFiles.push_back(file);
  }
}

SfxCoreNeuralAmpModeler::SfxCoreNeuralAmpModeler() : neuralAmpModeler(new NeuralAmpModeler)
{
}

i32 SfxCoreNeuralAmpModeler::getpar(i32 npar)
{
  switch (npar)
  {
  case 0:
    return input;
  case 1:
    return gate;
  case 2:
    return bass;
  case 3:
    return middle;
  case 4:
    return treble;
  case 5:
    return output;
  case 6:
    return gateEnabled;
  case 7:
    return eqEnabled;
  case 8:
    return normalizeEnabled;
  case 9:
    return namEnabled;
  case 10:
    return irEnabled;
  }
  unreachable();
}

void SfxCoreNeuralAmpModeler::changepar(i32 npar, i32 value)
{
  switch (npar)
  {
  case 0:
    input = value;
    return;
  case 1:
    gate = value;
    return;
  case 2:
    bass = value;
    return;
  case 3:
    middle = value;
    return;
  case 4:
    treble = value;
    return;
  case 5:
    output = value;
    return;
  case 6:
    gateEnabled = value;
    return;
  case 7:
    eqEnabled = value;
    return;
  case 8:
    normalizeEnabled = value;
    return;
  case 9:
    namEnabled = value;
    return;
  case 10:
    irEnabled = value;
    return;
  }
  unreachable();
}

void SfxCoreNeuralAmpModeler::processBlock(const f32* const* inBlock, f32** outBlock, const i32 blockSize)
{
  if (this == nullptr) // TODO: investigate what the fuck is going on here
    return;

  neuralAmpModeler->ProcessBlock(inBlock, outBlock, blockSize, sampleRate(), input, gate, bass, middle, treble, output, gateEnabled, eqEnabled, normalizeEnabled, irEnabled, namEnabled);

  if (nextIrFileIndex != loadedIrFileIndex)
  {
    loadedIrFileIndex = nextIrFileIndex;
    if (nextIrFileIndex == -1)
    {
      neuralAmpModeler->mShouldRemoveIR = true;
    }
    else
    {
#ifdef __ANDROID__
      neuralAmpModeler->_StageIR(Global::rootPath + Global::NeuralAmpModeler_IrFiles[nextIrFileIndex]);
#else // __ANDROID__
      neuralAmpModeler->_StageIR(Global::NeuralAmpModeler_IrFiles[nextIrFileIndex]);
#endif // __ANDROID__
    }
  }
  if (nextNamFileIndex != loadedNamFileIndex)
  {
    loadedNamFileIndex = nextNamFileIndex;
    if (nextNamFileIndex == -1)
    {
      neuralAmpModeler->mShouldRemoveModel = true;
    }
    else
    {
#ifdef __ANDROID__
      neuralAmpModeler->_StageModel(Global::rootPath + Global::NeuralAmpModeler_NamFiles[nextIrFileIndex]);
#else // __ANDROID__
      neuralAmpModeler->_StageModel(Global::NeuralAmpModeler_NamFiles[nextNamFileIndex]);
#endif // __ANDROID__
    }
  }
}

#endif // SHR3D_SFX_CORE_NEURALAMPMODELER