using System;
namespace NEG.Utils.Timing
{
    public class TimeMachine
    {
        private double time;
        public TimeMachine()
        {
            time = 0;
        }
        /// 
        /// Adds time into the TimeMachine
        /// 
        /// Amount of time to be added
        public void Accumulate(double time) 
        {
            this.time += time;
        }
        /// 
        /// Retrieves given amount of time from the TimeMachine
        /// 
        /// 
        /// Amount of time retrievend
        public double Retrieve(double maxTime) 
        {
            if(!Double.IsFinite(maxTime))
            {
                double timeRetrieved = time;
                time = 0;
                return timeRetrieved;
            }
            double timeLeft = time - maxTime;
            time = Math.Max(timeLeft, 0);
            return Math.Min(maxTime + timeLeft, maxTime);
        }
        /// 
        /// Attempts to retrieves given amount of time from the TimeMachine 
        /// If there is enough  accumulated in this machine subtructs that amount and returns true, otherwise returns false
        /// 
        /// 
        public bool TryRetrieve(double time)
        {
            if (this.time >= time)
            {
                this.time -= time;
                return true;
            }
            return false;
        }
        /// 
        /// Result is equivalent to calling  as many times as possible, but is faster for larger  values
        /// 
        /// Single unit of warp time, must be positive/param>
        /// Maximum amount of warps, must be positive
        /// Amount of warps
        public int RetrieveAll(double interval, int limit = int.MaxValue)
        {
            int result = Mathf.FloorToInt(time / interval);
            result = Math.Clamp(result, 0, limit);
            time -= result * interval;
            return result;
        }
    }
}