using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using SFML.Graphics;
using SlimDX.XInput;

namespace YourBeatingHeart.Main.Effects
{
    public class ControllerVibration
    {
        public static UserIndex IdToUserIndex(uint id)
        {
            switch (id)
            {
                case 0:
                    return UserIndex.One;
                case 1:
                    return UserIndex.Two;
                case 2:
                    return UserIndex.Three;
                case 3:
                    return UserIndex.Four;
                default:
                    throw new Exception("Unknown Gamepad Id: " + id);
            }
        }

        public class Animation
        {
            public float[] Values;
            public bool Repeat;
            public float SpeedMultiplier;
            public bool Important;

            public Animation(float[] values, bool repeat, bool important, float speedMultiplier)
            {
                Values = values;
                Repeat = repeat;
                Important = important;
                SpeedMultiplier = speedMultiplier;
            }
        }

        private Controller controller;

        private Dictionary<string, Animation> animations;
        private string currentAnimationName;
        private Animation currentAnimation;

        public float CurrentMultiplier { get; set; }
        public float CurrentSpeed { get; set; }
        public float CurrentIndex { get; set; }

        public ControllerVibration(uint gamepadId)
        {
            controller = new Controller(IdToUserIndex(gamepadId));

            animations = new Dictionary<string, Animation>();

            StopAnimation();
        }

        public void AddAnimation(string name, Animation animation)
        {
            animations[name] = animation;
        }


        public void SetVibration(float left, float right)
        {
            try
            {
                /*
                if (!controller.IsConnected)
                    return;
                 */

                var vibration = new Vibration();
                vibration.LeftMotorSpeed = (ushort) (ushort.MaxValue * left);
                vibration.LeftMotorSpeed = (ushort) (ushort.MaxValue * right);
                controller.SetVibration(vibration);
            }
            catch
            {
            }
        }

        public void StopVibration()
        {
            SetVibration(0, 0);
            StopAnimation();
        }

        public void StopAnimation()
        {
            if (!IsPlayingAnimation)
                return;

            currentAnimationName = "";
            currentAnimation = null;
            CurrentIndex = 0;
            StopVibration();
        }

        public void PlayAnimation(string name, float speedMultiplier = 1f)
        {
            if (name == currentAnimationName)
                return;

            if (IsPlayingAnimation && currentAnimation.Important)
                return;

            if (name == "")
            {
                StopAnimation();
                return;
            }

            currentAnimationName = name;
            currentAnimation = animations[currentAnimationName];
            CurrentSpeed = speedMultiplier;
            CurrentIndex = 0;
        }

        public void Update(float elapsedTime)
        {
            if (!IsPlayingAnimation)
                return;

            CurrentIndex += elapsedTime * CurrentSpeed * currentAnimation.SpeedMultiplier;
            while ((int)CurrentIndex >= currentAnimation.Values.Length)
            {
                CurrentIndex -= currentAnimation.Values.Length;
            }

            var value = currentAnimation.Values[(int)CurrentIndex] * CurrentMultiplier;
            SetVibration(value, value);
        }

        public bool IsPlayingAnimation { get { return currentAnimation != null; } }
    }
}
