#ifndef Foundation_Math_RunningAverage_INCLUDED
#define Foundation_Math_RunningAverage_INCLUDED

#include <foundation/TnTypes.h>
#include <foundation/SharedArray.h>

namespace Tn {

namespace math {

template <typename T>
struct RunningAverage {

    RunningAverage(size_t size, T init = T(0)) :
        size(size),
        sum(init * size),
        array(new T[size]),
        index(0)
    {
        for (uint32_t i = 0; i < size; ++i) {
            array[i] = init;
        }
    }


    RunningAverage(RunningAverage const & that) :
    size(that.size),
    sum(that.sum),
    array(that.array),
    index(that.index)
    {
    }


    RunningAverage & operator=(RunningAverage const & that) {

        size = that.size;
        sum = that.sum;
        array = that.array;
        index = that.index;
    }


    void push(T v) {
        sum -= array[index];
        array[index] = v;
        sum += array[index];
        if (++index >= size) index = 0;
    }


    T get() const {
        return sum / T(size);
    }

private:


    size_t size;
    T sum;
    Tn::Foundation::shared_array<T> array;
    uint32_t index;
};


} // namespace math

} // namespace Tn


#endif
