// SPDX-License-Identifier: Unlicense

#ifndef SFXCORE_H
#define SFXCORE_H

#include "type.h"

#include <string>
#ifdef SHR3D_SFX_CORE

#include "sfxCore/neuralAmpModeler/sfxCoreNeuralAmpModeler.h"
#include "sfxCore/rakarrack/effects/Alienwah.h"
#include "sfxCore/rakarrack/effects/AnalogPhaser.h"
#include "sfxCore/rakarrack/effects/Arpie.h"
#include "sfxCore/rakarrack/effects/Chorus_.h"
#include "sfxCore/rakarrack/effects/CoilCrafter.h"
#include "sfxCore/rakarrack/effects/CompBand.h"
#include "sfxCore/rakarrack/effects/Convolotron.h"
#include "sfxCore/rakarrack/effects/Derelict.h"
#include "sfxCore/rakarrack/effects/DistBand.h"
#include "sfxCore/rakarrack/effects/Distorsion_.h"
#include "sfxCore/rakarrack/effects/DualFlange.h"
#include "sfxCore/rakarrack/effects/DynamicFilter.h"
#include "sfxCore/rakarrack/effects/Echo.h"
#include "sfxCore/rakarrack/effects/Echotron.h"
#include "sfxCore/rakarrack/effects/Echoverse.h"
#include "sfxCore/rakarrack/effects/EQ_.h"
#include "sfxCore/rakarrack/effects/Exciter_.h"
#include "sfxCore/rakarrack/effects/Expander.h"
#include "sfxCore/rakarrack/effects/Harmonizer.h"
#include "sfxCore/rakarrack/effects/MusicalDelay.h"
#include "sfxCore/rakarrack/effects/MuTroMojo.h"
#include "sfxCore/rakarrack/effects/NoiseGate_.h"
#include "sfxCore/rakarrack/effects/OpticalTrem.h"
#include "sfxCore/rakarrack/effects/Pan_.h"
#include "sfxCore/rakarrack/effects/Phaser.h"
#include "sfxCore/rakarrack/effects/Reverb_.h"
#include "sfxCore/rakarrack/effects/Reverbtron.h"
#include "sfxCore/rakarrack/effects/Ring.h"
#include "sfxCore/rakarrack/effects/Sequence.h"
#include "sfxCore/rakarrack/effects/ShelfBoost.h"
#include "sfxCore/rakarrack/effects/Shifter.h"
#include "sfxCore/rakarrack/effects/Shuffle.h"
#include "sfxCore/rakarrack/effects/StereoHarm.h"
#include "sfxCore/rakarrack/effects/StompBox.h"
#include "sfxCore/rakarrack/effects/Sustainer.h"
#include "sfxCore/rakarrack/effects/Synthfilter.h"
#include "sfxCore/rakarrack/effects/Valve.h"
#include "sfxCore/rakarrack/effects/VaryBand.h"
#include "sfxCore/rakarrack/effects/Vibe.h"
#include "sfxCore/rakarrack/effects/Vocoder.h"

#include <vector>

enum struct SfxSystem : u8;

