public static void MoveEnemyGrid(List <Bug> bugs, AnimationService animationService, Ship ship, bool gameover)
        {
            if (BugFactory.EnemyGrid.GridLeft > 330 || BugFactory.EnemyGrid.GridLeft < 160)
            {
                MoveEnemyGridIncrement *= -1;
            }

            if (!EnemyGridBreathing)
            {
                BugFactory.EnemyGrid.GridLeft += MoveEnemyGridIncrement;
            }
            else
            {
                if (BugFactory.EnemyGrid.GridLeft == Constants.EnemyGridLeft)
                {
                    BugFactory.EnemyGrid.GridLeft = Constants.EnemyGridLeft;

                    if (BugFactory.EnemyGrid.HSpacing > 60 || BugFactory.EnemyGrid.HSpacing < 45)
                    {
                        BreathEnemyGridIncrement *= -1;
                    }

                    BugFactory.EnemyGrid.HSpacing += BreathEnemyGridIncrement;
                    BugFactory.EnemyGrid.VSpacing += BreathEnemyGridIncrement;

                    if (!BreathSoundPlayed && !gameover)
                    {
                        SoundManager.PlaySound(SoundManager.SoundManagerSounds.breathing);
                        BreathSoundPlayed = true;
                    }
                }
                else
                {
                    BugFactory.EnemyGrid.GridLeft += MoveEnemyGridIncrement;
                }
            }

            bugs.ForEach(bug =>
            {
                //if the player shoots the bug befire it's captured in the tractor beam
                //then destroy the tracktor beam
                if (!bugs.Any(a => a.CaptureState == Bug.enCaptureState.Started))
                {
                    animationService.Animatables.RemoveAll(a => a.Sprite.SpriteType == Sprite.SpriteTypes.TractorBeam);
                    SoundManager.MuteAllSounds = false;
                }

                if (bug.IsDiveBomber)
                {
                    if (bug.CurPathPointIndex >= bug.PathPoints.Count - 1)
                    {
                        bug.Speed = Constants.BugDiveSpeed + 2;
                        bug.Paths.Add(new BezierCurve()
                        {
                            StartPoint    = bug.Location,
                            ControlPoint1 = bug.Location,
                            ControlPoint2 = bug.DiveBombLocation,
                            EndPoint      = bug.DiveBombLocation
                        });
                        bug.PathPoints.AddRange(animationService.ComputePathPoints(bug.Paths.Last(), true));
                    }
                }
                else if (bug.CaptureState == Bug.enCaptureState.Started)
                {
                    if (!bug.IsMoving && (bug.Location.Y > Constants.CanvasSize.Height / 3 || bug.FighterCapturedMessageShowing))
                    {
                        bug.Rotation = -90;
                        GalagaCaptureManager.DoTractorBeam(bug, animationService, ship);
                    }
                }
                else if (bug.CaptureState == Bug.enCaptureState.RecaptureStarted)
                {
                    GalagaCaptureManager.DoRecapture(bug, animationService, ship);
                }
                else
                {
                    //after the ship has been captured and disabled
                    //wait for all bugs to finish diving before re-enabling it
                    if (ship.Disabled)
                    {
                        if (bugs.Count(a => a.IsDiving) == 0)
                        {
                            ship.Disabled = false;
                        }
                    }

                    var homepoint = BugFactory.EnemyGrid.GetPointByRowCol(bug.HomePoint.X, bug.HomePoint.Y);
                    if (!(homepoint.X == 0 && homepoint.Y == 0))
                    {
                        homepoint.Y += bug.HomePointYOffset;
                        if (bug.IsMoving)
                        {
                            //this makes the bugs go to their spot on the moving enemy grid
                            if (bug.PathPoints.Count > 0)
                            {
                                //update the last point to be the moving homepoint on the enemy grid
                                bug.PathPoints[bug.PathPoints.Count - 1] = homepoint;
                                //if we are moving to the home point, recalc our vector each time it moves
                                if (bug.CurPathPointIndex == bug.PathPoints.Count - 1)
                                {
                                    bug.LineFromLocation = new Vector2(bug.Location.X, bug.Location.Y);
                                    bug.LineToLocation   = new Vector2(homepoint.X, homepoint.Y);
                                }
                            }
                        }
                        //snap to grid if bug isn't moving
                        else if (bug.Started && bug.PathPoints.Count == 0)
                        {
                            bug.Location = homepoint;
                            bug.IsDiving = false;
                            bug.NeverDestroyOffScreen = true;
                            bug.IsInIntro             = false;
                            bug.MissileCountDowns.Clear();
                            if (bug.CaptureState == Bug.enCaptureState.FlyingBackHome)
                            {
                                bug.CaptureState                  = Bug.enCaptureState.Complete;
                                SoundManager.MuteAllSounds        = false;
                                bug.FighterCapturedMessageShowing = false;
                                bug.ClearFighterCapturedMessage   = true;
                                ship.Visible  = true;
                                ship.Disabled = false;
                            }
                            //if the bug is morphing, do the morph animation
                            //and create the morphed bugs
                            if (bug.MorphState == Bug.enMorphState.Started)
                            {
                                BugMorphMananger.DoMorph(bugs, bug, animationService, ship);
                            }
                            //if the bug is a morphed bug and has flown back home
                            //change back into it's previous form
                            if (bug.IsMorphedBug)
                            {
                                bug.IsMorphedBug = false;
                                bug.Sprite       = bug.PreMorphedSprite;
                                bug.SpriteBank.Add(bug.PreMorphedSpriteDownFlap);
                                bug.MorphState = Bug.enMorphState.NotStarted;
                            }
                        }
                    }
                    else if (bug.Started && bug.PathPoints.Count == 0)
                    {
                        //no homepoint means this is a morphed bug and we need to make it dive off screen

                        IDive dive;

                        if (Utils.Rnd(0, 10) % 2 == 0)
                        {
                            dive = new RedBugDive1();
                        }
                        else
                        {
                            dive = new RedBugDive2();
                        }

                        EnemyDiveManager.DoEnemyDive(bugs, animationService, ship, Constants.BugDiveSpeed, bug, false, false, dive);
                    }
                }
            });
        }
        public static Bug DoEnemyDive(
            List <Bug> bugs,
            AnimationService animationService,
            Ship ship,
            int speed,
            Bug bug              = null,
            bool captureship     = false,
            bool capturehappened = false,
            IDive overriddive    = null,
            bool canmorph        = false
            )

        {
            int loopcount = 0;

            while (bug == null || bug.IsMoving ||
                   bug.CaptureState == Bug.enCaptureState.Started ||
                   bug.CaptureState == Bug.enCaptureState.FlyingBackHome ||
                   bug.CaptureState == Bug.enCaptureState.RecaptureStarted ||
                   bug.MorphState == Bug.enMorphState.Started ||
                   bug.DrawPath)
            {
                bug = bugs[Utils.Rnd(0, bugs.Count - 1)];
                loopcount++;
                if (loopcount > 50)
                {
                    return(null);
                }
            }

            //if the captured ship bug is selected,
            //set the selected bug to the parent bug
            if (bug.Sprite.SpriteType == Sprite.SpriteTypes.CapturedShip)
            {
                var parentgreenbug = bugs.FirstOrDefault(a => a.CapturedBug != null);
                if (parentgreenbug != null)
                {
                    bug = parentgreenbug;
                }
            }

            //if morphing is enabled, 20% of the time morph instead of dive
            if (canmorph && Utils.Rnd(1, 100) < 20)
            {
                if ((bug.Sprite.SpriteType == Sprite.SpriteTypes.BlueBug || bug.Sprite.SpriteType == Sprite.SpriteTypes.RedBug) &&
                    !bug.IsMorphedBug)
                {
                    bug.MorphState = Bug.enMorphState.Started;
                    bug.IsDiving   = true;
                    SoundManager.PlaySound(SoundManager.SoundManagerSounds.morph);
                    return(null);
                }
            }

            IDive dive = null;

            if (bug.Sprite.SpriteType == Sprite.SpriteTypes.BlueBug || bug.IsMorphedBug)
            {
                if (Utils.Rnd(0, 10) % 2 == 0)
                {
                    dive = new BlueBugDive1();
                }
                else
                {
                    dive = new BlueBugDive2();
                }
            }
            else if (bug.Sprite.SpriteType == Sprite.SpriteTypes.RedBug)
            {
                if (Utils.Rnd(0, 10) % 2 == 0)
                {
                    dive = new RedBugDive1();
                }
                else
                {
                    dive = new RedBugDive2();
                }
            }
            else if (bug.Sprite.SpriteType == Sprite.SpriteTypes.GreenBug)
            {
                if (!captureship && !capturehappened)
                {
                    if (ship.Sprite.SpriteType != Sprite.SpriteTypes.DoubleShip &&
                        bugs.Count(a => a.Sprite.SpriteType == Sprite.SpriteTypes.GreenBug || a.Sprite.SpriteType == Sprite.SpriteTypes.GreenBug_Blue) > 1 &&
                        bugs.Count(a => a.CaptureState != Bug.enCaptureState.NotStarted) == 0)
                    {
                        captureship = true;
                    }
                }

                if (captureship)
                {
                    dive = new CaptureDive();

                    bug.RotateWhileStill = true;
                    bug.CaptureState     = Bug.enCaptureState.Started;
                }
                else
                {
                    if (bug.CapturedBug == null)
                    {
                        var childbugs = bugs.Where(a =>
                                                   (a.HomePoint == new Point(2, bug.HomePoint.Y + 1) ||
                                                    a.HomePoint == new Point(2, bug.HomePoint.Y + 2)) &&
                                                   !a.IsMoving);

                        bug.ChildBugs.AddRange(childbugs);
                        bug.ChildBugOffset = new Point(45, 35);
                    }

                    if (Utils.Rnd(0, 10) % 2 == 0)
                    {
                        dive = new GreenBugDive1();
                    }
                    else
                    {
                        dive = new GreenBugDive2();
                    }
                }
            }
            else
            {
                dive = new RedBugDive1();
            }

            animationService.Animatables.ForEach(a => a.ZIndex = 0);

            if (overriddive != null)
            {
                dive = overriddive;
            }

            var paths = dive.GetPaths(bug, ship);

            bug.SpriteBankIndex = null;
            bug.IsDiving        = true;
            bug.RotateAlongPath = true;
            bug.ZIndex          = 100;
            bug.Speed           = speed;
            bug.Paths.AddRange(paths);

            paths.ForEach(p => {
                bug.PathPoints.AddRange(animationService.ComputePathPoints(p, false));
            });

            if (bug != null && !bug.IsMorphedBug)
            {
                SoundManager.PlaySound(SoundManager.SoundManagerSounds.dive);
            }

            return(bug);
        }