private void InitializeMouseEventHandlers()
        {
            OnCircleMouseLeftButtonDown = (s, args) =>
            {
                if (_currentMode == Mode.Default)
                {
                    var c = s as Circle;
                    c.Opacity = MovingOpacity;
                    Mouse.Capture(c.UIElements.Where(x => x is Ellipse).FirstOrDefault() as UIElement);
                }
                else if (_currentMode == Mode.Delete)
                {
                    var c = s as Circle;
                    canvas.Children.Remove(c);
                    graph.RemoveNode(_circleNodeMap[c]);
                    _circles.Remove(c);
                    _circleNodeMap.Remove(c);
                    c.Dispose();
                }
                else if (_currentMode == Mode.Send)
                {
                    var start = s as Circle;
                    start.Fill = CommunicatingCircleFill.Clone();
                    _tempLine  = new Shapes.Line(start,
                                                 Circle.Empty,
                                                 new SolidColorBrush(Colors.Red),
                                                 new SolidColorBrush(Colors.Red),
                                                 MovingOpacity, LineThickness, SendLineDashLength);
                    canvas.Children.Add(_tempLine);
                }
            };
            OnCircleMouseLeftButtonUp = (s, args) =>
            {
                if (_currentMode == Mode.Default)
                {
                    var c = s as Circle;
                    Mouse.Capture(null);
                    c.Opacity = StationaryOpacity;
                    if (!_circleNodeMap.ContainsKey(c))
                    {
                        var node = new Node <string>(c.Text);
                        _circleNodeMap.Add(c, node);
                        _circles.Add(c);
                        graph.AddNode(node);
                    }
                }
                else if (_currentMode == Mode.Send)
                {
                    var c = s as Circle;
                    if (_tempLine == null || _tempLine.Start == c)
                    {
                        return;
                    }
                    ResetCircleStyle(_tempLine.Start);
                    ResetCircleStyle(c);
                    // send a packet from _tempLine.Start to _tempLine.End
                    var startNode = _circleNodeMap[_tempLine.Start];
                    var endNode   = _circleNodeMap[c];
                    try
                    {
                        var path  = graph.FindShortestPath(startNode, endNode).ToArray();
                        var lines = new List <Shapes.Line>();
                        for (int i = 0; i < path.Length - 1; i++)
                        {
                            var line = _lineNodeMap.Where(x => (x.Value.Item1 == path[i] && x.Value.Item2 == path[i + 1]) ||
                                                          (x.Value.Item1 == path[i + 1] && x.Value.Item2 == path[i])
                                                          )
                                       .Select(x => x.Key)
                                       .FirstOrDefault();
                            lines.Add(line);
                        }
                        ResetAllStyles();
                        var circles = _circleNodeMap.Where(x => path.Contains(x.Value)).Select(x => x.Key);
                        foreach (var line in lines)
                        {
                            line.Stroke    = PathLineStroke;
                            line.Thickness = PathLineThickness;
                        }
                        foreach (var circle in circles)
                        {
                            circle.Fill = CommunicatingCircleFill;
                        }
                    }
                    catch (PathDoesNotExistException)
                    {
                        MessageBox.Show("The selected routers are not connected.", "No connection", MessageBoxButton.OK, MessageBoxImage.Error);
                    }
                }
            };
            OnCircleMouseEnter = (s, args) =>
            {
                if (_currentMode == Mode.Default)
                {
                    this.Cursor = Cursors.Hand;
                    DisableCanvasMouseEvents();

                    if (_tempLine != null)
                    {
                        _tempLine.End.PositionCenter = (s as Circle).PositionCenter;
                    }
                }
                else if (_currentMode == Mode.Delete)
                {
                    this.Cursor = Cursors.No;
                }
                else if (_currentMode == Mode.Send)
                {
                    var c = s as Circle;
                    if (_tempLine != null)
                    {
                        _tempLine.End.PositionCenter = c.PositionCenter;
                        if (c != _tempLine.Start)
                        {
                            c.Fill = CommunicatingCircleFill.Clone();
                        }
                    }
                }
            };
            OnCircleMouseLeave = (s, args) =>
            {
                if (_currentMode == Mode.Default)
                {
                    this.Cursor = Cursors.Arrow;
                    EnableCanvasMouseEvents();
                }
                else if (_currentMode == Mode.Delete)
                {
                    this.Cursor = Cursors.Arrow;
                }
                else if (_currentMode == Mode.Send)
                {
                    var c = s as Circle;
                    if (_tempLine != null && _tempLine.Start != c)
                    {
                        ResetCircleStyle(c);
                    }
                }
            };
            OnCircleMouseMove = (s, args) =>
            {
                if (_currentMode == Mode.Default)
                {
                    var c   = s as Circle;
                    var pos = args.GetPosition(canvas);
                    if (pos.X < CircleRadius)
                    {
                        pos.X = CircleRadius;
                    }
                    if (pos.X >= canvas.ActualWidth - CircleRadius)
                    {
                        pos.X = canvas.ActualWidth - CircleRadius;
                    }
                    if (pos.Y < CircleRadius)
                    {
                        pos.Y = CircleRadius;
                    }
                    if (pos.Y >= canvas.ActualHeight - CircleRadius)
                    {
                        pos.Y = canvas.ActualHeight - CircleRadius;
                    }
                    if (Mouse.Captured == c.UIElements.Where(x => x is Ellipse).FirstOrDefault())
                    {
                        c.PositionCenter = pos;
                    }
                    if (_tempLine != null)
                    {
                        _tempLine.End.PositionCenter = (s as Circle).PositionCenter;
                        args.Handled = true;
                    }
                }
                else if (_currentMode == Mode.Send)
                {
                    if (_tempLine != null)
                    {
                        _tempLine.End.PositionCenter = (s as Circle).PositionCenter;
                        args.Handled = true;
                    }
                }
            };

            OnEmptyCircleMouseMove += (sender, args) =>
            {
                var pos = args.GetPosition(canvas);
                if (_currentMode == Mode.Default)
                {
                    if (pos.X < 0)
                    {
                        pos.X = 0;
                    }
                    if (pos.X >= canvas.ActualWidth)
                    {
                        pos.X = canvas.ActualWidth - 1;
                    }
                    if (pos.Y < 0)
                    {
                        pos.Y = 0;
                    }
                    if (pos.Y >= canvas.ActualHeight)
                    {
                        pos.Y = canvas.ActualHeight - 1;
                    }
                    if (_tempLine == null)
                    {
                        return;
                    }
                    if (args.RightButton == MouseButtonState.Pressed)
                    {
                        _tempLine.End.PositionCenter = pos;
                    }
                    else
                    {
                        _tempLine = null;
                    }
                }
                else if (_currentMode == Mode.Send)
                {
                    if (_tempLine != null)
                    {
                        _tempLine.End.PositionCenter = pos;
                    }
                }
            };

            OnCircleMouseRightButtonDown = (s, args) =>
            {
                if (_currentMode == Mode.Default)
                {
                    var start = s as Circle;
                    _tempLine = new Shapes.Line(start,
                                                Circle.Empty,
                                                LineStroke,
                                                LineStroke,
                                                LineThickness,
                                                MovingOpacity);
                    _tempLine.Disposing += (sender, e) =>
                    {
                        canvas.Children.Remove(sender as Shapes.Line);
                    };
                    _tempLine.DragStart += (sender, e) =>
                    {
                        if (_currentMode == Mode.Default)
                        {
                            (sender as Shapes.Line).Opacity = MovingOpacity;
                        }
                    };
                    _tempLine.DragEnd += (sender, e) =>
                    {
                        if (_currentMode == Mode.Default)
                        {
                            (sender as Shapes.Line).Opacity = StationaryOpacity;
                        }
                    };
                    canvas.Children.Add(_tempLine);
                }
            };

            OnCircleMouseRightButtonUp = (s, args) =>
            {
                if (_currentMode == Mode.Default)
                {
                    if (_tempLine == null)
                    {
                        return;
                    }
                    var c = s as Circle;
                    if (_tempLine.Start == c)
                    {
                        return;
                    }
                    var window = new IntegerInputWindow(this);
                    window.InputEntered += (sender, e) =>
                    {
                        _tempLine.LabelText = e.ToString();
                        _tempLine.End       = c;
                        _tempLine.Opacity   = StationaryOpacity;
                        _lines.Add(_tempLine);

                        var startNode = _circleNodeMap[_tempLine.Start];
                        var endNode   = _circleNodeMap[_tempLine.End];
                        _lineNodeMap.Add(_tempLine,
                                         new Tuple <Node <string>, Node <string> >(startNode, endNode));
                        graph.AddEdge(startNode, endNode, e);

                        _tempLine = null;
                    };
                    window.ShowDialog();
                }
            };

            OnEmptyCircleMouseRightButtonUp = (s, args) =>
            {
                if (_currentMode == Mode.Default)
                {
                    if (_tempLine != null)
                    {
                        canvas.Children.Remove(_tempLine);
                    }
                    _tempLine = null;
                }
            };

            OnEmptyCircleMouseLeftButtonUp = (s, args) =>
            {
                if (_currentMode == Mode.Send)
                {
                    if (_tempLine != null)
                    {
                        canvas.Children.Remove(_tempLine);
                    }
                    _tempLine = null;
                }
            };
        }