using System.Collections.Generic;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Graphics;

namespace GhostArena3D
{
    class ControlsScreen : MenuScreen
    {
        private string[] _items;
        private int[] _selectedIndices;

        private bool _leftArrowDown = false;
        private bool _rightArrowDown = false;

        private float _leftArrowDownTime = 0.0f;
        private float _rightArrowDownTime = 0.0f;

        private List<MappedAction> _actions;

        public ControlsScreen() : base("")
        {
        }

        public override void LoadContent()
        {
            //get the current configuration and load the menu
            _actions = ((IInputSystem)ScreenManager.Game.Services.GetService(typeof(IInputSystem))).MappedActions;

            _selectedIndices = new int[_actions.Count];

            int count = 0;

            foreach (MappedAction action in _actions)
            {
                MenuEntries.Add(new MenuEntry(action.Name + ": "));
                _selectedIndices[count] = (int)action.ActionControl;
                count++;
            }

            MenuEntries.Add(new MenuEntry("Back"));

            //populate items array with all available controls
            _items = new string[System.Enum.GetNames(typeof(Control)).Length];

            count = 0;

            //Loop through Keys enum
            foreach (int value in System.Enum.GetValues(typeof(Control)))
            {
                _items[count] = System.Enum.GetName(typeof(Control), value);
                count++;
            }

        }

        public override void Update(GameTime gameTime, bool otherScreenHasFocus,
                                                       bool coveredByOtherScreen)
        {
            base.Update(gameTime, otherScreenHasFocus, coveredByOtherScreen);

            int count = 0;
            string entry;

            for (count = 0; count < _actions.Count;count++ )
            {
                entry = _actions[count].Name + ": " + _items[_selectedIndices[count]];
                MenuEntries[count] = new MenuEntry(entry);
            }
        }

        protected override void OnSelectEntry(int entryIndex)
        {
            //increment and check item
            if (entryIndex == (MenuEntries.Count - 1))
            {
                // Go back to the main menu.
                ExitScreen();
            }
        }

        protected void OnArrowUp(Keys arrow, int entryIndex)
        {
            int index = _selectedIndices[entryIndex]++;

            switch (arrow)
            {
                case Keys.Left:

                    index--;

                    if (index < 0)
                        index = _items.Length - 1;

                    break;

                case Keys.Right:
                    index++;

                    if (index > _items.Length - 1)
                        index = 0;

                    break;
            }

            _selectedIndices[entryIndex] = index;
            
        }

        protected void OnArrowDown(Keys arrow, int entryIndex, GameTime gameTime)
        {
            int index = _selectedIndices[entryIndex]++;

            switch (arrow)
            {

                case Keys.Left:

                    if (_leftArrowDown)
                    {
                        _leftArrowDownTime += gameTime.ElapsedGameTime.Milliseconds;

                        if (_leftArrowDownTime > 250.0f)
                        {
                            index--;
                            _leftArrowDownTime = 0.0f;
                        }
                    }
                    else
                    {
                        _leftArrowDown = true;
                        _leftArrowDownTime = 0.0f;
                    }

                    break;

                case Keys.Right:

                    if (_rightArrowDown)
                    {
                        _rightArrowDownTime += gameTime.ElapsedGameTime.Milliseconds;

                        if (_rightArrowDownTime > 250.0f)
                        {
                            index++;
                            _rightArrowDownTime = 0.0f;
                        }
                    }
                    else
                    {
                        _rightArrowDown = true;
                        _rightArrowDownTime = 0.0f;
                    }

                    break;

            }

            if (index < 0)
                index = _items.Length - 1;
            else if (index == _items.Length)
                index=0;

            _selectedIndices[entryIndex] = index;

        }

        protected override void OnCancel()
        {
            ExitScreen();
        }

        public override void ExitScreen()
        {
            //save the controls configuration
            MappedAction action;

            for (int count = 0; count < _actions.Count; count++)
            {
                action = _actions[count];
                action.ActionControl = (Control)_selectedIndices[count];
            }

            ((IInputSystem)ScreenManager.Game.Services.GetService(typeof(IInputSystem))).MappedActions = _actions;

            base.ExitScreen();
        }

    }
}
