using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework.Input;
using MonoGame.FourEngine.Extensions;

namespace MonoGame.FourEngine.Services
{
    public class BasicKeyboardControl : IKeyboardControl
    {
        protected static readonly TimeSpan RepeatTime = TimeSpan.FromMilliseconds(500);

        public IReadOnlyDictionary<Keys, KeyState> State { get; }

        private IDictionary<Keys, TimeSpan> _repeat;

        public BasicKeyboardControl()
        {
            State = Enum
                .GetValues(typeof(Keys))
                .Cast<Keys>()
                .ToDictionary(x => x, x => new KeyState())
                .ToReadOnly();
            _repeat = State.Keys
                .ToDictionary(x => x, x => TimeSpan.Zero);
        }

        public void Update(TimeSpan deltaTime)
        {
            foreach (var state in State.Values.Where(x => x.WasPressed))
            {
                state.WasPressed = false;
            }
            foreach (var state in State.Values.Where(x => x.IsPressed))
            {
                state.WasPressed = true;
                state.IsPressed = false;
                state.ClickCancellable.Reset();
            }
            var pressedKeys = RetrievePressedKeys();
            foreach (var key in pressedKeys)
            {
                if (State.ContainsKey(key))
                {
                    State[key].IsPressed = true;
                    _repeat[key] += deltaTime;
                    if (_repeat[key] >= RepeatTime)
                    {
                        _repeat[key] = TimeSpan.Zero;
                        State[key].WasPressed = false;
                    }
                }
            }
            foreach (var state in State.Where(x => !x.Value.IsPressed && x.Value.WasPressed))
            {
                _repeat[state.Key] = TimeSpan.Zero;
            }
        }

        protected virtual IEnumerable<Keys> RetrievePressedKeys()
        {
            return Keyboard.GetState().GetPressedKeys();
        }
    }
}