namespace SFXCore
{
#ifdef SHR3D_SFX_CORE_NEURALAMPMODELER
  extern std::vector<SfxCoreNeuralAmpModeler> nam;
#endif // SHR3D_SFX_CORE_NEURALAMPMODELER

#ifdef SHR3D_SFX_CORE_RAKARRACK
  extern std::vector<Reverb> reverb;
  extern std::vector<Echo> echo;
  extern std::vector<Chorus> chorus;
  extern std::vector<Phaser> phaser;
#ifdef SHR3D_SFX_CORE_RAKARRACK_LIBSAMPLERATE
  extern std::vector<Distorsion> distorsion;
#endif // SHR3D_SFX_CORE_RAKARRACK_LIBSAMPLERATE
  extern std::vector<EQ> eq;
  extern std::vector<Compressor> compressor;
  extern std::vector<DynamicFilter> wahWah;
  extern std::vector<Alienwah> alienWah;
  extern std::vector<Pan> pan;
#ifdef SHR3D_SFX_CORE_RAKARRACK_LIBSAMPLERATE
#if 0
  extern std::vector<Harmonizer> harmonizer;
#endif
#endif // SHR3D_SFX_CORE_RAKARRACK_LIBSAMPLERATE
  extern std::vector<MusicalDelay> musicalDelay;
  extern std::vector<NoiseGate> noiseGate;
#ifdef SHR3D_SFX_CORE_RAKARRACK_LIBSAMPLERATE
  extern std::vector<Derelict> derelict;
#endif // SHR3D_SFX_CORE_RAKARRACK_LIBSAMPLERATE
  extern std::vector<AnalogPhaser> analogPhaser;
  extern std::vector<Valve> valve;
  extern std::vector<DualFlange> dualFlange;
  extern std::vector<Ring> ring;
  extern std::vector<Exciter> exciter;
#ifdef SHR3D_SFX_CORE_RAKARRACK_LIBSAMPLERATE
  extern std::vector<DistBand> distBand;
#endif // SHR3D_SFX_CORE_RAKARRACK_LIBSAMPLERATE
  extern std::vector<Arpie> arpie;
  extern std::vector<Expander> expander;
  extern std::vector<Shuffle> shuffle;
  extern std::vector<Synthfilter> synthFilter;
  extern std::vector<VaryBand> varyBand;
#ifdef SHR3D_SFX_CORE_RAKARRACK_LIBSAMPLERATE
#ifdef SHR3D_SFX_CORE_RAKARRACK_CONVOLOTRON
  extern std::vector<Convolotron> convolotron;
#endif // SHR3D_SFX_CORE_RAKARRACK_CONVOLOTRON
#endif // SHR3D_SFX_CORE_RAKARRACK_LIBSAMPLERATE
  extern std::vector<MuTroMojo> muTroMojo;
  extern std::vector<Echoverse> echoverse;
  extern std::vector<CoilCrafter> coilCrafter;
  extern std::vector<ShelfBoost> shelfBoost;
#ifdef SHR3D_SFX_CORE_RAKARRACK_LIBSAMPLERATE
  extern std::vector<Vocoder> vocoder;
#endif // SHR3D_SFX_CORE_RAKARRACK_LIBSAMPLERATE
  extern std::vector<Sustainer> sustainer;
#ifdef SHR3D_SFX_CORE_RAKARRACK_LIBSAMPLERATE
  extern std::vector<Sequence> sequence;
  extern std::vector<Shifter> shifter;
  extern std::vector<StompBox> stompBox;
#ifdef SHR3D_SFX_CORE_RAKARRACK_REVERBTRON
  extern std::vector<Reverbtron> reverbtron;
#endif // SHR3D_SFX_CORE_RAKARRACK_REVERBTRON
#endif // SHR3D_SFX_CORE_RAKARRACK_LIBSAMPLERATE
  extern std::vector<Echotron> echotron;
#ifdef SHR3D_SFX_CORE_RAKARRACK_LIBSAMPLERATE
  extern std::vector<StereoHarm> stereoHarm;
#endif // SHR3D_SFX_CORE_RAKARRACK_LIBSAMPLERATE
  extern std::vector<CompBand> compBand;
  extern std::vector<OpticalTrem> opticalTrem;
  extern std::vector<Vibe> vibe;
#endif // SHR3D_SFX_CORE_RAKARRACK

  void init();

  ProcessBlockResult processBlock(SfxId sfxId, i32 instance, f32** inBlock, f32** outBlock, i32 blockSize);

  std::u8string saveParameters(SfxId sfxId, i32 instance);
  void loadParameters(SfxId sfxId, i32 instance, const std::u8string& parameters);

#ifdef SHR3D_SFX_CORE_AIRWINDOWS
  i32 getParameterCount(SfxCoreAirWindows_ sfxCoreAirWindows);
  f32 getParameter(SfxCoreAirWindows_ sfxCoreAirWindows, i32 instance, i32 param);
  void setParameter(SfxCoreAirWindows_ sfxCoreAirWindows, i32 instance, i32 param, f32 value);
  void getParameterLabel(SfxCoreAirWindows_ sfxCoreAirWindows, i32 instance, i32 param, char* text);
  void getParameterName(SfxCoreAirWindows_ sfxCoreAirWindows, i32 instance, i32 param, char* text);
  void getParameterDisplay(SfxCoreAirWindows_ sfxCoreAirWindows, i32 instance, i32 param, char* text);
#endif // SHR3D_SFX_CORE_AIRWINDOWS
}

#endif // SHR3D_SFX_CORE

#endif // SFXCORE_H