#pragma once

#include "DeepPluckParameters.h"

#include <array>

namespace deeppluck
{
inline constexpr std::array<const char*, 62> allParameterIds {
    ParameterIDs::outputGain,
    ParameterIDs::masterTune,
    ParameterIDs::ampAttack,
    ParameterIDs::ampDecay,
    ParameterIDs::ampSustain,
    ParameterIDs::ampRelease,
    ParameterIDs::filterEnabled,
    ParameterIDs::filterCutoff,
    ParameterIDs::filterResonance,
    ParameterIDs::filterDrive,
    ParameterIDs::filterKeyTracking,
    ParameterIDs::filterEnvAmount,
    ParameterIDs::filterAttack,
    ParameterIDs::filterDecay,
    ParameterIDs::filterSustain,
    ParameterIDs::filterRelease,
    ParameterIDs::transientEnabled,
    ParameterIDs::transientLevel,
    ParameterIDs::transientDecay,
    ParameterIDs::transientTone,
    ParameterIDs::noiseEnabled,
    ParameterIDs::noiseLevel,
    ParameterIDs::noiseDecay,
    ParameterIDs::noiseTone,
    ParameterIDs::osc2Enabled,
    ParameterIDs::osc2Level,
    ParameterIDs::osc2Octave,
    ParameterIDs::osc2Semitone,
    ParameterIDs::osc2FineTune,
    ParameterIDs::unisonVoices,
    ParameterIDs::unisonDetune,
    ParameterIDs::stereoSpread,
    ParameterIDs::lfoRate,
    ParameterIDs::lfoSync,
    ParameterIDs::lfoSyncDivision,
    ParameterIDs::lfoWaveform,
    ParameterIDs::lfoRestartMode,
    ParameterIDs::lfoFilterAmount,
    ParameterIDs::lfoPitchAmount,
    ParameterIDs::lfoSpreadAmount,
    ParameterIDs::osc1Waveform,
    ParameterIDs::osc1PulseWidth,
    ParameterIDs::osc2Waveform,
    ParameterIDs::osc2PulseWidth,
    ParameterIDs::chorusBypass,
    ParameterIDs::chorusRate,
    ParameterIDs::chorusDepth,
    ParameterIDs::chorusWidth,
    ParameterIDs::chorusMix,
    ParameterIDs::delayBypass,
    ParameterIDs::delaySync,
    ParameterIDs::delayTime,
    ParameterIDs::delaySyncDivision,
    ParameterIDs::delayFeedback,
    ParameterIDs::delayTone,
    ParameterIDs::delayMix,
    ParameterIDs::reverbBypass,
    ParameterIDs::reverbSize,
    ParameterIDs::reverbPreDelay,
    ParameterIDs::reverbDamping,
    ParameterIDs::reverbMix,
    ParameterIDs::fxOrder
};

using DeepPluckParameterValues = std::array<float, allParameterIds.size()>;

[[nodiscard]] DeepPluckParameterValues captureParameterValues (
    const juce::AudioProcessorValueTreeState& state) noexcept;
[[nodiscard]] DeepPluckParameterValues captureParameterDefaults (
    const juce::AudioProcessorValueTreeState& state) noexcept;
[[nodiscard]] bool canonicalizeParameterValues (
    const juce::AudioProcessorValueTreeState& state,
    DeepPluckParameterValues& values) noexcept;
[[nodiscard]] bool applyParameterValues (
    juce::AudioProcessorValueTreeState& state,
    const DeepPluckParameterValues& values);
[[nodiscard]] bool parameterValuesMatch (
    const juce::AudioProcessorValueTreeState& state,
    const DeepPluckParameterValues& expected,
    float normalizedTolerance = 1.0e-5f) noexcept;
[[nodiscard]] int findParameterIndex (juce::StringRef parameterId) noexcept;
[[nodiscard]] bool setParameterValueNotifyingHost (
    juce::AudioProcessorValueTreeState& state,
    int parameterIndex,
    float rawValue);
}
