// SPDX-License-Identifier: Unlicense

#include "audioeffectx.h"

#include <stdio.h>

enum Parameter
{
  gain,
  COUNT
};

struct Gain final : AudioEffectX
{
  float parameter[Parameter::COUNT]{ 0.5f };
  char programName[kVstMaxProgNameLen + 1] = "Default";

  Gain(audioMasterCallback audioMaster)
    : AudioEffectX(audioMaster, 1, 1)	// 1 program, 1 parameter only
  {
    setUniqueID('Gain');
    setNumInputs(2);
    setNumOutputs(2);
    canProcessReplacing();
    programsAreChunks();
  }

  void processReplacing(float** inputs, float** outputs, const VstInt32 sampleFrames) override
  {
    const float gain = 2.0f * parameter[Parameter::gain];

    for (VstInt32 i = 0; i < sampleFrames; ++i)
    {
      outputs[0][i] = inputs[0][i] * gain;
      outputs[1][i] = inputs[1][i] * gain;
    }
  }

  void setParameter(const VstInt32 index, const float value) override
  {
    switch (index)
    {
    case Parameter::gain:
      parameter[index] = value;
      break;
    default:
      break;
    }
  }

  float getParameter(const VstInt32 index) override
  {
    switch (index)
    {
    case Parameter::gain:
      return parameter[index];
    default:
      return {};
    }
  }

  void setProgramName(char* name) override
  {
    vst_strncpy(programName, name, kVstMaxProgNameLen);
  }

  void getProgramName(char* name) override
  {
    vst_strncpy(name, programName, kVstMaxProgNameLen);
  }

  void getParameterLabel(const VstInt32 index, char* label) override
  {
    switch (index)
    {
    case Parameter::gain:
      vst_strncpy(label, "", kVstMaxParamStrLen);
      break;
    default:
      break;
    }
  }

  void getParameterDisplay(const VstInt32 index, char* text) override
  {
    switch (index)
    {
    case Parameter::gain:
      snprintf(text, kVstMaxParamStrLen, "%f", 2.0f * parameter[index]);
      break;
    default:
      break;
    }
  }

  void getParameterName(const VstInt32 index, char* text) override
  {
    switch (index)
    {
    case Parameter::gain:
      vst_strncpy(text, "Gain", kVstMaxParamStrLen);
      break;
    default:
      break;
    }
  }

  VstInt32 getChunk(void** data, bool isPreset = false) override
  {
    *data = parameter;
    return sizeof(parameter);
  }

  VstInt32 setChunk(void* data, VstInt32 byteSize, bool isPreset = false) override
  {
    //assert(byteSize == sizeof(parameter));
    memcpy(parameter, data, byteSize);
    return 0;
  }

  bool getEffectName(char* name) override
  {
    vst_strncpy(name, "SfxPluginVstGain", kVstMaxEffectNameLen);
    return true;
  }

  bool getVendorString(char* text) override
  {
    vst_strncpy(text, "Shr3D Industries", kVstMaxVendorStrLen);
    return true;
  }

  bool getProductString(char* text) override
  {
    vst_strncpy(text, "Shr3D", kVstMaxProductStrLen);
    return true;
  }

  VstInt32 getVendorVersion() override
  {
    return 1000;
  }

  VstPlugCategory getPlugCategory() override
  {
    return kPlugCategEffect;
  }
};

//-------------------------------------------------------------------------------------------------------
AudioEffect* createEffectInstance(audioMasterCallback audioMaster)
{
  return new Gain(audioMaster);
}
