using System;

namespace Sledgemapper.Shared.Entities
{
    public abstract class BaseMapEntity
    {
        public BaseMapEntity()
        {
            Timestamp = DateTime.UtcNow.Ticks;
        }

        public int X { get; set; }
        public int Y { get; set; }
        public string ID { get; set; }
        public int Rotation { get; set; }
        public override string ToString()
        {
            return $"{X}_{Y}";
        }
        public double Timestamp { get; set; }
    }

    public class Ping : BaseMapEntity
    {
        public Player Player { get; set; }
        public int Iterations {get;set;}
        public double StartTime {get;set;}
    }

    public class Tile : BaseMapEntity
    {

        public bool Equals(Tile other)
        {
            if (other == null) return false;
            return (X == other.X && Y == other.Y);
        }

        public static bool operator ==(Tile a, Tile b)
        {
            // If both are null, or both are same instance, return true.
            if (System.Object.ReferenceEquals(a, b))
            {
                return true;
            }

            // If one is null, but not both, return false.
            if (((object)a == null) || ((object)b == null))
            {
                return false;
            }

            // Return true if the fields match:
            return a.X == b.X && a.Y == b.Y;
        }

        public static bool operator !=(Tile a, Tile b)
        {
            return !(a == b);
        }


        public override bool Equals(object obj)
        {
            //
            // See the full list of guidelines at
            //   http://go.microsoft.com/fwlink/?LinkID=85237
            // and also the guidance for operator== at
            //   http://go.microsoft.com/fwlink/?LinkId=85238
            //

            if (obj == null || GetType() != obj.GetType())
            {
                return false;
            }

            return Equals(obj as Tile);
        }

        // override object.GetHashCode
        public override int GetHashCode()
        {
            unchecked
            {
                int hash = 13;
                hash = (hash * 7) + X + Y;
                return hash;
            }
        }
    }

    public class Line : BaseMapEntity
    {
        public SnapPoint Start { get; set; }
        public SnapPoint End { get; set; }
        public float Width { get; set; }

        public override string ToString()
        {
            return $"{Start.X}_{Start.Y}_{Start.Index}_{End.X}_{End.Y}_{End.Index}";
        }
    }

    public class Room : BaseMapEntity
    {
        public SnapPoint Start { get; set; }
        public SnapPoint End { get; set; }
        public bool Delete { get; set; }

        public override string ToString()
        {
            return $"{Start.X}_{Start.Y}_{Start.Index}_{End.X}_{End.Y}_{End.Index}";
        }
    }

    public class SnapPoint : BaseMapEntity
    {
        public int Index { get; set; }

        public override string ToString()
        {
            return $"{X}_{Y}_{Index}";
        }
    }
}
