// SPDX-FileCopyrightText: 2026 0064ff
// SPDX-License-Identifier: MIT-0

#pragma once
#include <JuceHeader.h>

//==============================================================================

template <typename FloatType, typename SmoothingType = juce::ValueSmoothingTypes::Linear>
class MySmoothedValue : public juce::SmoothedValue<FloatType, SmoothingType>
{
public:
    //==============================================================================

    using BaseClass = juce::SmoothedValue<FloatType, SmoothingType>;

    /** Sets maximum and minimum possible values to return when advancing the smoother. Necessary for multiplicative smoothing. */
    void setRange(FloatType minValue, FloatType maxValue) noexcept
    {
        jassert(minValue <= maxValue);

        minOut = minValue;
        maxOut = maxValue;
    }

    /** Advances the smoother and returns the next value. */
    FloatType getNextValueClamped() noexcept
    {
        // multiplicative smoothing will sometimes go out of bounds, especially with floats, so it needs to be clamped
        return std::clamp(BaseClass::getNextValue(), minOut, maxOut);
    }

    /** Combo function for setting a target value and skipping x amount of samples. */
    FloatType setTargetAndSkip(FloatType targetValue, int numSamplesToSkip=1) noexcept
    {
        BaseClass::setTargetValue(targetValue);

        // multiplicative smoothing will sometimes go out of bounds, especially with floats, so it needs to be clamped
        return std::clamp(BaseClass::skip(numSamplesToSkip), minOut, maxOut);
    }

    //==============================================================================
private:
    FloatType minOut = std::numeric_limits<FloatType>::lowest();
    FloatType maxOut = std::numeric_limits<FloatType>::max();
};
