using System;
using SFML.Graphics;
using SFML.Window;

namespace YourBeatingHeart.Main.Entities
{
    // A general entity. It's main use is to be updated and drawn.
    public abstract class Entity
    {
        public Game Game { get; private set; }

        public Vector2f _position;

        public Vector2f Position
        {
            get { return _position; }
            private set { _position = value; }
        }

        public int _layer;

        public int Layer
        {
            get { return _layer; }

            protected set
            {
                if (IsAdded)
                    throw new InvalidOperationException("You cannot change the layer while the object is in an EntityList.");

                _layer = value;
            }
        }

        public bool IsAdded { get; private set; }

        /// <summary>If this is set, the entity is queued for removal in its EntityList. It's upon your discretion to treat this Entity as non-existent if that is the case.</summary>
        public bool MarkedForRemoval { get; private set; }

        protected Entity(Game game, Vector2f position, float rotation = 0)
        {
            this.Game = game;
            IsAdded = false;

            Position = position;

            _layer = 0;
        }

        public virtual void Added()
        {
            IsAdded = true;
        }

        public virtual void Removed()
        {
            IsAdded = false;
        }

        public abstract void Update(float elapsedTime);

        public abstract void Draw(RenderTarget renderTarget);

        public virtual bool Move(float dx, float dy)
        {
            return Set(Position.X + dx, Position.Y + dy);
        }

        public bool Set(Vector2f vector)
        {
            return Set(vector.X, vector.Y);
        }

        public virtual bool Set(float x, float y)
        {
            _position.X = x;
            _position.Y = y;

            return true;
        }

        /// <summary>Only to be called by EntityList: Marks the Entity as queued for removal.</summary>
        public void MarkForRemoval()
        {
            MarkedForRemoval = true;
        }
    }
}
