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

namespace GhostArena6
{
    public class Bullet
    {
        private Direction _direction;
        private Vector2 _location;
        private bool _alive;

        public Vector2 Location
        {
            get { return _location; }
        }

        public Direction BulletDirection
        {
            get { return _direction; }
        }

        public bool IsAlive
        {
            get { return _alive; }
        }

        public Bullet(Direction dir,Vector2 location)
        {
            _direction = dir;
            _location = location;
            _alive = true;
        }

        public void Update()
        {
            if (_alive)
            {
                switch (_direction)
                {
                    case Direction.East:
                        _location.X += 4.0f;;

                        break;

                    case Direction.North:

                        _location.Y -= 4.0f;;

                        break;

                    case Direction.NorthEast:

                        _location.Y -= 3.0f;;
                        _location.X += 3.0f;;

                        break;

                    case Direction.NorthWest:

                        _location.Y -= 3.0f;;
                        _location.X -= 3.0f;;

                        break;

                    case Direction.South:

                        _location.Y += 4.0f;;
                        break;

                    case Direction.SouthEast:

                        _location.Y += 3.0f;;
                        _location.X += 3.0f;;
                        break;

                    case Direction.SouthWest:

                        _location.Y += 3.0f;;
                        _location.X -= 3.0f;;
                        break;

                    case Direction.West:

                        _location.X -= 4.0f;;
                        break;
                }
            }

            if (_location.X < 20 || _location.X > Game1.ScreenWidth - 20 || _location.Y < 88 || _location.Y > Game1.ScreenHeight - 20)
                _alive = false;

        }

        public void Kill()
        {
            _alive = false;
            _location = Vector2.Zero;
        }

        public void Spawn(Direction dir, Vector2 loc)
        {
            _direction = dir;
            _location = loc;
            _alive = true;
        }
    }
    
    public class BulletManager : List<Bullet>
    {
        private static Vector2[] _bulletOffset;

        private Texture2D _bulletTexture;

        private Rectangle _bulletRect;

        private float _lastBulletSpawnTime;

        private int _shotsFired;
        private int _shotsHit;

        public int ShotsFired
        {
            get { return _shotsFired; }
        }

        public int ShotsHit
        {
            get { return _shotsHit; }
        }

        public BulletManager(Game game)
            : base(5)
        {
            _bulletOffset = new Vector2[8];
            _bulletOffset[0] = new Vector2(0,-33);
            _bulletOffset[1] = new Vector2(24,-25);
            _bulletOffset[2] = new Vector2(33,0);
            _bulletOffset[3] = new Vector2(24,25);
            _bulletOffset[4] = new Vector2(0,33);
            _bulletOffset[5] = new Vector2(-24,25);
            _bulletOffset[6] = new Vector2(-33,0);
            _bulletOffset[7] = new Vector2(-24,-25);

            ContentManager content = new ContentManager(game.Services);

            _bulletTexture = content.Load<Texture2D>("Content/bullet");

            _bulletRect = new Rectangle(0, 0, 2, 6);

            _lastBulletSpawnTime = 1.0f;

            _shotsFired = 0;
            _shotsHit = 0;

        }
        
        public bool Spawn(Direction dir, Vector2 location)
        {
            bool bRet = false;

            if (this.Count < 5)
            {
                this.Add(new Bullet(dir, location + _bulletOffset[(int)dir]));
                bRet = true;
            }
            else
            {
                //check to see if any bullet is no longer alive
                foreach (Bullet bullet in this)
                    if (bullet.IsAlive == false)
                    {
                        bullet.Spawn(dir, location + _bulletOffset[(int)dir]);
                        bRet = true;
                        break;
                    }
            }

            if (bRet)
                _shotsFired++;

            return bRet;
        }

        public void Update()
        {
            foreach (Bullet bullet in this)
                bullet.Update();
        }

        public void Draw(SpriteBatch sb)
        {
            Vector2 origin = new Vector2(_bulletTexture.Width / 2, _bulletTexture.Height / 2);
            float rot;

            foreach (Bullet bullet in this)
            {
                if (bullet.IsAlive)
                {
                    rot = (int)bullet.BulletDirection * MathHelper.ToRadians(45.0f);

                    sb.Draw(_bulletTexture, new Rectangle((int)bullet.Location.X, (int)bullet.Location.Y, 2, 6), _bulletRect, Color.White, rot, origin, SpriteEffects.None, 0.0f);
                }
            }
        }

        public bool CheckCollision(Entity entity)
        {
            bool ret = false;

            BoundingBox entityBox = new BoundingBox(new Vector3(entity.Location.X, entity.Location.Y, 0),
                new Vector3(entity.Location.X + entity.FrameWidth, entity.Location.Y + entity.FrameWidth, 0));

            foreach (Bullet bullet in this)
            {
                BoundingBox bulletBox = new BoundingBox(new Vector3(bullet.Location.X, bullet.Location.Y, 0),
                    new Vector3(bullet.Location.X + 2, bullet.Location.Y + 6, 0));

                if (entityBox.Intersects(bulletBox))
                {
                    bullet.Kill();

                    _shotsHit++;

                    ret = true;
                    break;
                }
            }

            return ret;
        }

    }
}
