// SPDX-License-Identifier: Unlicense

#include "api.h"

#ifdef SHR3D_SFX_CORE_EXTENSION_V2

#include <stdio.h>

static constexpr f32 default_gain = 0.5f;

struct GainInstance final : SfxCoreExtensionV2Instance
{
  f32 gain = default_gain;

  ProcessBlockResult processBlock(f32** inBlock, f32** /*outBlock*/, const i32 blockSize) override
  {
    for (i32 i = 0; i < blockSize; ++i)
    {
      inBlock[0][i] = inBlock[0][i] * 2.0f * gain;
      inBlock[1][i] = inBlock[1][i] * 2.0f * gain;
    }
    return ProcessBlockResult::ProcessedInInBlock;
  }

  f32 getParameter(const i32 index) const override
  {
    switch (index)
    {
    case 0:
      return gain;
    default:
      unreachable();
    }
  }

  void setParameter(const i32 index, const f32 value) override
  {
    switch (index)
    {
    case 0:
      gain = value;
      break;
    default:
      unreachable();
    }
  }

  void getParameterDisplay(const i32 index, char* text) override
  {
    switch (index)
    {
    case 0:
      sprintf(text, "%8.2f", gain * 2.0f);
      break;
    default:
      unreachable();
    }
  }

  void resetParameter(const i32 index) override
  {
    switch (index)
    {
    case 0:
      gain = default_gain;
      break;
    default:
      unreachable();
    }
  }
};

static struct Gain final : SfxCoreExtensionV2Base
{
  Gain()
  {
    RegisterSfxCoreExtensionV2(u8"Gain", this);
  }

  i32 getParameterCount() const override
  {
    return 1;
  }

  const char8_t* getParameterLabel(const i32 index) override
  {
    switch (index)
    {
    case 0:
      return u8"";
    default:
      unreachable();
    }
  }

  const char8_t* getParameterName(const i32 index) override
  {
    switch (index)
    {
    case 0:
      return u8"Gain";
    default:
      unreachable();
    }
  }

  SfxCoreExtensionV2Instance* getInstance(const i32 instance) override
  {
    static SfxCoreExtensionV2Instance* instances[ExtensionV2MaxInstanceCount];
    assert(instance < ARRAY_SIZE(instances));

    if (instances[instance] == nullptr)
      instances[instance] = new GainInstance;

    return instances[instance];
  }
} gain;

#endif // SHR3D_SFX_CORE_EXTENSION_V2
