using FishNet.Documenting;
using System;
using UnityEngine;
namespace FishNet.Managing.Timing
{
    [APIExclude]
    public class MovingAverage
    {
        #region Public.
        /// 
        /// Average from samples favoring the most recent sample.
        /// 
        public float Average { get; private set; }
        #endregion
        /// 
        /// Next index to write a sample to.
        /// 
        private int _writeIndex;
        /// 
        /// Collected samples.
        /// 
        private float[] _samples;
        /// 
        /// Number of samples written. Will be at most samples size.
        /// 
        private int _writtenSamples;
        /// 
        /// Samples accumulated over queue.
        /// 
        private float _sampleAccumulator;
        public MovingAverage(int sampleSize)
        {
            if (sampleSize < 0)
                sampleSize = 0;
            else if (sampleSize < 2)
                NetworkManager.StaticLogWarning("Using a sampleSize of less than 2 will always return the most recent value as Average.");
            _samples = new float[sampleSize];
        }
        /// 
        /// Computes a new windowed average each time a new sample arrives
        /// 
        /// 
        public void ComputeAverage(float newSample)
        {
            if (_samples.Length <= 1)
            {
                Average = newSample;
                return;
            }
            _sampleAccumulator += newSample;
            _samples[_writeIndex] = newSample;
            //Increase writeIndex.
            _writeIndex++;
            _writtenSamples = Math.Max(_writtenSamples, _writeIndex);
            if (_writeIndex >= _samples.Length)
                _writeIndex = 0;
            Average = _sampleAccumulator / _writtenSamples;
            /* If samples are full then drop off
            * the oldest sample. This will always be
            * the one just after written. The entry isn't
            * actually removed from the array but will
            * be overwritten next sample. */
            if (_writtenSamples >= _samples.Length)
                _sampleAccumulator -= _samples[_writeIndex];
        }
    }
}