using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;

namespace MegaManRipoff.MainGameClasses
{
    /// <summary>
    /// A special effect of an explosion, commonly used
    /// when an enemy is destroyed by the player.
    /// </summary>
    class ExplosionEffect : SpecialEffect
    {
        #region Member Variables

        /// <summary>
        /// The explosion's texture.
        /// </summary>
        static Texture2D _texture;

        /// <summary>
        /// The explosion sound effect.
        /// </summary>
        static SoundEffect _explodeSound;

        #endregion

        #region Constructors

        /// <summary>
        /// Creates a new explosion effect.
        /// </summary>
        /// <param name="room">The current room.</param>
        /// <param name="position">The position of the new explosion effect.</param>
        public ExplosionEffect(Room room, Vector2 position)
            : base(room, position, true)
        {
            //Play the explosion sound effect.
            _explodeSound.Play();
        }

        /// <summary>
        /// Creates a new explosion effect and an item.
        /// </summary>
        /// <param name="room">The current room.</param>
        /// <param name="position">The position of the new explosion effect.</param>
        /// <param name="itemType">The type of item to create. Use null to randomly
        /// create any item.</param>
        public ExplosionEffect(Room room, Vector2 position, Type itemType)
            : this(room, position)
        {
            //If the given type is null, randomly create an item. Otherwise, create
            //an instance of the given item.
            if (itemType == null)
                ItemCreator.CreateItem(room, position);
            else
                ItemCreator.CreateItem(room, position, itemType);
        }

        #endregion

        #region Methods

        /// <summary>
        /// Creates the animation for this explosion special effect.
        /// </summary>
        protected override void InitialiseAnimations()
        {
            //The only animation.
            _animation = new Animation(new Tuple<Rectangle, Vector2, int>
                (new Rectangle(0, 4, 24, 24), new Vector2(-12, -12), 2), 0);
            _animation.AddFrame(new Tuple<Rectangle, Vector2, int>
                (new Rectangle(24, 2, 28, 28), new Vector2(-14, -14), 2));
            _animation.AddFrame(new Tuple<Rectangle, Vector2, int>
                (new Rectangle(52, 1, 30, 30), new Vector2(-15, -15), 2));
            _animation.AddFrame(new Tuple<Rectangle, Vector2, int>
                (new Rectangle(82, 0, 32, 32), new Vector2(-16, -16), 2));
            _animation.AddFrame(new Tuple<Rectangle, Vector2, int>
                (new Rectangle(114, 1, 30, 30), new Vector2(-15, -15), 2));
            _animation.AddFrame(new Tuple<Rectangle, Vector2, int>
                (new Rectangle(144, 0, 32, 32), new Vector2(-16, -16), 2));
            _animation.AddFrame(new Tuple<Rectangle, Vector2, int>
                (new Rectangle(), Vector2.Zero, 0));

            base.InitialiseAnimations();
        }

        /// <summary>
        /// Loads the assets required for the explosion effect.
        /// </summary>
        /// <param name="content">The game's content manager.</param>
        public static void LoadContent(ContentManager content)
        {
            _texture = content.Load<Texture2D>("Images\\Explosion");

            _explodeSound = content.Load<SoundEffect>("Sounds\\EnemyDeath");
        }

        /// <summary>
        /// Draws the explosion effect to the screen.
        /// </summary>
        /// <param name="spriteBatch">The sprite batch to draw to.</param>
        public override void Draw(SpriteBatch spriteBatch)
        {
            //Get the necessary details from the current animation frame.
            Rectangle currentFrameSource = _animation.CurrentFrame.Item1;
            Vector2 currentFrameOffset = _animation.CurrentFrame.Item2;

            spriteBatch.Draw(_texture,
                                _position + new Vector2(currentFrameOffset.X, currentFrameOffset.Y),
                                currentFrameSource,
                                Color.White);
        }

        #endregion
    }
}
