public SerializableCursorPath(SerializablePoint destination, SerializableRectangle bounds,
                               int MouseDownTime, int[][] path)
 {
     this.Destination   = destination;
     this.Bounds        = bounds;
     this.MouseDownTime = MouseDownTime;
     this.Path          = path;
 }
        public SerializableCursorPath GetRandomSuitablePath(int dx, int dy)
        {
            const double INITIAL_TOLERANCE      = 0.5;
            const double MAX_TOLERANCE          = 4.0;
            const int    MAX_LOOPS              = 100;
            const int    MINIMUM_SUITABLE_PATHS = 10;

            IEnumerable <SerializableCursorPath> SuitablePaths = null;

            SerializablePoint Destination = new SerializablePoint(dx, dy);

            double tolerance = INITIAL_TOLERANCE;

            int i = 0;

            do
            {
                if (i > MAX_LOOPS)
                {
                    throw new Exception("Not enough suitable paths found");
                }

                SuitablePaths = Paths.Where(p =>
                                            p.Destination.IsTolerant(Destination, tolerance));

                tolerance *= 1.5;
                i++;
            } while (SuitablePaths.Count() < MINIMUM_SUITABLE_PATHS &&
                     !(tolerance > MAX_TOLERANCE && SuitablePaths.Count() > 0));
            // (tolerance <= MAX_TOLERANCE || SuitablePaths.Count == 0)
            // SuitablePaths.Count == 0 || (SuitablePaths.Count() < MINIMUM_SUITABLE_PATHS)

            // select a random SuitablePath
            return(SuitablePaths.ElementAt(
                       RandomGenerator.NextInt(SuitablePaths.Count())));
        }
        bool MouseEvent(Point p, MouseEventIdentifier id, uint timestamp)
        {
            const double MOUSE_DRAG_LIMIT = 5.0; // 5 pixels

            if (timestamp - previous_timestamp > 1000)
            {
                // this automatically disqualifies the first path as well
                disqualified = true;
            }

            switch (id)
            {
            case MouseEventIdentifier.LeftUp:
            case MouseEventIdentifier.RightUp:
                SerializablePoint relative_p =
                    new SerializablePoint(p.X - origin_x, p.Y - origin_y);

                // limits amount of pixels the cursor can drag while pressed
                if (!disqualified && mouse_down_pos.DistanceTo(relative_p) < MOUSE_DRAG_LIMIT)
                {
                    CurrentPath.Add(new int[] {
                        (int)(timestamp - origin_timestamp), // relative_time
                        relative_p.X,                        // relative_x
                        relative_p.Y                         // relative_y
                    });
                    Paths.Add(new SerializableCursorPath(
                                  mouse_down_pos, bounds, mouse_down_relative_time,
                                  CurrentPath.ToArray()));
                }
                ResetPath();

                break;

            default:
                // check if first move, init origins
                if (CurrentPath.Count() == 0)
                {
                    origin_timestamp = timestamp;
                    origin_x         = p.X;
                    origin_y         = p.Y;
                }

                int relative_time = (int)(timestamp - origin_timestamp);
                int relative_x    = p.X - origin_x;
                int relative_y    = p.Y - origin_y;

                if (id == MouseEventIdentifier.LeftDown || id == MouseEventIdentifier.RightDown)
                {
                    mouse_down_relative_time = relative_time;
                    mouse_down_pos           = new SerializablePoint(relative_x, relative_y);
                }

                bounds.PushBounds(relative_x, relative_y);

                // record data relative to start position and time
                CurrentPath.Add(new int[] { relative_time, relative_x, relative_y });
                break;
            }

            previous_timestamp = timestamp;
            return(false); // don't block mouse input events from going to other applications
        }
 public bool Contains(Point point)
 {
     return(Contains(SerializablePoint.FromPoint(point)));
 }
 public bool Contains(SerializablePoint point)
 {
     return(Left <= point.X && point.X <= Right &&
            Top <= point.Y && point.Y <= Bottom);
 }
 public double DistanceTo(SerializablePoint b)
 {
     return(DistanceTo(b.X, b.Y));
 }
 public bool IsTolerant(SerializablePoint other, double tolerance)
 {
     return(AreDimensionsTolerant(this.X, other.X, tolerance) &&
            AreDimensionsTolerant(this.Y, other.Y, tolerance));
 }