//Reads in a paint image and adds all entities to the level.
        public void readImage(Level level)
        {
            for (int y = 0; y < img.Height; y++)
            {
                for (int x = 0; x < img.Width; x++)
                {
                    //Get the color of the pixel
                    Color col = img.GetPixel(x, y);

                    float levelX = x;
                    float levelY = y;

                    //First check for cases which have some variation in possible color values
                    //i.e. something identified with only it's RG, or GB, or RB, or just R or G or B
                    if (col.R == switchReserveRed)
                    {
                        Entity s = null;

                        if (col.G == permSwitchG)
                        {
                            s = new SwitchEntity(level, rand.Next(Int32.MinValue, Int32.MaxValue), levelX * tileWidth, levelY * tileHeight);
                        }
                        else if (col.G == presSwitchG)
                        {
                            //Pressure Switch
                            s = new PressureSwitchEntity(level, rand.Next(Int32.MinValue, Int32.MaxValue), levelX * tileWidth, levelY * tileWidth);
                            TimedSwitchComponent timeComp = ( TimedSwitchComponent )s.getComponent(GlobalVars.TIMED_SWITCH_COMPONENT_NAME);
                            timeComp.baseTime = 0;
                        }
                        else
                        {
                            s = new TimedSwitchEntity(level, rand.Next(Int32.MinValue, Int32.MaxValue), levelX * tileWidth, levelY * tileWidth);
                            TimedSwitchComponent timeComp = ( TimedSwitchComponent )s.getComponent(GlobalVars.TIMED_SWITCH_COMPONENT_NAME);
                            timeComp.baseTime = col.G / 10;
                        }
                        s.isStartingEntity = true;
                        adjustLocation(s, level);
                        switches.Add(col.B, s);
                        level.addEntity(s.randId, s);
                    }
                    else if (col.R == spikeSwitchReserveRed)
                    {
                        float time = -1;
                        if (col.G < 255)
                        {
                            time = col.G / 10;
                        }
                        Entity s = new SpikeSwitchEntity(level, rand.Next(Int32.MinValue, Int32.MaxValue), levelX * tileWidth, levelY * tileHeight, time);

                        s.isStartingEntity = true;
                        adjustLocation(s, level);
                        switches.Add(col.B, s);
                        level.addEntity(s.randId, s);
                    }
                    else if (col.R == shooterRedUp || col.R == shooterRedRight || col.R == shooterRedDown || col.R == shooterRedLeft)
                    {
                        float betweenBursts = ( float )col.B / ( float )10;
                        int   switchId      = col.G;

                        TimedShooterEntity shooter = new TimedShooterEntity(level, rand.Next(Int32.MinValue, Int32.MaxValue), levelX * tileWidth, levelY * tileHeight, betweenBursts, 1, col.R - 110, switchId);
                        if (switchId == 0)
                        {
                            shooter.removeComponent(GlobalVars.SWITCH_LISTENER_COMPONENT_NAME);
                        }
                        else
                        {
                            SwitchListenerComponent slComp = ( SwitchListenerComponent )shooter.getComponent(GlobalVars.SWITCH_LISTENER_COMPONENT_NAME);
                            if (switches.ContainsKey(switchId))
                            {
                                slComp.switchId = switches[switchId].randId;
                            }
                            else
                            {
                                unmachedSwitchListeners.Add(slComp, switchId);
                            }
                        }
                        adjustLocation(shooter, level);
                        shooter.isStartingEntity = true;
                        level.addEntity(shooter);
                    }
                    else if (col.R == smushRed && (col.B - 4 <= 0))
                    {
                        int switchId           = col.G;
                        SmushBlockEntity smush = new SmushBlockEntity(level, rand.Next(Int32.MinValue, Int32.MaxValue), levelX * tileWidth, levelY * tileHeight, col.B, switchId);

                        if (switchId == 0)
                        {
                            smush.removeComponent(GlobalVars.SWITCH_LISTENER_COMPONENT_NAME);
                        }
                        else
                        {
                            SwitchListenerComponent slComp = ( SwitchListenerComponent )smush.getComponent(GlobalVars.SWITCH_LISTENER_COMPONENT_NAME);
                            if (switches.ContainsKey(switchId))
                            {
                                slComp.switchId = switches[switchId].randId;
                            }
                            else
                            {
                                unmachedSwitchListeners.Add(slComp, switchId);
                            }
                        }

                        adjustLocation(smush, level);
                        smush.isStartingEntity = true;
                        level.addEntity(smush);
                    }
                    else if (col.G == tallDoorReserveGreen || col.G == wideDoorReserveGreen || col.G == openTallDoorReserveGreen || col.G == openWideDoorReserveGreen)
                    {
                        float width  = tallDoorWidth;
                        float height = tallDoorHeight;

                        if (col.G == wideDoorReserveGreen || col.G == openWideDoorReserveGreen)
                        {
                            width  = wideDoorWidth;
                            height = wideDoorHeight;
                        }

                        DoorEntity door = new DoorEntity(level, rand.Next(Int32.MinValue, Int32.MaxValue), levelX * tileWidth, levelY * tileHeight, width, height, (col.G % 100 == 0 || col.G % 100 == 1));
                        adjustLocation(door, level);
                        SwitchListenerComponent slComp = ( SwitchListenerComponent )door.getComponent(GlobalVars.SWITCH_LISTENER_COMPONENT_NAME);
                        door.isStartingEntity = true;
                        //check for its switch
                        if (switches.ContainsKey(col.B))
                        {
                            slComp.switchId = switches[col.B].randId;
                        }
                        else
                        {
                            unmachedSwitchListeners.Add(slComp, col.B);
                        }
                        level.addEntity(door);
                    }
                    else if (col.R == spikeRed && col.G == spikeGreen && (col.B - 4 <= 0))
                    {
                        SpikeEntity spike = new SpikeEntity(level, rand.Next(Int32.MinValue, Int32.MaxValue), levelX * tileWidth, levelY * tileHeight, col.B);
                        adjustLocation(spike, level);
                        spike.isStartingEntity = true;
                        level.addEntity(spike);
                    }
                    else if (col.R == signRed && col.G == signGreen)
                    {
                        SignEntity signEnt = new SignEntity(level, rand.Next(Int32.MinValue, Int32.MaxValue), levelX * tileWidth, levelY * tileHeight, col.B);
                        adjustLocation(signEnt, level);
                        signEnt.isStartingEntity = true;
                        level.addEntity(signEnt);
                    }

                    //Now just check for the specific colors
                    else if (col == playerCol)
                    {
                        Player player = new Player(level, rand.Next(Int32.MinValue, Int32.MaxValue), levelX * tileWidth, levelY * tileHeight);
                        adjustLocation(player, level);
                        PositionComponent posComp = ( PositionComponent )player.getComponent(GlobalVars.POSITION_COMPONENT_NAME);
                        level.getMovementSystem().teleportToNoCollisionCheck(posComp, posComp.x, posComp.y - GlobalVars.MIN_TILE_SIZE / 2);
                        posComp.setCurrentLocToStartingLoc();
                        player.isStartingEntity = true;
                        level.addEntity(player.randId, player);
                    }
                    else if (col == movePlatformTurn)
                    {
                        PlatformTurnEntity platTurn = new PlatformTurnEntity(level, rand.Next(Int32.MinValue, Int32.MaxValue), levelX * tileWidth, levelY * tileHeight);
                        adjustLocation(platTurn, level);
                        platTurn.isStartingEntity = true;
                        level.addEntity(platTurn.randId, platTurn);
                    }
                    else if (col == basicGroundCol)
                    {
                        float groundX     = (levelX) * tileWidth;
                        float groundWidth = tileWidth;

                        BasicGround ground = new BasicGround(level, rand.Next(Int32.MinValue, Int32.MaxValue), groundX, (levelY) * tileHeight, groundWidth, tileHeight);
                        adjustLocation(ground, level);
                        ground.isStartingEntity = true;
                        level.addEntity(ground.randId, ground);

                        if (!GlobalVars.fullForegroundImage)
                        {
                            //If no ground above it, change to a grass sprite
                            List <Entity> above = level.getCollisionSystem().findObjectAtPoint((levelX) * tileWidth, (levelY - 1) * tileWidth);
                            if (above.Count <= 0 || !(above[0] is BasicGround))
                            {
                                ground.changeSprite(false);
                            }
                        }
                    }
                    else if (col == testEntityColor)
                    {
                        float      xLoc = (levelX) * tileWidth;
                        float      yLoc = (levelY) * tileHeight;
                        int        id   = rand.Next(Int32.MinValue, Int32.MaxValue);
                        TestEntity test = new TestEntity(level, id, xLoc, yLoc);
                        adjustLocation(test, level);
                        test.isStartingEntity = true;
                        level.addEntity(test.randId, test);
                    }
                    else if (col == simpleEnemyColor)
                    {
                        float             xLoc  = (levelX) * tileWidth;
                        float             yLoc  = (levelY) * tileHeight;
                        int               id    = rand.Next(Int32.MinValue, Int32.MaxValue);
                        SimpleEnemyEntity enemy = new SimpleEnemyEntity(level, id, xLoc, yLoc, false);
                        adjustLocation(enemy, level);
                        enemy.isStartingEntity = true;
                        level.addEntity(enemy.randId, enemy);
                    }
                    else if (col == flyingEnemyColor)
                    {
                        float             xLoc  = (levelX) * tileWidth;
                        float             yLoc  = (levelY) * tileHeight;
                        int               id    = rand.Next(Int32.MinValue, Int32.MaxValue);
                        FlyingEnemyEntity enemy = new FlyingEnemyEntity(level, id, xLoc, yLoc, false);
                        adjustLocation(enemy, level);
                        enemy.isStartingEntity = true;
                        level.addEntity(enemy.randId, enemy);
                    }
                    else if (col == shieldWalkingEnemyColor)
                    {
                        float             xLoc  = (levelX) * tileWidth;
                        float             yLoc  = (levelY) * tileHeight;
                        int               id    = rand.Next(Int32.MinValue, Int32.MaxValue);
                        SimpleEnemyEntity enemy = new SimpleEnemyEntity(level, id, xLoc, yLoc, true);
                        adjustLocation(enemy, level);
                        enemy.isStartingEntity = true;
                        level.addEntity(enemy.randId, enemy);
                    }
                    else if (col == shieldFlyingEnemyColor)
                    {
                        float             xLoc  = (levelX) * tileWidth;
                        float             yLoc  = (levelY) * tileHeight;
                        int               id    = rand.Next(Int32.MinValue, Int32.MaxValue);
                        FlyingEnemyEntity enemy = new FlyingEnemyEntity(level, id, xLoc, yLoc, true);
                        adjustLocation(enemy, level);
                        enemy.isStartingEntity = true;
                        level.addEntity(enemy.randId, enemy);
                    }
                    else if (col == checkPointCollider)
                    {
                        CheckPointEntity checkEnt = new CheckPointEntity(level, rand.Next(Int32.MinValue, Int32.MaxValue), levelX * tileWidth, levelY * tileHeight);
                        adjustLocation(checkEnt, level);
                        checkEnt.isStartingEntity = true;
                        level.addEntity(checkEnt.randId, checkEnt);
                    }/*else if ( col == checkPointCollider ) {
                      *
                      * float xLoc = ( levelX ) * tileWidth;
                      * float yLoc = ( levelY ) * tileHeight;
                      * int id = rand.Next( Int32.MinValue, Int32.MaxValue );
                      * EndLevelEntity lvlEnd = new EndLevelEntity( level, id, xLoc, yLoc );
                      * adjustLocation( lvlEnd, level );
                      * lvlEnd.isStartingEntity = true;
                      * level.addEntity( lvlEnd.randId, lvlEnd );
                      *
                      * }*/
                    else if (col == vertMovPlatCol)
                    {
                        float xLoc = (levelX) * tileWidth;
                        float yLoc = (levelY) * tileHeight;
                        int   id   = rand.Next(Int32.MinValue, Int32.MaxValue);

                        MovingPlatformEntity plat = new MovingPlatformEntity(level, id, xLoc, yLoc);
                        adjustLocation(plat, level);

                        plat.isStartingEntity = true;
                        level.addEntity(plat);
                    } /*else if ( col == horizMovPlatCol ) {
                       *
                       * float xLoc = ( levelX ) * tileWidth;
                       * float yLoc = ( levelY ) * tileHeight;
                       * int id = rand.Next( Int32.MinValue, Int32.MaxValue );
                       *
                       * MovingPlatformEntity plat = new MovingPlatformEntity( level, id, xLoc, yLoc );
                       * adjustLocation( plat, level );
                       *
                       * plat.isStartingEntity = true;
                       * MovingPlatformComponent movPlatComp = ( MovingPlatformComponent )plat.getComponent( GlobalVars.MOVING_PLATFORM_COMPONENT_NAME );
                       * movPlatComp.vertical = false;
                       * VelocityComponent velComp = ( VelocityComponent )plat.getComponent( GlobalVars.VELOCITY_COMPONENT_NAME );
                       * velComp.y = 0;
                       * level.addEntity( plat );
                       *
                       * }*/
                    else if (col == bouncePickup)
                    {
                        float xLoc = (levelX) * tileWidth;
                        float yLoc = (levelY) * tileHeight;
                        int   id   = rand.Next(Int32.MinValue, Int32.MaxValue);

                        PowerupPickupEntity pickup = new PowerupPickupEntity(level, id, xLoc, yLoc, GlobalVars.BOUNCE_NUM);
                        adjustLocation(pickup, level);

                        pickup.isStartingEntity = true;
                        level.addEntity(pickup);
                    }
                    else if (col == speedyPickup)
                    {
                        float xLoc = (levelX) * tileWidth;
                        float yLoc = (levelY) * tileHeight;
                        int   id   = rand.Next(Int32.MinValue, Int32.MaxValue);

                        PowerupPickupEntity pickup = new PowerupPickupEntity(level, id, xLoc, yLoc, GlobalVars.SPEED_NUM);
                        adjustLocation(pickup, level);

                        pickup.isStartingEntity = true;
                        level.addEntity(pickup);
                    }
                    else if (col == jmpPickup)
                    {
                        float xLoc = (levelX) * tileWidth;
                        float yLoc = (levelY) * tileHeight;
                        int   id   = rand.Next(Int32.MinValue, Int32.MaxValue);

                        PowerupPickupEntity pickup = new PowerupPickupEntity(level, id, xLoc, yLoc, GlobalVars.JMP_NUM);
                        adjustLocation(pickup, level);

                        pickup.isStartingEntity = true;
                        level.addEntity(pickup);
                    }
                    else if (col == glidePickup)
                    {
                        float xLoc = (levelX) * tileWidth;
                        float yLoc = (levelY) * tileHeight;
                        int   id   = rand.Next(Int32.MinValue, Int32.MaxValue);

                        PowerupPickupEntity pickup = new PowerupPickupEntity(level, id, xLoc, yLoc, GlobalVars.GLIDE_NUM);
                        adjustLocation(pickup, level);

                        pickup.isStartingEntity = true;
                        level.addEntity(pickup);
                    }
                    else if (col == spawnPickup)
                    {
                        float xLoc = (levelX) * tileWidth;
                        float yLoc = (levelY) * tileHeight;
                        int   id   = rand.Next(Int32.MinValue, Int32.MaxValue);

                        PowerupPickupEntity pickup = new PowerupPickupEntity(level, id, xLoc, yLoc, GlobalVars.SPAWN_NUM);
                        adjustLocation(pickup, level);

                        pickup.isStartingEntity = true;
                        level.addEntity(pickup);
                    }
                    else if (col == grapPickup)
                    {
                        float xLoc = (levelX) * tileWidth;
                        float yLoc = (levelY) * tileHeight;
                        int   id   = rand.Next(Int32.MinValue, Int32.MaxValue);

                        PowerupPickupEntity pickup = new PowerupPickupEntity(level, id, xLoc, yLoc, GlobalVars.GRAP_NUM);
                        adjustLocation(pickup, level);

                        pickup.isStartingEntity = true;
                        level.addEntity(pickup);
                    }
                    else if (col == visionOrbUnlock)
                    {
                        float xLoc = (levelX) * tileWidth;
                        float yLoc = (levelY) * tileHeight;
                        int   id   = rand.Next(Int32.MinValue, Int32.MaxValue);

                        VisionOrbUnlock visUnlock = new VisionOrbUnlock(level, id, xLoc, yLoc);
                        adjustLocation(visUnlock, level);

                        visUnlock.isStartingEntity = true;
                        level.addEntity(visUnlock);
                    }
                }
            }

            //Match any unmatched switch listeners to their switch
            foreach (SwitchListenerComponent sc in unmachedSwitchListeners.Keys)
            {
                if (switches.ContainsKey(unmachedSwitchListeners[sc]))
                {
                    SwitchListenerComponent slComp = sc;
                    slComp.switchId = switches[unmachedSwitchListeners[sc]].randId;
                }
                else
                {
                    Console.WriteLine("Unmatched Switch Listener - B: " + unmachedSwitchListeners[sc]);
                }
            }
        }
        public override void Update(float deltaTime)
        {
            foreach (Entity e in getApplicableEntities())
            {
                //Grab needed components
                SimpleEnemyComponent simpEnemyComp = ( SimpleEnemyComponent )e.getComponent(GlobalVars.SIMPLE_ENEMY_COMPONENT_NAME);
                VelocityComponent    velComp       = ( VelocityComponent )e.getComponent(GlobalVars.VELOCITY_COMPONENT_NAME);

                float speedyBuffer = 0;
                if (!simpEnemyComp.checkCliff && simpEnemyComp.checkCliffOrig && Math.Abs(velComp.x) <= Math.Abs(simpEnemyComp.mySpeed + speedyBuffer))
                {
                    simpEnemyComp.checkCliff = simpEnemyComp.checkCliffOrig;
                }

                if (simpEnemyComp.hasRunOnce && !simpEnemyComp.hasLandedOnce && velComp.y <= 0)
                {
                    simpEnemyComp.hasLandedOnce = true;
                }
                if (velComp.x < 0)
                {
                    simpEnemyComp.movingLeft          = true;
                    simpEnemyComp.wasStoppedLastFrame = false;
                }
                else if (velComp.x > 0)
                {
                    simpEnemyComp.movingLeft          = false;
                    simpEnemyComp.wasStoppedLastFrame = false;
                }
                else if (velComp.x == 0 && velComp.y == 0 && simpEnemyComp.hasLandedOnce)     //If it's been stopped for more than one frame, try changing the direction and see if it can move that way instead.
                {
                    float newVel = simpEnemyComp.mySpeed;
                    if (!simpEnemyComp.movingLeft)
                    {
                        newVel *= -1;
                    }

                    if (simpEnemyComp.wasStoppedLastFrame)
                    {
                        velComp.x = newVel;
                    }

                    simpEnemyComp.wasStoppedLastFrame = true;
                }

                //Change position if it's about to fall off a cliff, and checkCliff is true.
                if (simpEnemyComp.hasLandedOnce && velComp.y == 0 && simpEnemyComp.checkCliff)
                {
                    PositionComponent posComp = ( PositionComponent )e.getComponent(GlobalVars.POSITION_COMPONENT_NAME);
                    ColliderComponent colComp = ( ColliderComponent )e.getComponent(GlobalVars.COLLIDER_COMPONENT_NAME);

                    //Separated out for easy changing.
                    float e1X      = posComp.x;
                    float e1Y      = posComp.y;
                    float e1Width  = colComp.width;
                    float e1Height = colComp.height;

                    //Center width/height values
                    if (e1Width != posComp.width)
                    {
                        float diff = (posComp.width - e1Width);
                        e1X += diff / 2;
                    }
                    if (e1Height != posComp.height)
                    {
                        float diff = (posComp.height - e1Height);
                        e1Y += diff / 2;
                    }

                    List <Entity> collisionsAheadAndBelow = level.getCollisionSystem().findObjectAtPoint(e1X + getSign(velComp.x) * (e1Width / 2 + 1), e1Y + e1Height / 2 + 1);

                    //Remove spikes from the collisions
                    List <Entity> entsToRemove = new List <Entity>();
                    foreach (Entity ent in collisionsAheadAndBelow)
                    {
                        if (ent is SpikeEntity)
                        {
                            entsToRemove.Add(ent);
                        }
                    }
                    foreach (Entity ent in entsToRemove)
                    {
                        collisionsAheadAndBelow.Remove(ent);
                    }

                    if (collisionsAheadAndBelow.Count <= 0)
                    {
                        velComp.x = -velComp.x;
                    }


                    //If there are any bounced bullets, decrease their timer - remove if it's been enough time since bounce.
                    if (simpEnemyComp.bouncedBullets.Count > 0)
                    {
                        List <Entity> toRemove = simpEnemyComp.bouncedBullets.Keys.ToList <Entity>();
                        foreach (Entity bullet in toRemove)
                        {
                            simpEnemyComp.bouncedBullets[bullet] -= deltaTime;
                            if (simpEnemyComp.bouncedBullets[bullet] < 0)
                            {
                                simpEnemyComp.bouncedBullets.Remove(bullet);
                            }
                        }
                    }
                }

                //Face the right way
                if (e is SimpleEnemyEntity)
                {
                    SimpleEnemyEntity enemy = ( SimpleEnemyEntity )e;
                    if (velComp.x > 0 && !enemy.isLookingRight())
                    {
                        enemy.faceRight();
                    }
                    if (velComp.x < 0 && !enemy.isLookingLeft())
                    {
                        enemy.faceLeft();
                    }
                }
                else if (e is FlyingEnemyEntity)
                {
                    FlyingEnemyEntity enemy = ( FlyingEnemyEntity )e;
                    if (velComp.x > 0 && !enemy.isLookingRight())
                    {
                        enemy.faceRight();
                    }
                    if (velComp.x < 0 && !enemy.isLookingLeft())
                    {
                        enemy.faceLeft();
                    }
                }
                simpEnemyComp.hasRunOnce = true;
            }
        }