/// <summary>
        /// Processes a button click where the command can be cancelled by holding the button down for more than 2 seconds.
        /// </summary>
        private void ProcessDownAndUpButtonClick(GameControllerButtonMapping mapping, int stateValue, IProgress <GameControllerProgressArgs> progress)
        {
            long now = DateTime.Now.Ticks;
            GameControllerButtonCommandState history = _ButtomCommandHistory.Where(h => h.Command == mapping.Command).FirstOrDefault();

            if (history == null || history.Value != stateValue)
            {
                // Not seen the command or seen it and the state has changed
                if (stateValue >= 0)
                {
                    if (history == null) // Initial command down
                    {
                        _ButtomCommandHistory.Add(new GameControllerButtonCommandState(mapping.Command, stateValue));
                        progress.Report(new GameControllerProgressArgs(GameControllerUpdateNotification.CommandDown, mapping.Command));
                    }
                }
                else
                {
                    if (history != null)
                    {
                        // Remove history record
                        _ButtomCommandHistory.Remove(history);
                        progress.Report(new GameControllerProgressArgs(GameControllerUpdateNotification.CommandUp, mapping.Command));
                    }
                }
            }
        }
        /// <summary>
        /// Processes a button click where the command can be cancelled by holding the button down for more than 2 seconds.
        /// </summary>
        private void ProcessCancellableButtonClick(GameControllerButtonMapping mapping, int stateValue, IProgress <GameControllerProgressArgs> progress)
        {
            long now = DateTime.Now.Ticks;
            GameControllerButtonCommandState history = _ButtomCommandHistory.Where(h => h.Command == mapping.Command).FirstOrDefault();

            if (history == null || history.Value != stateValue)
            {
                // Not seen the command or seen it and the state has changed
                if (stateValue >= 0)
                {
                    if (history == null) // Initial command down
                    {
                        _ButtomCommandHistory.Add(new GameControllerButtonCommandState(mapping.Command, stateValue));
                        // progress.Report(new GameControllerProgressArgs(GameControllerUpdateNotification.CommandDown, mapping.Command));
                    }
                }
                else
                {
                    if (history != null)
                    {
                        if (now - history.Timestamp < 15E6) // Test to make sure that press is less than 1.5 seconds.Allows command to be cancelled by long hold.
                        {
                            progress.Report(new GameControllerProgressArgs(GameControllerUpdateNotification.CommandUp, mapping.Command));
                        }
                        // Remove history record
                        _ButtomCommandHistory.Remove(history);
                    }
                }
            }
        }
        private void ProcessPOVs(GameController controller, IEnumerable <JoystickUpdate> updates, IProgress <GameControllerProgressArgs> progress)
        {
            GameControllerPOVDirection  previousPOVDirection = GameControllerPOVDirection.UNMAPPED;
            GameControllerButtonMapping previousMapping      = null;

            foreach (JoystickUpdate state in updates)
            {
                if (_PreviousPOVState.Timestamp != 0)
                {
                    // Get previous stuff
                    previousPOVDirection = GameController.GetPOVDirection(_PreviousPOVState);
                    previousMapping      = controller.ButtonMappings.Where(m => m.JoystickOffset == _PreviousPOVState.Offset && m.POVDirection == previousPOVDirection).FirstOrDefault();
                }
                GameControllerPOVDirection povDirection = GameController.GetPOVDirection(state);
                if (povDirection == GameControllerPOVDirection.UNMAPPED)
                {
                    if (previousMapping != null)
                    {
                        ProcessButtonMapping(previousMapping, -1, progress);
                    }
                    _PreviousPOVState = new JoystickUpdate();
                }
                else
                {
                    if (povDirection != previousPOVDirection && previousPOVDirection != GameControllerPOVDirection.UNMAPPED)
                    {
                        // switch from one direction to another without coming up so need to UP the previous mapping.
                        ProcessButtonMapping(previousMapping, -1, progress);
                    }
                    GameControllerButtonMapping mapping = controller.ButtonMappings.Where(m => m.JoystickOffset == state.Offset && m.POVDirection == povDirection).FirstOrDefault();
                    ProcessButtonMapping(mapping, state.Value, progress);
                    _PreviousPOVState = state;
                }
            }
        }
        private void ProcessUpdate(JoystickUpdate update)
        {
            GameControllerButtonMapping unsetButtonMapping = null;
            GameControllerAxisMapping   unsetAxisMapping   = null;
            string name = "<Unknown>";

            _Controller.JoystickObjects.TryGetValue(update.Offset, out name);

            if (_CurrentSetting == GameControllerCurrentSetting.ButtonCommand && update.RawOffset >= 48 && update.RawOffset <= 175)
            {
                if (SelectedButtonMapping != null)
                {
                    SelectedButtonMapping.JoystickOffset = update.Offset;
                    SelectedButtonMapping.Name           = name;
                    unsetButtonMapping = Controller.ButtonMappings.Where(m => m.Command != SelectedButtonMapping.Command && m.JoystickOffset == update.Offset).FirstOrDefault();
                }
            }
            else if (_CurrentSetting == GameControllerCurrentSetting.ButtonCommand && update.RawOffset >= 32 && update.RawOffset <= 44) // POV controls
            {
                if (SelectedButtonMapping != null)
                {
                    GameControllerPOVDirection direction = GameController.GetPOVDirection(update);
                    if (direction != GameControllerPOVDirection.UNMAPPED)
                    {
                        SelectedButtonMapping.JoystickOffset = update.Offset;
                        SelectedButtonMapping.Name           = $"{name} ({direction})";
                        SelectedButtonMapping.POVDirection   = direction;
                        unsetButtonMapping = Controller.ButtonMappings.Where(m => m.Command != SelectedButtonMapping.Command && m.JoystickOffset == update.Offset && m.POVDirection == direction).FirstOrDefault();
                    }
                }
            }
            else if (update.RawOffset <= 20) // Axis
            {
                if (_CurrentSetting == GameControllerCurrentSetting.AxisCommand)
                {
                    if (SelectedAxisMapping != null)
                    {
                        SelectedAxisMapping.JoystickOffset = update.Offset;
                        SelectedAxisMapping.Name           = name;
                        unsetAxisMapping = Controller.AxisMappings.Where(m => m.Command != SelectedAxisMapping.Command && m.JoystickOffset == update.Offset).FirstOrDefault();
                    }
                }
            }

            if (unsetButtonMapping != null)
            {
                unsetButtonMapping.JoystickOffset = null;
                unsetButtonMapping.Name           = null;
                unsetButtonMapping.POVDirection   = GameControllerPOVDirection.UNMAPPED;
            }

            if (unsetAxisMapping != null)
            {
                unsetAxisMapping.Name             = null;
                unsetAxisMapping.JoystickOffset   = null;
                unsetAxisMapping.ReverseDirection = false;
            }
        }
 private void ProcessButtons(GameController controller, IEnumerable <JoystickUpdate> updates, IProgress <GameControllerProgressArgs> progress)
 {
     foreach (JoystickUpdate state in updates) // Just take the down clicks not the up.
     {
         GameControllerButtonMapping mapping = controller.ButtonMappings.Where(m => m.JoystickOffset == state.Offset).FirstOrDefault();
         // Need to change 0 (button up to -1) so that we can share the same processing methods as the POV.
         ProcessButtonMapping(mapping, (state.Value == 0 ? -1 : state.Value), progress);
     }
 }
        /// <summary>
        /// Processes a button click where it must be double clicked within second.
        /// </summary>
        private void ProcessDoubleClickButton(GameControllerButtonMapping mapping, int stateValue, IProgress <GameControllerProgressArgs> progress)
        {
            long now = DateTime.Now.Ticks;
            GameControllerButtonCommandState history = _ButtomCommandHistory.Where(h => h.Command == mapping.Command).FirstOrDefault();

            if (history == null)
            {
                // Not seen the command or seen it and the state has changed
                if (stateValue >= 0)
                {
                    _ButtomCommandHistory.Add(new GameControllerButtonCommandState(mapping.Command, stateValue));
                }
            }
            else
            {
                if (stateValue >= 0)
                {
                    if ((now - history.Timestamp) < 10E06) // Second click must be within 1 second
                    {
                        // Increment the history count
                        history.Increment();
                    }
                    history.Timestamp = now;
                }
                else
                {
                    // Button up
                    if (now - history.Timestamp >= 15E6) // Test to make sure that press is less than 1.5 seconds.Allows command to be cancelled by long hold.
                    {
                        // Remove history record
                        _ButtomCommandHistory.Remove(history);
                    }
                    else
                    {
                        if (history.Count > 0)
                        {
                            _ButtomCommandHistory.Remove(history);
                            progress.Report(new GameControllerProgressArgs(GameControllerUpdateNotification.CommandUp, mapping.Command));
                        }
                        else
                        {
                            // Update timestamp and value
                            history.Timestamp = now;
                            history.Value     = stateValue;
                        }
                    }
                }
            }
        }
        private void ProcessButtonMapping(GameControllerButtonMapping mapping, int stateValue, IProgress <GameControllerProgressArgs> progress)
        {
            if (mapping != null)
            {
                switch (mapping.Command)
                {
                case GameControllerButtonCommand.Sync:
                    ProcessDoubleClickButton(mapping, stateValue, progress);
                    break;

                case GameControllerButtonCommand.North:
                case GameControllerButtonCommand.South:
                case GameControllerButtonCommand.West:
                case GameControllerButtonCommand.East:
                    ProcessDownAndUpButtonClick(mapping, stateValue, progress);
                    break;

                default:
                    ProcessCancellableButtonClick(mapping, stateValue, progress);
                    break;
                }
            }
        }
 public void PushProperties()
 {
     _OriginalController.Name = _Controller.Name;
     foreach (GameControllerButtonMapping newMapping in _Controller.ButtonMappings)
     {
         GameControllerButtonMapping originalMapping = _OriginalController.ButtonMappings.Where(m => m.Command == newMapping.Command).FirstOrDefault();
         if (originalMapping != null)
         {
             originalMapping.JoystickOffset = newMapping.JoystickOffset;
             originalMapping.POVDirection   = newMapping.POVDirection;
             originalMapping.Name           = newMapping.Name;
         }
     }
     foreach (GameControllerAxisMapping newMapping in _Controller.AxisMappings)
     {
         GameControllerAxisMapping originalMapping = _OriginalController.AxisMappings.Where(m => m.Command == newMapping.Command).FirstOrDefault();
         if (originalMapping != null)
         {
             originalMapping.JoystickOffset   = newMapping.JoystickOffset;
             originalMapping.Name             = newMapping.Name;
             originalMapping.ReverseDirection = newMapping.ReverseDirection;
         }
     }
 }
 public void PopProperties()
 {
     _Controller = new GameController(_OriginalController.Id, _OriginalController.Name);
     foreach (GameControllerButtonMapping originalMapping in _OriginalController.ButtonMappings)
     {
         GameControllerButtonMapping newMapping = _Controller.ButtonMappings.Where(m => m.Command == originalMapping.Command).FirstOrDefault();
         if (newMapping != null)
         {
             newMapping.JoystickOffset = originalMapping.JoystickOffset;
             newMapping.POVDirection   = originalMapping.POVDirection;
             newMapping.Name           = originalMapping.Name;
         }
     }
     foreach (GameControllerAxisMapping originalMapping in _OriginalController.AxisMappings)
     {
         GameControllerAxisMapping newMapping = _Controller.AxisMappings.Where(m => m.Command == originalMapping.Command).FirstOrDefault();
         if (newMapping != null)
         {
             newMapping.JoystickOffset   = originalMapping.JoystickOffset;
             newMapping.Name             = originalMapping.Name;
             newMapping.ReverseDirection = originalMapping.ReverseDirection;
         }
     }
 }