public static InputState MixInput( InputState Keyboard, InputState Gamepad, InputState Kinect )
        {
            if ( Keyboard == null && Gamepad == null && Kinect == null)
            {
                return null;
            }
            else
            {
                if ( Keyboard == null )
                {
                    Keyboard = new InputState();
                }
                if ( Gamepad == null )
                {
                    Gamepad = new InputState();
                }
                if ( Kinect == null )
                {
                    Kinect = new InputState();
                }
                InputState MixedInput = new InputState();
                if ( Keyboard.CameraSwap || Gamepad.CameraSwap || Kinect.CameraSwap )
                    MixedInput.CameraSwap = true;
                if ( Keyboard.Emergency || Gamepad.Emergency || Kinect.Emergency )
                    MixedInput.Emergency = true;
                if ( Keyboard.FlatTrim || Gamepad.FlatTrim || Kinect.FlatTrim )
                    MixedInput.FlatTrim = true;
                if ( Keyboard.Hover || Gamepad.Hover || Kinect.Hover )
                    MixedInput.Hover = true;
                if ( Keyboard.Land || Gamepad.Land || Kinect.Land )
                    MixedInput.Land = true;
                if ( Keyboard.SpecialAction || Gamepad.SpecialAction || Kinect.SpecialAction )
                    MixedInput.SpecialAction = true;
                if ( Keyboard.TakeOff || Gamepad.TakeOff || Kinect.TakeOff )
                    MixedInput.TakeOff = true;

                if ( Gamepad.Gaz != 0 && (Keyboard.Gaz != 0 || Kinect.Gaz != 0) )
                {
                    MixedInput.Gaz = Gamepad.Gaz;
                }
                else if ( Keyboard.Gaz != 0 && Kinect.Gaz != 0 )
                {
                    MixedInput.Gaz = Keyboard.Gaz;
                }
                else
                {
                    MixedInput.Gaz += Kinect.Gaz;
                    MixedInput.Gaz += Keyboard.Gaz;
                    MixedInput.Gaz += Gamepad.Gaz;
                }

                if ( Gamepad.Pitch != 0 && (Keyboard.Pitch != 0 || Kinect.Pitch != 0) )
                {
                    MixedInput.Pitch = Gamepad.Pitch;
                }
                else if ( Keyboard.Pitch != 0 && Kinect.Pitch != 0 )
                {
                    MixedInput.Pitch = Keyboard.Pitch;
                }
                else
                {
                    MixedInput.Pitch += Kinect.Pitch;
                    MixedInput.Pitch += Keyboard.Pitch;
                    MixedInput.Pitch += Gamepad.Pitch;
                }

                if ( Gamepad.Roll != 0 && (Keyboard.Roll != 0 || Kinect.Roll != 0) )
                {
                    MixedInput.Roll = Gamepad.Roll;
                }
                else if ( Keyboard.Roll != 0 && Kinect.Roll != 0 )
                {
                    MixedInput.Roll = Keyboard.Roll;
                }
                else
                {
                    MixedInput.Roll += Kinect.Roll;
                    MixedInput.Roll += Keyboard.Roll;
                    MixedInput.Roll += Gamepad.Roll;
                }

                if ( Gamepad.Yaw != 0 && (Keyboard.Yaw != 0 || Kinect.Yaw != 0) )
                {
                    MixedInput.Yaw = Gamepad.Yaw;
                }
                else if (Keyboard.Yaw != 0 && Kinect.Yaw != 0)
                {
                    MixedInput.Yaw = Keyboard.Yaw;
                }
                else
                {
                    MixedInput.Yaw += Kinect.Yaw;
                    MixedInput.Yaw += Keyboard.Yaw;
                    MixedInput.Yaw += Gamepad.Yaw;
                }
                return MixedInput;
            }
        }
        public void MixInputAndProcess(InputState Keyboard,InputState Gamepad, InputState Kinect)
        {
            if ( Keyboard.Equals( Gamepad ) )
            {
                Process( Gamepad );
            }
            else
            {
                InputState MixedInput = MixInput( Keyboard, Gamepad, Kinect );
                if ( MixedInput != null )
                {
                    Process( MixedInput );
                }

            }
        }
        public RideOnMotion.Inputs.InputState GetCurrentControlInput(RideOnMotion.Inputs.InputState _lastInputState)
        {
            // TODO test

            if (roll != _lastInputState.Roll || pitch != _lastInputState.Pitch || yaw != _lastInputState.Yaw || gaz != _lastInputState.Gaz || cameraSwap != _lastInputState.CameraSwap || takeOff != _lastInputState.TakeOff ||
                land != _lastInputState.Land || hover != _lastInputState.Hover || emergency != _lastInputState.Emergency || flatTrim != _lastInputState.FlatTrim || specialActionButton != _lastInputState.SpecialAction)
            {
                RideOnMotion.Inputs.InputState newInputState = new RideOnMotion.Inputs.InputState(roll, pitch, yaw, gaz, cameraSwap, takeOff, land, hover, emergency, flatTrim, specialActionButton);
                return newInputState;
            }
            else
            {
                return null;
            }
        }
        /// <summary>
        /// Kinect sensor input controller.
        /// Handles drone control through a Kinect sensor.
        /// </summary>
        public KinectSensorController()
        {
            this.DepthImageEnabled = true;
            SetSkeletonSmoothingEnabled( false );

            int deviceCount = KinectSensor.KinectSensors.Count; // Blocking call (USB devices polling).

            TriggerButtons = new ObservableCollectionEx<ICaptionArea>();
            initTriggerZones( TRIGGER_BUTTON_WIDTH, TRIGGER_BUTTON_HEIGHT );

            this.InputMenu = PrepareInputMenuItem();
            this.InputStatusChanged += OnInputStatusChanged;

            _interactionClient = new InteractionClient();

            if ( deviceCount > 0 )
            {
                KinectSensor kinectSensor = KinectSensor.KinectSensors.Where( item => item.Status == KinectStatus.Connected ).FirstOrDefault();
                initializeKinectSensor( kinectSensor );
            }

            KinectSensor.KinectSensors.StatusChanged += sensors_StatusChanged;

            this._inputState = new InputState();

            this.InputUIControl = new KinectSensorControllerUI( this );
            ReleaseLeftHand.Interval = new TimeSpan( 0, 0, 2 );
            ReleaseLeftHand.Tick += new EventHandler( OnReleaseLeftHand );
            ReleaseRightHand.Interval = new TimeSpan( 0, 0, 2 );
            ReleaseRightHand.Tick += new EventHandler( OnReleaseRightHand );
        }
        /// <summary>
        /// Initializes the ViewModel with the given IDroneInputController.
        /// </summary>
        public MainWindowViewModel()
        {
            CreateDroneCommands();

            InputTypes = new List<Type>();
            InputTypes.Add( typeof( RideOnMotion.Inputs.Kinect.KinectSensorController ) );

            _logStrings = new ObservableCollection<string>();

            loadInputType( InputTypes[0] );

            mp1.Open( new Uri( "..\\..\\Resources\\Quack.wav", UriKind.Relative ) );
            mp2.Open( new Uri( "..\\..\\Resources\\Quack2.wav", UriKind.Relative ) );
            mp3.Open( new Uri( "..\\..\\Resources\\Quack3.wav", UriKind.Relative ) );
            mp4.Open( new Uri( "..\\..\\Resources\\Quack4.mp3", UriKind.Relative ) );

            initializeBindings();

            _lastKeyboardInput = new InputState();
            _lastGamepadInput = new InputState();
            _lastKinectInput = new InputState();
            _keyboardController = new KeyboardController();
            _Xbox360Gamepad = new Xbox360GamepadController();
            _Xbox360Gamepad.Start();
            _Xbox360Gamepad.StartMappingForDrone();
            ConnectDrone(this._currentDroneConfig); // At this point, should be default config.
            DroneOrderTimer.Interval = new TimeSpan( 0, 0, 0,0,30 );
            DroneOrderTimer.Tick += new EventHandler( OrderTheMotherfuckingDrone );
            DroneOrderTimer.Start();
        }
 private void OrderTheMotherfuckingDrone( object sender, EventArgs e )
 {
     InputState newKeyboardInput = _keyboardController.GetCurrentControlInput(_lastKeyboardInput);
     InputState newKinectInput = ((RideOnMotion.Inputs.Kinect.KinectSensorController)_inputController).GetCurrentControlInput(_lastKinectInput);
     InputState newGamepadInput = _Xbox360Gamepad.GetCurrentControlInput( _lastGamepadInput );
     if ( newGamepadInput != null || newKeyboardInput != null || newKinectInput != null)
     {
         if ( newKeyboardInput != null )
         {
             _lastKeyboardInput = newKeyboardInput;
         }
         if ( newGamepadInput != null )
         {
             _lastGamepadInput = newGamepadInput;
         }
         if ( newKinectInput != null )
         {
             _lastKinectInput = newKinectInput;
         }
         InputState MixedInput = SendDroneCommand.MixInput( _lastKeyboardInput, _lastGamepadInput, _lastKinectInput );
         if ( MixedInput != null )
         {
             _sendDroneCommand.Process( MixedInput );
         }
     }
 }