#ifndef _PARAHELPER_CORE_H
#define _PARAHELPER_CORE_H

/// \brief 定义整形、浮点型参数的缺省值和取值范围，类型T可以为8/16/32/64位的有符号或无符号数、float/double。
template <typename T>
struct sParaRange
{
    /// 默认构造后不能直接使用，必须正确设置Def/Min/Max参数才能使用
    sParaRange() = default;

    /// 带所有参数测构造函数。当所有参数都是常数或constexpr时，构造的实例可以是constexpr
    constexpr sParaRange(const T &def, const T & min, const T & max, const T& step=1, int dec=2)
        : Def(def), Min(min), Max(max), Step(step)
        , Decimal(dec)
    {
    }

    /// 必须设的参数：缺省值, 最小值, 最大值。默认构造为0是没法使用的
    T Def=0, Min=0, Max=0;

    /// 可选设置的参数：在UI控件中调整参数的步进值，默认为1
    T Step=1;

    /// 小数位数，仅用于float/double浮点型数据，整形数据忽略此项
    int Decimal=2;

    /// 判断输入参数是否在[Min, Max]范围内
    bool inRange(const T & val) const {
        return (val>=Min && val <= Max);
    }

    /// @brief 校验参数，如果小于Min设置为Min，大于Max设置为Max
    bool verify(T& val) const {
        if (val < Min)      { val = Min; return false; }
        else if (val > Max) { val = Max; return false; }
        else return true;
    }

	/// @brief 校验参数，如果小于Min设置为Min，大于Max设置为Max
	/// @param err 误差值，多用于浮点数比较
	bool verify(T& val, const T err) const {
		if (val < Min-err) { val = Min; return false; }
		else if (val > Max+err) { val = Max; return false; }
		else return true;
	}

    /// @brief 校验参数，如果超出范围，设置为缺省值
    bool verifyToDefault(T& val) const{
        if (val <Min || val > Max) { val = Def; return false;}
        else return true;
    }

	/// @brief 校验参数，如果超出范围，设置为缺省值
	bool verifyToDefault(T& val, const T err) const {
		if (val <Min-err || val > Max+err) { val = Def; return false; }
		else return true;
	}

	sParaRange operator+(T d) const
    {
        return sParaRange(Def + d, Min + d, Max + d, Step, Decimal);
    }

    sParaRange operator-(T d) const
    {
        return sParaRange(Def - d, Min - d, Max - d, Step, Decimal);
    }
};

#endif
