#if USING_XBOX_PAD

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Input;
using GTA;

namespace NomeScripts
{
//    public delegate void InputDelegate();

    public class X360Pad
    {
        // Current gamepad state.
        public GamePadState CurrentState 
        { 
            get { return currentState; }
        }

        public Dictionary<Buttons[], InputDelegate> ButtonMapping
        {
            get { return buttonMapping; }
        }

        Dictionary<Buttons[], InputDelegate> buttonMapping;
        ControllerParser controllerParser;

        GamePadState currentState;
        int connectedPort = -1;

        public X360Pad(int portToConnect)
        {
            controllerParser = new ControllerParser();
            buttonMapping = new Dictionary<Buttons[], InputDelegate>();
            
            switch (portToConnect)
            {
                case 1 :
                    if (GamePad.GetState(PlayerIndex.One).IsConnected)
                    {
                        // Get state of the pad in Port one
                        currentState = GamePad.GetState(PlayerIndex.One);
                        connectedPort = portToConnect;
                    }
                    break;
                case 2 :
                    if (GamePad.GetState(PlayerIndex.Two).IsConnected)
                    {
                        // Get state of the pad in Port two
                        currentState = GamePad.GetState(PlayerIndex.Two);
                        connectedPort = portToConnect;
                    }
                    break;
                case 3 :
                    if (GamePad.GetState(PlayerIndex.Three).IsConnected)
                    {
                        // Get state of the pad in Port three
                        currentState = GamePad.GetState(PlayerIndex.Three);
                        connectedPort = portToConnect;
                    }
                    break;
                case 4 :
                    if (GamePad.GetState(PlayerIndex.Four).IsConnected)
                    {
                        // Get state of the pad in Port four
                        currentState = GamePad.GetState(PlayerIndex.Four);
                        connectedPort = portToConnect;
                    }
                    break;
                default:
                    Game.Console.Print("X360Pad : Port " + portToConnect.ToString() + " is not Connected");
                    portToConnect = -1;
                    break;
            }
        }

        /**
         * <summary>
         * Pass the name of the action(s) you want to load the buttons for, this is the name found in
         * the .ini file under the [Controls-XBOX360] section. It associates that action with the given
         * method in the KeyValuePair[]
         * </summary>
         */
        public bool LoadButtons(IniFile settings, params KeyValuePair<String, InputDelegate>[] buttons)
        {
            foreach (KeyValuePair<String, InputDelegate> pair in buttons)
            {
                Buttons[] buttonArr = controllerParser.MapButtons(settings, "Controls-XBOX360", pair.Key);

                for (int i = 0; i < buttonArr.Length; ++i)
                {
                    if (!controllerParser.CheckButtonIsValid(buttonArr[i]))
                    {
                        return false;
                    }
                }

                buttonMapping.Add(buttonArr, pair.Value);
            }

            return true;
        }

        /**
         * <summary>
         * Pass an array of xbox buttons to be associated with a delegate, to be used for loading default values
         * </summary>
         */
        public bool LoadButtons(params KeyValuePair<Buttons[], InputDelegate>[] buttons)
        {
            foreach (KeyValuePair<Buttons[], InputDelegate> pair in buttons)
            {
                for (int i = 0; i < pair.Key.Length; ++i)
                {
                    if (!controllerParser.CheckButtonIsValid(pair.Key[i]))
                    {
                        return false;
                    }
                }

                buttonMapping.Add(pair.Key, pair.Value);
            }

            return true;
        }

        private void UpdatePadState()
        {
            switch (connectedPort)
            {
                case 1:
                    // Get state of the pad in Port one
                    currentState = GamePad.GetState(PlayerIndex.One);
                    break;
                case 2:
                    // Get state of the pad in Port two
                    currentState = GamePad.GetState(PlayerIndex.Two);
                    break;
                case 3:
                    // Get state of the pad in Port three
                    currentState = GamePad.GetState(PlayerIndex.Three);
                    break;
                case 4:
                    // Get state of the pad in Port four
                    currentState = GamePad.GetState(PlayerIndex.Four);
                    break;
                default:
                    Game.Console.Print("X360Pad: Cannot get state of controller");
                    break;
            }
        }

        /**
         * <summary>
         * Check for input from the controller, if the correct button or button are pressed it will call the respective method
         * Returns a bool as to whether of not the controller is being used
         * <\summary>
         */
        public bool UpdateInput()
        {
            bool allButtonsArePressed = false;

            // Check its still connected
            if (CurrentState.IsConnected)
            {
                // Get the current gamepad state.
                UpdatePadState();

                // Check each array of buttons in the keylist
                foreach (Buttons[] buttonArr in buttonMapping.Keys)
                {
                    allButtonsArePressed = false;
                    
                    foreach (Buttons button in buttonArr)
                    {
                        if (CurrentState.IsButtonDown(button))
                        {
                            allButtonsArePressed = true;
                        } else {
                            allButtonsArePressed = false;
                            break;
                        }
                    }
                    
                    // Check all buttons in the button array are being pressed
                    if (allButtonsArePressed)
                    {
                        // Call method associated with this button press
                        buttonMapping[buttonArr]();
                        return allButtonsArePressed;
                    }
                }
            }

            return allButtonsArePressed;
        }
    }
}
#endif