/// <summary>
        /// In order to move an item we catch the mouse down event to decide which
        /// thing has been selected. This function chooses either the selected
        /// cut, trigger or player.
        /// </summary>
        /// <param name="mouseLocation">Screen coordinates.</param>
        /// <param name="frame">Frame currently being designed.</param>
        /// <param name="converter">Used to convert from screen to pitch 
        /// coordinates.</param>
        public override void handleMouseDown(Point mouseLocation, 
                                         PlayFrame frame,
                                         PitchScreenCoordConverter converter,
                                         VisualOverlay overlay)
        {
            PointF pitchCoords = converter.screenToPitchCoords(mouseLocation);

              // Choose closest selected item.
              mSelectedPlayer = frame.GetClosestPlayer(pitchCoords,
                                               SELECTION_MAX_DISTANCE);
              mSelectedCut = frame.GetClosestCutEnd(pitchCoords,
                                              SELECTION_MAX_DISTANCE);
              mSelectedTrigger = frame.GetClosestTrigger(pitchCoords,
                                                 SELECTION_MAX_DISTANCE);
              mIsMovingDiscControlPoint = frame.IsNearControlPoint(pitchCoords,
                                                           SELECTION_MAX_DISTANCE);

              // Note that the ordering of priorities here MUST be the same as the
              // ordering on mouse up.
              if (mSelectedTrigger != null)
              {
            overlay.SelectedTrigger = mSelectedTrigger;
            overlay.TriggerPlayer = mSelectedTrigger.AffectedPlayer;
              }
              else if (mSelectedCut != null)
              {
            overlay.DrawingNewCut = false;
            overlay.CutStart = mSelectedCut;
              }
              else if (mSelectedPlayer != null)
              {
            overlay.SelectedPlayer = mSelectedPlayer;
              }
              else if (mIsMovingDiscControlPoint)
              {
            overlay.MovingDiscControlPoint = true;
              }
        }
        /// <summary>
        /// Draw a trigger onto the screen. The location is tied to the trigger 
        /// object.
        /// 
        /// The description of what the trigger will look like is contained wholly 
        /// within this function.
        /// </summary>
        /// <param name="display"></param>
        /// <param name="trigger"></param>
        /// <param name="converter"></param>
        private void DrawTrigger(Graphics display, 
                             Trigger trigger, 
                             PitchScreenCoordConverter converter)
        {
            PointF locationToDraw = trigger.CausingCutRatio.GetAbsolutePosition();

              DrawPlayer(trigger.AffectedPlayer,
                 trigger.CausingCutRatio.GetAbsolutePosition(),
                 display,
                 converter,
                 true);
        }
 /// <summary>
 /// Called whenever we want to remove a specified trigger from the
 /// frame.
 /// 
 /// Noop if the trigger didn't exist.
 /// </summary>
 /// <param name="trigger">Can be null.</param>
 internal void RemoveTrigger(Trigger trigger)
 {
     if (Triggers.Contains(trigger))
       {
     Triggers.Remove(trigger);
       }
 }
        /// <summary>
        /// Given a position on the pitch and a player who is going to be moved we
        /// are able to check whether the trigger lies on a cut from any other 
        /// player and if so to create a new trigger at that position so that the
        /// player moves when the trigger is hit.
        /// </summary>
        /// <param name="pitchCoords"></param>
        /// <param name="maxDistanceFromLine"></param>
        /// <param name="affectedPlayer"></param>
        /// <returns>True if a trigger was created and false otherwise.</returns>
        public Boolean MaybeCreateTrigger(PointF pitchCoords, 
                                      float maxDistanceFromLine, 
                                      Player affectedPlayer)
        {
            Boolean foundCut = false;
              CutRatio cutRatio = GetClosestCutPoint(pitchCoords,
                                             maxDistanceFromLine,
                                             affectedPlayer);

              if (cutRatio != null)
              {
            foundCut = true;
            Trigger trigger = new Trigger(cutRatio, affectedPlayer);
            Triggers.Add(trigger);
              }

              return foundCut;
        }
        /// <summary>
        /// We capture the mouse up event and use it to place whatever it was that
        /// was selected on the mouse down event. If nothing was selected this does
        /// nothing. 
        /// </summary>
        /// <param name="mouseLocation"></param>
        /// <param name="frame"></param>
        /// <param name="converter"></param>
        public override void handleMouseUp(Point mouseLocation,
                                       PlayFrame frame,
                                       PitchScreenCoordConverter converter,
                                       VisualOverlay overlay)
        {
            PointF pitchCoords = converter.screenToPitchCoords(mouseLocation);

              if (mSelectedTrigger != null)
              {
            // If we are moving a trigger then only move it if the position it is
            // being placed is valid.
            if (frame.MaybeCreateTrigger(pitchCoords,
                                     SELECTION_MAX_DISTANCE,
                                     mSelectedTrigger.AffectedPlayer))
            {
              frame.RemoveTrigger(mSelectedTrigger);
              ModelChanged = true;
            }
              }
              else if (mSelectedPlayer != null)
              {
            frame.PlayerMovement[mSelectedPlayer][0].FinalPosition = pitchCoords;
            ModelChanged = true;
              }
              else if (mSelectedCut != null)
              {
            mSelectedCut.FinalPosition = pitchCoords;
            ModelChanged = true;
              }
              else if (mIsMovingDiscControlPoint)
              {
            frame.DiscFrameMovement.ControlPoint = pitchCoords;
            ModelChanged = true;
              }

              // Regardless of whether anything moved the move tool is complete on
              // mouse up.
              mSelectedCut = null;
              mSelectedPlayer = null;
              mSelectedTrigger = null;
              IsComplete = true;
        }
        internal void DeleteTrigger(Trigger mClickedTrigger)
        {
            viewPanel.CurrentFrame.RemoveTrigger(mClickedTrigger);

              viewPanel.Refresh();
              ModelChanged();
        }
        /// <summary>
        /// Overriding the onpopup handler (gets called before the menu is 
        /// displayed) to set up the menu based on what was clicked on.
        /// 
        /// This is to get around the fact that each player and cut is not
        /// actually a control.
        /// </summary>
        /// <param name="e"></param>
        protected override void OnPopup(EventArgs e)
        {
            this.MenuItems.Clear();

              if (mViewPanel.IsDesignMode)
              {
            // The mouse location comes in here as the location on the entire application
            // We need to use PointToClient to convert it to mouse location on the view
            // panel.
            Point mouseLocation = Cursor.Position;
            mMouseLocation = mViewPanel.PointToClient(mouseLocation);
            PointF pitchCoordinates = mViewPanel.Converter.screenToPitchCoords(mMouseLocation);
            PlayFrame currentFrame = mViewPanel.CurrentFrame;

            // Find out what was near the right click.
            mClickedPlayer = currentFrame.GetClosestPlayer(pitchCoordinates,
                                                       Settings.Default.PlayerDiameter);
            mClickedTrigger = currentFrame.GetClosestTrigger(pitchCoordinates,
                                                         Settings.Default.PlayerDiameter);
            mClickedCutRatio = mViewPanel.CurrentFrame.GetClosestCutPoint(pitchCoordinates,
                                                                      Settings.Default.PlayerDiameter,
                                                                      null);
            bool discPathClicked = currentFrame.IsOnFlightPath(pitchCoordinates,
                                                           Settings.Default.PlayerDiameter);
            if (mClickedPlayer != null)
            {
              SetUpPlayerMenu();
            }
            if (mClickedTrigger != null)
            {
              SetUpTriggerMenu();
            }
            if (mClickedCutRatio != null)
            {
              SetUpCutMenu();
            }
            if (discPathClicked)
            {
              SetUpDiscFlightMenu();
            }
            if (currentFrame.CanDrawCut(pitchCoordinates, Settings.Default.PlayerDiameter, 0.0f))
            {
              SetUpNewCutMenu();
            }

            base.OnPopup(e);
              }
        }