The main component in charge of displaying particles.
Inheritance: Microsoft.Xna.Framework.DrawableGameComponent
        /// <summary>
        /// Constructs a new projectile.
        /// </summary>
        public Upgrade(ParticleSystem starParticles)
        {
            this.starParticles = starParticles;

            // Start at the origin, firing in a random (but roughly upward) direction.
            Position = Vector3.Zero;
            velocity = Vector3.Zero;
        }
        /// <summary>
        /// Constructs a new particle emitter object.
        /// </summary>
        public ParticleEmitter(ParticleSystem particleSystem,
                               float particlesPerSecond, Vector3 initialPosition)
        {
            this.particleSystem = particleSystem;

            timeBetweenParticles = 1.0f / particlesPerSecond;

            previousPosition = initialPosition;
        }
        /// <summary>
        /// Constructs a new projectile.
        /// </summary>
        public Explosion(ParticleSystem explosionParticles, ParticleSystem laserParticles)
        {
            this.explosionParticles = explosionParticles;
            this.laserParticles = laserParticles;

            // Start at the origin, firing in a random (but roughly upward) direction.
            Position = Vector3.Zero;
            velocity = Vector3.Zero;
            Destination = Vector3.Zero;
            DestinationNearby = Vector3.Zero;
        }
        /// <summary>
        /// Constructs a new projectile.
        /// </summary>
        public Projectile(ParticleSystem explosionParticles,
                          ParticleSystem explosionSmokeParticles,
                          ParticleSystem projectileTrailParticles)
        {
            this.explosionParticles = explosionParticles;
            this.explosionSmokeParticles = explosionSmokeParticles;

            // Start at the origin, firing in a random (but roughly upward) direction.
            Position = Vector3.Zero;

            velocity.X = (float)(random.NextDouble() - 0.5) * sidewaysVelocityRange;
            velocity.Y = (float)(random.NextDouble() + 0.5) * verticalVelocityRange;
            velocity.Z = (float)(random.NextDouble() - 0.5) * sidewaysVelocityRange;

            // Use the particle emitter helper to output our trail particles.
            trailEmitter = new ParticleEmitter(projectileTrailParticles,
                                               trailParticlesPerSecond, Position);
        }
        public static void Dispose()
        {
            ScreenManager.Game.Components.Remove(explosionParticles);
            ScreenManager.Game.Components.Remove(explosionSmokeParticles);
            ScreenManager.Game.Components.Remove(projectileTrailParticles);
            ScreenManager.Game.Components.Remove(smokePlumeParticles);
            ScreenManager.Game.Components.Remove(fireParticles);

            explosionParticles.Dispose();
            explosionSmokeParticles.Dispose();
            projectileTrailParticles.Dispose();
            smokePlumeParticles.Dispose();
            fireParticles.Dispose();
            for (int i = 0; i < upgradeParticles.Length; i++)
            {
                if(upgradeParticles[i] != null)
                    upgradeParticles[i].Dispose();
            }

            for (int i = 0; i < repairParticles.Length; i++)
            {
                if (repairParticles[i] != null)
                    repairParticles[i].Dispose();
            }

            explosionParticles = null;
            explosionSmokeParticles = null;
            projectileTrailParticles = null;
            smokePlumeParticles = null;
            fireParticles = null;
            upgradeParticles = null;
            repairParticles = null;

            projectiles = null;
            upgradeEffect = null;
            upgradeCount = null;
            repairEffect = null;
            repairCount = null;
            GC.Collect();
        }
        public static void Initialize()
        {
            // Construct our particle system components.
            explosionParticles = new ExplosionParticleSystem(ScreenManager.Game, ScreenManager.Game.Content);
            explosionSmokeParticles = new ExplosionSmokeParticleSystem(ScreenManager.Game, ScreenManager.Game.Content);
            projectileTrailParticles = new ProjectileTrailParticleSystem(ScreenManager.Game, ScreenManager.Game.Content);
            smokePlumeParticles = new SmokePlumeParticleSystem(ScreenManager.Game, ScreenManager.Game.Content);
            fireParticles = new FireParticleSystem(ScreenManager.Game, ScreenManager.Game.Content);
            //starParticles = new StarParticleSystem(ScreenManager.Game, ScreenManager.Game.Content);
            upgradeParticles = new ParticleSystem[5];
            repairParticles = new ParticleSystem[5];
            for (int i = 1; i < 5; i++)
            {

                switch(i)
                {
                    case 1:
                        upgradeParticles[i] = new P1Upgrade(ScreenManager.Game, ScreenManager.Game.Content);
                        repairParticles[i] = new P1Upgrade(ScreenManager.Game, ScreenManager.Game.Content);
                        break;
                    case 2:
                        upgradeParticles[i] = new P2Upgrade(ScreenManager.Game, ScreenManager.Game.Content);
                        repairParticles[i] = new P2Upgrade(ScreenManager.Game, ScreenManager.Game.Content);
                        break;
                    case 3:
                        upgradeParticles[i] = new P3Upgrade(ScreenManager.Game, ScreenManager.Game.Content);
                        repairParticles[i] = new P3Upgrade(ScreenManager.Game, ScreenManager.Game.Content);
                        break;
                    case 4:
                        upgradeParticles[i] = new P4Upgrade(ScreenManager.Game, ScreenManager.Game.Content);
                        repairParticles[i] = new P4Upgrade(ScreenManager.Game, ScreenManager.Game.Content);
                        break;

                }

                upgradeParticles[i].DrawOrder = 600;
                repairParticles[i].DrawOrder = 600;
                ScreenManager.Game.Components.Add(upgradeParticles[i]);
                ScreenManager.Game.Components.Add(repairParticles[i]);
            }

            // Set the draw order so the explosions and fire
            // will appear over the top of the smoke.
            smokePlumeParticles.DrawOrder = 100;
            explosionSmokeParticles.DrawOrder = 200;
            projectileTrailParticles.DrawOrder = 300;
            explosionParticles.DrawOrder = 400;
            fireParticles.DrawOrder = 500;
            //starParticles.DrawOrder = 600;

            // Register the particle system components.
            ScreenManager.Game.Components.Add(explosionParticles);
            ScreenManager.Game.Components.Add(explosionSmokeParticles);
            ScreenManager.Game.Components.Add(projectileTrailParticles);
            ScreenManager.Game.Components.Add(smokePlumeParticles);
            ScreenManager.Game.Components.Add(fireParticles);
            //ScreenManager.Game.Components.Add(starParticles);

            projectiles = new List<Projectile>();
            //stars = new List<Star>();

            for (int i = 0; i < MAX_PROJECTILES; i++)
            {
                projectiles.Add(new Projectile(explosionParticles, explosionSmokeParticles, projectileTrailParticles));
                //stars.Add(new Star(starParticles));
            }

            upgradeEffect = new List<List<Upgrade>>();
            upgradeCount = new int[5];
            upgradeEffect.Add(new List<Upgrade>());
            repairEffect = new List<List<Repair>>();
            repairEffect.Add(new List<Repair>());
            repairCount = new int[5];
            for (int p = 1; p < 5; p++)
            {
                upgradeEffect.Add(new List<Upgrade>());
                repairEffect.Add(new List<Repair>());
                for (int i = 0; i < MAX_PROJECTILES; i++)
                {
                    upgradeEffect[p].Add(new Upgrade(upgradeParticles[p]));
                    repairEffect[p].Add(new Repair(repairParticles[p]));
                }
                upgradeCount[p] = 0;
                repairCount[p] = 0;
            }
            projectileCount = 0;

            cameraManager = (CameraManager)ScreenManager.Game.Services.GetService(typeof(CameraManager));

            particleThread = new Thread(ThreadedUpdate);
            particleThreadExit = new ManualResetEvent(false);
            timer = System.Diagnostics.Stopwatch.StartNew();
        }