//****************************************************************//
        // This function updates the position of each enemy in the game   //
        // and the player, it then checks if there are collisions between //
        // the enemy or the player and raises a PlayerCaught event.       //
        // It also checks if the player has reached the end goal.         //
        //****************************************************************//
        public void UpdatePositions(CGameState gameState, float time_delta)
        {
            ///////////////////////////////////////////////////////////////////
            // First we update the positions of the players and enemies.

            foreach (CSprite sprite in gameState.Enemies)
            {
                UpdatePosition(sprite, time_delta);
            }

            UpdatePosition(gameState.Player, time_delta);


            ///////////////////////////////////////////////////////////////////
            // Next we check if our player has reached the goal position.

            CPoint2f goalPositionPixels = CLevelUtils.GetPixelFromTileCoordinates(m_level.GoalPosition);

            if (IsInCollision(gameState.Player.Position, goalPositionPixels))
            {
                OnGoalReached(this, "You Won!! Goal Reached!!");
                return;
            }


            ///////////////////////////////////////////////////////////////////
            // Next we check each enemy in turn to see if the user has been
            // caught.

            foreach (CSprite sprite in gameState.Enemies)
            {
                if (IsInCollision(gameState.Player.Position, sprite.Position))
                {
                    OnPlayerCaught(this, "You Lose!! Player Caught!!");
                    break;
                }
            }
        }
        //****************************************************************//
        // This function updates the velocity of each enemy in the game   //
        // depending on whether it is in collision with a wall or an      //
        // alternative move is available (e.g. turn left or right). It    //
        // will only move backwards if no other move is available and a   //
        // dead end has been encountered.                                 //
        //****************************************************************//
        public void UpdateVelocities(CGameState gameState, float time_delta)
        {
            /////////////////////////////////////////////////
            // We only update the velocities of the enemies,
            // the player is done through keyboard events.

            /////////////////////////////////////////////////////////
            // Each enemy has a targetPosition aswell as a Position.
            // the target position is the centre of the square the enemy
            // is moving towards. this is done so that a monster always
            // walks along the centre of a corridor.
            // When we compute the velocity we are allowing the enemy to
            // change direction if he is close to a square centre.
            // If he is within 5 pixels of the target square we take the following steps:
            // 1. Update his position to be at the target position.
            // 2. Test if there are any available squares in any direction (forwards, left, right).
            // 3. If there are randomly select a direction and update velocity.
            // 4. Set the target as one complete tile in the new direction.
            // 5. If no squares are available set velocity to be backwards and target square the
            // next square backwards.


            foreach (CEnemy enemy in gameState.Enemies)
            {
                if (Math.Pow(enemy.TargetPosition.X - enemy.Position.X, 2.0) + Math.Pow(enemy.TargetPosition.Y - enemy.Position.Y, 2.0) <= AT_TARGET_TOLERANCE_SQ)
                {
                    /////////////////////////////////////////////////////////
                    // Move the enemy to the target position.

                    enemy.Position.X = enemy.TargetPosition.X;
                    enemy.Position.Y = enemy.TargetPosition.Y;

                    float xVel = 0.0f;
                    float yVel = 0.0f;


                    ////////////////////////////////////////////////////////
                    // Set the velocity to be a complete tile in the
                    // current direction.

                    if (enemy.Velocity.X != 0.0f)
                    {
                        xVel = Math.Sign(enemy.Velocity.X) * CGameTextures.TILE_SIZE;
                    }
                    else
                    {
                        yVel = Math.Sign(enemy.Velocity.Y) * CGameTextures.TILE_SIZE;
                    }

                    bool[] ValidMoves = new bool[3] {
                        false, false, false
                    };
                    bool valid_move_found = false;

                    CPoint2f testPos = new CPoint2f();


                    ////////////////////////////////////////////////////////
                    // At each central tile position we test if the monster
                    // can move in any direction other than backwards.

                    testPos.X = enemy.Position.X + xVel;
                    testPos.Y = enemy.Position.Y + yVel;

                    if (!IsInCollisionWithWall(testPos) && !IsInCollisionWithFire(testPos))
                    {
                        ValidMoves[0]    = true;
                        valid_move_found = true;
                    }

                    testPos.X = enemy.Position.X + yVel;
                    testPos.Y = enemy.Position.Y + xVel;

                    if (!IsInCollisionWithWall(testPos) && !IsInCollisionWithFire(testPos))
                    {
                        ValidMoves[1]    = true;
                        valid_move_found = true;
                    }

                    testPos.X = enemy.Position.X - yVel;
                    testPos.Y = enemy.Position.Y - xVel;

                    if (!IsInCollisionWithWall(testPos) && !IsInCollisionWithFire(testPos))
                    {
                        ValidMoves[2]    = true;
                        valid_move_found = true;
                    }


                    /////////////////////////////////////////////////////////
                    // If we've found a valid move we randomly select a new
                    // direction. Otherwise we move backwards (since this must
                    // be valid).

                    if (valid_move_found)
                    {
                        //////////////////////////////////////////////////////
                        // Find a valid random move (this is a little inefficient).

                        int i = m_randomGenerator.Next() % 3;
                        while (!ValidMoves[i])
                        {
                            i = m_randomGenerator.Next() % 3;
                        }

                        switch (i)
                        {
                        case 0:
                            enemy.TargetPosition.X = enemy.Position.X + xVel;
                            enemy.TargetPosition.Y = enemy.Position.Y + yVel;

                            enemy.Velocity.X = enemy.Velocity.X;
                            enemy.Velocity.Y = enemy.Velocity.Y;
                            break;

                        case 1:
                            enemy.TargetPosition.X = enemy.Position.X + yVel;
                            enemy.TargetPosition.Y = enemy.Position.Y + xVel;

                            float temp = enemy.Velocity.X;
                            enemy.Velocity.X = enemy.Velocity.Y;
                            enemy.Velocity.Y = temp;
                            break;

                        default:
                        case 2:
                            enemy.TargetPosition.X = enemy.Position.X - yVel;
                            enemy.TargetPosition.Y = enemy.Position.Y - xVel;

                            temp             = enemy.Velocity.X;
                            enemy.Velocity.X = -enemy.Velocity.Y;
                            enemy.Velocity.Y = -temp;
                            break;
                        }
                    }
                    else
                    {
                        ////////////////////////////////////////////////////////////
                        // No move is available so we will move backwards.

                        enemy.TargetPosition.X = enemy.Position.X - xVel;
                        enemy.TargetPosition.Y = enemy.Position.Y - yVel;

                        enemy.Velocity.X = -enemy.Velocity.X;
                        enemy.Velocity.Y = -enemy.Velocity.Y;
                    }
                }
            }
        }
        //****************************************************************//
        // This function is used as an event handler for the load click  *//
        // event. This is used to load a new level. In addition to       *//
        // the data required for the level it also ensures the board is  *//
        // displayed.                                                    *//
        //****************************************************************//
        private void btnLoad_Click(object sender, RoutedEventArgs e)
        {
            ////////////////////////////////////////////////////////////
            // clear any existing children from the canvas.

            cvsMainScreen.Children.Clear();

            ///////////////////////////////////////////////////////////
            // Get the directory where the level data is stored and
            // load the data in.

            string fileDir = txtLevelDir.Text;

            currentLevel = CLevelParser.ImportLevel(fileDir);
            gameTextures = CLevelParser.ImportTextures(fileDir);


            ///////////////////////////////////////////////////////////
            // Draw the set of wall and floor tiles for the current
            // level and the goal icon. This is part of the game
            // we do not expect to change as it cannot move.

            DrawLevel();


            //////////////////////////////////////////////////////////
            // Add a game state, this represents the position and velocity
            // of all the enemies and the player. Basically, anything
            // that is dynamic that we expect to move around.

            gameState = new CGameState(currentLevel.EnemyPositions.Count());


            ///////////////////////////////////////////////////////////
            // Set up the player to have the correct .bmp and set it to
            // its initial starting point. The player's position is stored
            // as a tile index on the Clevel class, this must be converted
            // to a pixel position on the game state.

            playerIcon        = new Image();
            playerIcon.Width  = CGameTextures.TILE_SIZE;
            playerIcon.Height = CGameTextures.TILE_SIZE;

            playerIcon.Source = gameTextures.PlayerIcon;

            cvsMainScreen.Children.Add(playerIcon);


            //////////////////////////////////////////////////////////
            // Create instances of the enemies and fires for display. We must do
            // this as each child on a canvas must be a distinct object,
            // we could not simply add the same image multiple times.

            enemyIcons = new Image[currentLevel.EnemyPositions.Count()];

            for (int i = 0; i < currentLevel.EnemyPositions.Count(); i++)
            {
                enemyIcons[i] = new Image();

                enemyIcons[i].Width  = CGameTextures.TILE_SIZE;
                enemyIcons[i].Height = CGameTextures.TILE_SIZE;

                enemyIcons[i].Source = gameTextures.EnemyIcon;

                cvsMainScreen.Children.Add(enemyIcons[i]);
            }


            fireIcons = new Image[currentLevel.FirePositions.Count()];

            for (int i = 0; i < currentLevel.FirePositions.Count(); i++)
            {
                fireIcons[i] = new Image();

                fireIcons[i].Width  = CGameTextures.TILE_SIZE;
                fireIcons[i].Height = CGameTextures.TILE_SIZE;

                fireIcons[i].Source = gameTextures.FireIcon;

                cvsMainScreen.Children.Add(fireIcons[i]);

                CPoint2i tilePosition = CLevelUtils.GetPixelFromTileCoordinates(new CPoint2i(currentLevel.FirePositions[i].X, currentLevel.FirePositions[i].Y));


                Canvas.SetLeft(fireIcons[i], tilePosition.X);
                Canvas.SetTop(fireIcons[i], tilePosition.Y);
            }

            loadTextures();
            ////////////////////////////////////////////////////////////
            // Set each instance of a dynamic object to its initial position
            // as defined by the current level object.

            InitialiseGameState();


            ////////////////////////////////////////////////////////////
            // Render the current game state, this will render the player
            // and the enemies in their initial position.

            RenderGameState();
        }