using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Content;
using Audio3D;

namespace FredriksdalAssault2
{
    /// <summary>
    /// This class is used to store data about each player in a network game so that we can
    /// draw a soldier for each player and more. Implements IComparable so that we can sort player data
    /// on number of kills.
    /// </summary>
    public class NetworkPlayerProfile : PlayerProfile
    {

        #region Instance variables

        // Variables for soldier world matrix.
        public byte clipNumber;
        public Vector3 soldierPosition;
        public Quaternion rotation;
        public Vector3 direction;

        // The id of the killer
        public byte killedByGamerId;

        // Shot delay and shot countdown to slow shooting sound. 
        int shotDelay = 100;
        int shotCountdown = 0;

        #endregion

        #region Constructors

        /// <summary>
        /// Create a new network player profile
        /// </summary>
        /// <param name="gamerId"></param>
        /// <param name="gamerName"></param>
        public NetworkPlayerProfile(ContentManager content, byte gamerId, String gamerName, bool attacker, GraphicsDevice graphicsDevice)
            : base (content, gamerId, gamerName, attacker, graphicsDevice)
        {
            
            // Set the initial value for soldier position and initial clip number.
            this.soldierPosition = new Vector3(0, 8000, 0);
            this.clipNumber = 2;
        }

        #endregion

        #region Methods

        /// <summary>
        /// Update the network player profile.
        /// </summary>
        /// <param name="gameTime"></param>
        public override void UpdatePlayerProfile(GameTime gameTime, AudioManager audioManager)
        {
            // Update the simple soldier.
            if (this.isDead == false)
            {
                // A living soldier
                this.soldier.UpdateSimpleSoldier(gameTime, this.soldierPosition, this.rotation, this.clipNumber);

                // Update the direction for the soldier.
                Vector3 movement = Vector3.Zero + Vector3.Transform(new Vector3(0, 0, 10), this.rotation);
                Vector3 tempDirection = movement - Vector3.Zero;
                tempDirection.Normalize();
                this.direction = tempDirection * -1;

                // Update audio emitter options
                this.Position = this.soldierPosition;
                this.Forward = this.direction;
                this.Up = Vector3.Up;
                this.Velocity = this.direction * 4f;

                // Play the walking sound.
                if (this.clipNumber == 1)
                {
                    if (this.walkCountdown <= 0)
                    {
                        // For variety, choose between (footstep0 or footstep1).
                        string soundName;
                        if (this.walkSoundIndex == 0)
                        {
                            soundName = "footstep" + this.walkSoundIndex++;
                        }
                        else
                        {
                            soundName = "footstep" + this.walkSoundIndex--;
                        }

                        // Play the sound.
                        audioManager.Play3DSound(soundName, false, this);

                        // Reset the walking counter.
                        this.walkCountdown = this.walkDelay;
                    }
                    else
                    {
                        // Decrease the counter.
                        this.walkCountdown -= gameTime.ElapsedGameTime.Milliseconds;
                    }
                }

                // Play the sound, when the shot delay has been running out.
                if (shotCountdown <= 0)
                {
                    // Play the shooting sound.
                    if (this.isShooting == true)
                    {
                        audioManager.Play3DSound("fire", false, this);

                        // Reset the shot countdown
                        shotCountdown = shotDelay;
                    }   
                }
                else
                {
                    // Subract game time from the shotCountdown counter
                    shotCountdown -= gameTime.ElapsedGameTime.Milliseconds;
                }

            }
            else
            {
                // A dead soldier.
                this.soldier.UpdateDeadSoldier(gameTime, this.soldierPosition, this.rotation);
            }

        } // End of the UpdatePlayerProfile method

        /// <summary>
        /// Draw the enemy shot effect.
        /// </summary>
        /// <param name="gameTime"></param>
        /// <param name="view"></param>
        /// <param name="projection"></param>
        public override void DrawShotEffect(GameTime gameTime, Matrix view, Matrix projection)
        {
            // Update the enemy shot effect
            this.enemyShotParticles.UpdateEnemyShotEffect(gameTime);

            // If the player not is dead.
            if (this.isDead == false)
            {
                // Add a particle to the enemy shot effect if the player is shooting
                if (this.isShooting == true)
                {
                    Vector3 position = this.soldierPosition + new Vector3(0, 57.5f, 0) + this.direction * 40;
                    this.enemyShotParticles.AddParticles(1, position, this.direction);
                }

                // Draw the shot effect
                this.enemyShotParticles.DrawEnemyShotEffect(gameTime, view, projection);
            }

        } // End of the DrawShotEffect method

        #endregion

    } // End of the class

} // End of the namespace
