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

namespace MegaManRipoff.MainGameClasses
{
    /// <summary>
    /// A big, flashy and powerful bullet. Its sprite flips depending on its
    /// horizontal velocity.
    /// </summary>
    class BigBullet : Bullet
    {
        #region Member Variables

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

        /// <summary>
        /// Determines if the bullet has been deflected by an invincible
        /// enemy.
        /// </summary>
        bool _deflected;

        #endregion

        #region Properties

        /// <summary>
        /// Gets the big bullet's hitbox.
        /// </summary>
        public override Rectangle Hitbox
        {
            get
            { 
                //If the bullet is being reflected, return a useless hitbox.
                if (_deflected)
                    return new Rectangle();
                else
                    return new Rectangle((int)_position.X - 17, (int)_position.Y - 15, 35, 31);
            }
        }

        #endregion

        /// <summary>
        /// Creates a new big bullet.
        /// </summary>
        /// <param name="room">The reference to the current room.</param>
        /// <param name="position">The position to create the bullet.</param>
        /// <param name="bulletOwner">The entity that created the bullet.</param>
        /// <param name="damage">How much damage the bullet should deal.</param>
        /// <param name="speed">The bullet's speed vector.</param>
        /// <param name="destroyOnCollision">Whether or not the bullet should be destroyed
        /// when a collision is encountered.</param>
        public BigBullet(Room room, Vector2 position, Entity bulletOwner, int damage,
            Vector2 speed, bool destroyOnCollision)
            : base(room, position, bulletOwner, damage, speed, destroyOnCollision, true)
        {
        }

        #region Methods

        /// <summary>
        /// Create all animations associated with this bullet.
        /// </summary>
        protected override void InitialiseAnimations()
        {
            //The only animation.
            _animation = new Animation(new Tuple<Rectangle, Vector2, int>
                (new Rectangle(0, 0, 35, 31), new Vector2(-17, -15), 5), 0);
            _animation.AddFrame(new Tuple<Rectangle, Vector2, int>
                (new Rectangle(35, 0, 35, 31), new Vector2(-17, -15), 5));
            _animation.AddFrame(new Tuple<Rectangle, Vector2, int>
                (new Rectangle(70, 0, 35, 31), new Vector2(-17, -15), 5));
        }

        /// <summary>
        /// Load all assests asscociated with this entity.
        /// </summary>
        /// <param name="content">The content manager to load to.</param>
        public static void LoadContent(ContentManager content)
        {
            //Load in a default texture.
            _texture = content.Load<Texture2D>("Images/BigBullet");
        }

        /// <summary>
        /// Causes this bullet to be deflected (and thus useless).
        /// </summary>
        public override void Deflect()
        {
            //Change this bullet's speed vector so that its going backwards
            //and up.
            _speed = EntityHelper.RadialToVector(_speed.X,
                MathHelper.ToRadians(180 + (45 * Math.Sign(_speed.X))));

            _deflected = true;
        }

        /// <summary>
        /// Moves the bullet according to its speed, and removes the bullet
        /// should it leave the camera view.
        /// </summary>
        /// <param name="gameTime"></param>
        public override void Update(GameTime gameTime)
        {
            //If we leave the camera view, remove this bullet from the room.
            if (!_room.Camera.IsInView(_position, _animation))
                Remove();

            //Update the animation.
            _animation.Update();

            base.Update(gameTime);
        }

        /// <summary>
        /// Draw the bullet 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;

            //Flip the sprite according to its speed vector.
            SpriteEffects directionEffects;
            if (_speed.X < 0)
                directionEffects = SpriteEffects.FlipHorizontally;
            else
                directionEffects = SpriteEffects.None;

            spriteBatch.Draw(_texture,
                                _position + currentFrameOffset,
                                currentFrameSource,
                                Color.White,
                                0,
                                Vector2.Zero,
                                1,
                                directionEffects,
                                0.3f);
        }

        #endregion
    }
}
