private static void OnChannelValueSetReceived(RemoteSystemSessionMessageChannel sender, RemoteSystemSessionValueSetReceivedEventArgs args)
        {
            DebugString($"Received Message {args.Sender.RemoteSystem.DisplayName}: {args.Sender.GetHostNames()[0]}");
            var messageTypeString = args.Message["Type"] as string;

            switch (messageTypeString)
            {
            case "PositionData":
                var dragPosition = float.Parse(args.Message["DragPosition"].ToString());
                PositionDataUpdated?.Invoke(sender, dragPosition);
                break;

            case "MediaData":
                var cardJson            = args.Message["CardJson"].ToString();
                var mediaPlayedPosition = TimeSpan.Parse(args.Message["MediaPlayedPosition"].ToString());
                var mediaUrl            = args.Message["MediaUrl"].ToString();
                MediaDataUpdated?.Invoke(sender, new MediaDataEventArgs(cardJson, mediaPlayedPosition, mediaUrl));
                break;
            }
        }
        private void Kinect_OnTrackedBody(object sender, BodyEventArgs e)
        {
            Body body = e.BodyData;

            if (Mode == ControlMode.Disabled)
            {
                return;
            }

            for (int i = 1; i >= 0; i--) // Starts looking from right hand.
            {
                bool isLeft = i == 0;
                if (body.IsHandLiftForward(isLeft))
                {
                    if (usedHandIndex == -1)
                    {
                        usedHandIndex = i;
                    }
                    else if (usedHandIndex != i)
                    {
                        // In two-hand control mode, non-used hand would be used for pressing/releasing mouse button.
                        if (Mode == ControlMode.MoveGripPressing)
                        {
                            DoMouseControlByHandState(i, body.GetHandState(isLeft));
                        }

                        continue;
                    }

                    MVector2 handPos   = body.GetHandRelativePosition(isLeft);
                    MVector2 targetPos = cursorMapper.GetSmoothedOutputPosition(handPos);

                    MouseControl.MoveTo(targetPos.X, targetPos.Y);

                    if (Mode == ControlMode.GripToPress)
                    {
                        MouseControlState state = DoMouseControlByHandState(i, body.GetHandState(isLeft));
                        Data d = new Data(targetPos.X, targetPos.Y, state, body);
                        if (task_num != 0)
                        {
                            DataCollector.CollectData(d);
                        }
                        PositionDataUpdated?.Invoke(this, d);
                    }
                    else if (Mode == ControlMode.HoverToClick)
                    {
                        if ((targetPos - lastCursorPos).Length() > HoverRange)
                        {
                            ToggleHoverTimer(false);
                            hoverClicked = false;
                        }

                        lastCursorPos = targetPos;
                    }
                }
                else
                {
                    if (usedHandIndex == i)
                    {
                        // Reset to none.
                        usedHandIndex = NONE_USED;
                        ReleaseGrip(i);
                    }
                    else if (Mode == ControlMode.MoveLiftClicking)
                    {
                        DoMouseClickByHandLifting(i, body.GetHandRelativePosition(isLeft));
                        //System.Diagnostics.Trace.WriteLine(body.GetHandRelativePosition(isLeft).Y);
                    }
                    else // Release mouse button when it's not regularly released, such as hand tracking lost.
                    {
                        ReleaseGrip(i);
                    }
                }
            }

            ToggleHoverTimer(Mode == ControlMode.HoverToClick && usedHandIndex != -1);
        }