using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using SFML.Graphics;
using SFML.Window;
using YourBeatingHeart.Main.States.Play.Entities;

namespace YourBeatingHeart.Main.States.Play.Collision
{
    public class CollisionManager
    {
        private List<CollisionLine> lines;
        private List<Player> players;

        public CollisionManager()
        {
            lines = new List<CollisionLine>();
            players = new List<Player>();
        }

        public void Add(CollisionLine line)
        {
            lines.Add(line);
        }

        public void Add(Player player)
        {
            players.Add(player);
        }

        public void Remove(Player player)
        {
            players.Remove(player);
        }

        public void Clear()
        {
            lines.Clear();
        }

        /**
         * Restricts the movement of a player.
         * @param r  Player rectangle.
         * @param v  Vector of desired player movement.
         */
        public Vector2f Restrict(FloatRect r, Vector2f delta)
        {
            CollisionLine feet = new CollisionLine(r.Top + r.Height, r.Left, r.Left + r.Width);

            // only compute line collision when moving downward
            if (delta.Y > 0)
            {
                foreach (CollisionLine line in lines)
                {
                    if ((feet.Y <= line.Y) && (feet.Y + delta.Y > line.Y))
                    {
                        if (line.Left <= feet.Right && line.Right >= feet.Left) 
                        {
                            delta.Y = line.Y - feet.Y;
                        }
                    }
                }
            }

            // ensure you don't run out of the screen
            if (r.Left + delta.X < 0) 
                delta.X = -r.Left;
            if (r.Left + r.Width + delta.X > Constants.TARGET_WIDTH)
                delta.X = Constants.TARGET_WIDTH - r.Left - r.Width;

            return delta;
        }

        /**
         * Checks if the given rectangle collides with any player.
         * If it does, returns the player, otherwise returns null.
         */
        public Player PlayerCollision(FloatRect r)
        {
            foreach (Player player in players)
            {
                if (!player.Alive)
                    continue;

                FloatRect p = player.CollisionRect;
                if (p.Intersects(r))
                {
                    return player;
                }
            }
            return null;
        }

        public bool inTouchDownArea(Vector2f p)
        {
            return Constants.TOUCHDOWN_AREA.Contains(p.X, p.Y);
        }

    }

}
