using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Assets.Scripts.Devices.Ant.LegacyPages
{
    public class RotationData
    {
        private static readonly TimeSpan TimeBeforeRollover = TimeSpan.FromSeconds(63.0);
        private const int MaxUpdateValue = 65535;
        private const int MaxCountValue = 65535;
        private int? _update;
        private int? _count;
        private DateTimeOffset? _lastUpdatedTime;
        private int _rpm;

        public int? CalculateRpm(DateTimeOffset now, int newUpdate, int newCount)
        {
            DateTimeOffset time = now;
            if (!this._lastUpdatedTime.HasValue)
            {
                this._update = new int?(newUpdate);
                this._count = new int?(newCount);
                this._lastUpdatedTime = new DateTimeOffset?(now);
                return new int?();
            }
            if (this.HasNotMoved(newUpdate, time))
                return new int?(0);
            if (this.HasMoreThanOneRolloverOccurred(time))
            {
                this._lastUpdatedTime = new DateTimeOffset?(time);
                this._update = new int?(newUpdate);
                this._count = new int?(newCount);
                return new int?();
            }
            if (this.HasNotUpdated(newUpdate))
                return new int?(this._rpm);
            if (this.HasUpdateRolledOver(newUpdate))
            {
                int? nullable = this._update;
                this._update = nullable.HasValue ? new int?(nullable.GetValueOrDefault() - (int)ushort.MaxValue) : new int?();
            }
            if (this.HasCountRolledOver(newCount))
            {
                int? nullable = this._count;
                this._count = nullable.HasValue ? new int?(nullable.GetValueOrDefault() - (int)ushort.MaxValue) : new int?();
            }
            this._rpm = (int)Math.Round((double)(newCount - this._count.Value) / (double)(newUpdate - this._update.Value) * 1024.0 * 60.0);
            this._lastUpdatedTime = new DateTimeOffset?(time);
            this._update = new int?(newUpdate);
            this._count = new int?(newCount);
            return new int?(this._rpm);
        }

        private bool HasMoreThanOneRolloverOccurred(DateTimeOffset time)
        {
            DateTimeOffset dateTimeOffset = time;
            DateTimeOffset? nullable1 = this._lastUpdatedTime;
            TimeSpan? nullable2 = nullable1.HasValue ? new TimeSpan?(dateTimeOffset - nullable1.GetValueOrDefault()) : new TimeSpan?();
            TimeSpan timeSpan = RotationData.TimeBeforeRollover;
            if (!nullable2.HasValue)
                return false;
            return nullable2.GetValueOrDefault() > timeSpan;
        }

        private bool HasCountRolledOver(int newCount)
        {
            int num = newCount;
            int? nullable = this._count;
            int valueOrDefault = nullable.GetValueOrDefault();
            if (num >= valueOrDefault)
                return false;
            return nullable.HasValue;
        }

        private bool HasUpdateRolledOver(int newUpdate)
        {
            int num = newUpdate;
            int? nullable = this._update;
            int valueOrDefault = nullable.GetValueOrDefault();
            if (num >= valueOrDefault)
                return false;
            return nullable.HasValue;
        }

        private bool HasNotUpdated(int newUpdate)
        {
            int num = newUpdate;
            int? nullable = this._update;
            int valueOrDefault = nullable.GetValueOrDefault();
            if (num != valueOrDefault)
                return false;
            return nullable.HasValue;
        }

        private bool HasNotMoved(int newUpdate, DateTimeOffset time)
        {
            DateTimeOffset dateTimeOffset = time - TimeSpan.FromSeconds(4.0);
            DateTimeOffset? nullable1 = this._lastUpdatedTime;
            if ((nullable1.HasValue ? (dateTimeOffset >= nullable1.GetValueOrDefault() ? 1 : 0) : 0) == 0)
                return false;
            int num = newUpdate;
            int? nullable2 = this._update;
            int valueOrDefault = nullable2.GetValueOrDefault();
            if (num != valueOrDefault)
                return false;
            return nullable2.HasValue;
        }
    }
}
