/// <summary>
        /// Determines whether a given logical position is within the configured active area determined by the given input margin.
        /// </summary>
        /// <param name="logicalPosition">The logical position to test.</param>
        /// <param name="inputMargin">The input margin to use to determine the active area.</param>
        /// <returns>
        ///   <c>true</c> if the logical position is within the active area; otherwise, <c>false</c>.
        /// </returns>
        public static bool IsInActiveArea(Vector2 logicalPosition, Thickness inputMargin)
        {
            if (inputMargin == null)
            {
                return true;
            }

            return logicalPosition.X - inputMargin.Left > 0 &&
                   logicalPosition.X + inputMargin.Right < DeviceInfo.Current.LogicalScreenWidth &&
                   logicalPosition.Y - inputMargin.Top > 0 &&
                   logicalPosition.Y + inputMargin.Bottom < DeviceInfo.Current.LogicalScreenHeight;
        }
 /// <summary>
 /// Initializes a new instance of the <see cref="ControllerConfiguration"/> class using default values for the configuration.
 /// </summary>
 public ControllerConfiguration()
 {
     // create default configuration values
     AutoReconnectOnActivation = false;
     TouchInputMargin = new Thickness(90, 20, 20, 20); // this is the default for the standard WP7 client so it can show the special buttons
     MinAccelerometerDataRate = 0;
     MinCompassDataRate = 0;
     MinGyroscopeDataRate = 0;
     MinMotionDataRate = 0;
     MinMillisecondsBetweenMessages = 0; // as fast as possible
     EnableTracing = false;
     TracingEndpointAddress = null;
 }
        /// <summary>
        /// Projects a logical position within the active area defined by the given margin to the full logical screen dimensions.
        /// The result is stored in the <paramref name="logicalPosition"/> that is passed into the method.
        /// </summary>
        /// <remarks>
        /// Example: 
        /// * The original logical horizontal position is 100
        /// * The left margin is 50
        /// * The right margin is 10
        /// * The logical screen width is 800.
        /// That means that the resulting active screen width is 800 - (50 + 10) = 740. The relative offset of the logical position
        /// then is (100 - 50) / 740 ~= 0.068. The resulting projected horizontal coordinate then is 800 * 0.068 = 54.4.
        /// </remarks>
        /// <param name="logicalPosition">The logical position to use.</param>
        /// <param name="inputMargin">The input margin that defines the active area.</param>
        public static void ProjectToActiveArea(Vector2 logicalPosition, Thickness inputMargin)
        {
            // get the logical screen dimensions
            var logicalScreenWidth = (float)DeviceInfo.Current.LogicalScreenWidth;
            var logicalScreenHeight = (float)DeviceInfo.Current.LogicalScreenHeight;

            // calculate the active screen dimensions
            var activeScreenWidth = logicalScreenWidth - (float)(inputMargin.Left + inputMargin.Right);
            var activeScreenHeight = logicalScreenHeight - (float)(inputMargin.Top + inputMargin.Bottom);

            // calculate the new coordinates
            var clampedX = Xna.MathHelper.Clamp(logicalPosition.X, (float)inputMargin.Left, logicalScreenWidth - (float)inputMargin.Right);
            var relativeX = (clampedX - (float)inputMargin.Left) / activeScreenWidth;
            logicalPosition.X = relativeX * logicalScreenWidth;

            var clampedY = Xna.MathHelper.Clamp(logicalPosition.Y, (float)inputMargin.Top, logicalScreenHeight - (float)inputMargin.Bottom);
            var relativeY = (clampedY - (float)inputMargin.Top) / activeScreenHeight;
            logicalPosition.Y = relativeY * logicalScreenHeight;
        }
 /// <summary>
 /// Deserializes the configuration from a given binary reader.
 /// </summary>
 /// <param name="br">The binary reader to use.</param>
 internal void Deserialize(BinaryReader br)
 {
     AutoReconnectOnActivation = br.ReadBoolean();
     MinMillisecondsBetweenMessages = br.ReadInt32();
     MinAccelerometerDataRate = br.ReadInt32();
     MinCompassDataRate = br.ReadInt32();
     MinGyroscopeDataRate = br.ReadInt32();
     MinMotionDataRate = br.ReadInt32();
     TouchInputMargin = new Thickness();
     TouchInputMargin.Left = br.ReadDouble();
     TouchInputMargin.Top = br.ReadDouble();
     TouchInputMargin.Right = br.ReadDouble();
     TouchInputMargin.Bottom = br.ReadDouble();
     EnableTracing = br.ReadBoolean();
     TracingEndpointAddress = br.ReadString();
 }