using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Media;
using AIStudio.Wpf.DiagramDesigner.Geometrys;
using AIStudio.Wpf.DiagramDesigner.Models;

namespace AIStudio.Wpf.DiagramDesigner
{
    public class ConnectorPointModel : SelectableViewModelBase
    {
        public ConnectorPointModel() : this(null)
        {

        }

        public ConnectorPointModel(IDiagramViewModel root) : base(root)
        {

        }

        public ConnectorPointModel(IDiagramViewModel root, SelectableItemBase designer) : base(root, designer)
        {

        }

        public ConnectorPointModel(IDiagramViewModel root, SerializableItem serializableItem, string serializableType) : base(root, serializableItem, serializableType)
        {

        }

        public ConnectorPointModel(PointBase point) : this()
        {
            X = point.X;
            Y = point.Y;
        }

        public ConnectorPointModel(double x, double y) : this()
        {
            X = x;
            Y = y;
        }

        public override SelectableItemBase GetSerializableObject()
        {
            return new ConnectorPointItem(this);
        }

        protected override void Init(IDiagramViewModel root, bool initNew)
        {
            base.Init(root, initNew);
        }

        protected override void InitNew()
        {
            ColorViewModel = new ColorViewModel()
            {
                LineColor = new ColorObject() { Color = Color.FromArgb(0xAA, 0x00, 0x00, 0x80) },
                FillColor = new ColorObject() { Color = Colors.White },
            };
        }

        protected override void LoadDesignerItemViewModel(SelectableItemBase designerbase)
        {
            base.LoadDesignerItemViewModel(designerbase);

            if (designerbase is ConnectorPointItem designer)
            {
                X = designer.X;
                Y = designer.Y;
                ConnectorWidth = designer.ConnectorWidth;
                ConnectorHeight = designer.ConnectorHeight;
            }
        }      

        /// <summary>
        /// 中间X
        /// </summary>
        private double _x;
        public double X
        {
            get
            {
                return _x;
            }
            set
            {
                if (SetProperty(ref _x, value))
                {
                    RaisePropertyChanged(nameof(Left));
                }
            }
        }

        /// <summary>
        /// 中间Y
        /// </summary>
        private double _y;
        public double Y
        {
            get
            {
                return _y;
            }
            set
            {
                if (SetProperty(ref _y, value))
                {
                    RaisePropertyChanged(nameof(Top));
                }
            }
        }

        /// <summary>
        /// 边界Left
        /// </summary>
        public double Left
        {
            get
            {
                return X - ConnectorWidth / 2;
            }
        }

        /// <summary>
        ///  边界Top
        /// </summary>
        public double Top
        {
            get
            {
                return Y - ConnectorHeight / 2;
            }
        }

        public virtual PointBase Position
        {
            get
            {
                return new PointBase(Left, Top);
            }
        }
        public virtual PointBase MiddlePosition => new PointBase(X, Y);

        private double _connectorWidth = 8;
        public double ConnectorWidth
        {
            get
            {
                return _connectorWidth;
            }
            set
            {
                _connectorWidth = value;
            }
        }

        private double _connectorHeight = 8;
        public double ConnectorHeight
        {
            get
            {
                return _connectorHeight;
            }
            set
            {
                _connectorHeight = value;
            }
        }

        private bool _dragStart;
        public bool DragStart
        {
            get
            {
                return _dragStart;
            }
            set
            {
                SetProperty(ref _dragStart, value);
            }
        }

        public void SetPosition(PointBase position)
        {
            X = position.X;
            Y = position.Y;
        }

        public static ConnectorPointModel operator -(ConnectorPointModel a, ConnectorPointModel b)
        {
            return new ConnectorPointModel(a.X - b.X, a.Y - b.Y);
        }
        public static ConnectorPointModel operator +(ConnectorPointModel a, ConnectorPointModel b)
        {
            return new ConnectorPointModel(a.X + b.X, a.Y + b.Y);
        }

        public static implicit operator ConnectorPointModel(PointBase point)
        {
            return new ConnectorPointModel(point);
        }

        public static implicit operator PointBase(ConnectorPointModel pointInfoBase)
        {
            return new PointBase(pointInfoBase.X, pointInfoBase.Y);
        }

        public static List<ConnectorPointModel> ToList(List<PointBase> lst)
        {
            return lst.Select(p => (ConnectorPointModel)p).ToList();
        }

        public override string ToString() => $"ConnectorPoint(x={X}, y={Y})";
    }
}
