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

namespace AIStudio.Wpf.DiagramDesigner
{
    public class BlockConnectorInfo : FullyCreatedConnectorInfo
    {
        public BlockConnectorInfo(DesignerItemViewModelBase dataItem, ConnectorOrientation orientation) : this(null, dataItem, orientation)
        {

        }

        public BlockConnectorInfo(IDiagramViewModel root, DesignerItemViewModelBase dataItem, ConnectorOrientation orientation) : base(root, dataItem, orientation)
        {
            if (Orientation == ConnectorOrientation.Left || Orientation == ConnectorOrientation.Right)
            {
                ConnectorWidth = 4;
                ConnectorHeight = double.NaN;
            }
            else if (Orientation == ConnectorOrientation.Top || Orientation == ConnectorOrientation.Bottom)
            {
                ConnectorWidth = double.NaN;
                ConnectorHeight = 4;
            }
        } 

        public BlockConnectorInfo(IDiagramViewModel root, DesignerItemViewModelBase dataItem, SerializableItem serializableItem, string serializableType) : base(root, dataItem, serializableItem, serializableType)
        {
        }

        public BlockConnectorInfo(IDiagramViewModel root, DesignerItemViewModelBase dataItem, SelectableItemBase designer) : base(root, dataItem, designer)
        {
        }

        protected override void InitNew()
        {
            base.InitNew();
            ColorViewModel.LineColor.Color = Colors.Transparent;
            ColorViewModel.FillColor.Color = Colors.Transparent;
        }

        public new BlockDesignerItemViewModel DataItem
        {
            get
            {
                return Parent as BlockDesignerItemViewModel;
            }
        }

        public override bool CanAttachTo(ConnectorInfoBase port)
        {
            if (port is BlockConnectorInfo blockConnectorInfo)
            {
                return port != this && !port.IsReadOnly && DataItem != blockConnectorInfo.DataItem;
            }
            else
            {
                return false;
            }
        }

        public PointBase LeftPosition
        {
            get
            {
                return new PointBase(MiddlePosition.X - DataItem.GetItemWidth() / 2, MiddlePosition.Y);
            }
        }

        public PointBase RightPosition
        {
            get
            {
                return new PointBase(MiddlePosition.X + DataItem.GetItemWidth() / 2, MiddlePosition.Y);
            }
        }

        public double DistanceTo(BlockConnectorInfo port)
        {
            PointBase p0 = port.LeftPosition;
            PointBase p1 = port.RightPosition;
            PointBase p2 = LeftPosition;
            PointBase p3 = RightPosition;
            var distance1 = DistanceTo(p0, p1, p2);
            var distance2 = DistanceTo(p0, p1, p3);
            var distance3 = DistanceTo(p2, p3, p0);
            var distance4 = DistanceTo(p2, p3, p1);

            return Math.Min(Math.Min(distance1, distance2), Math.Min(distance3, distance4));
        }

        double DistanceTo(PointBase A, PointBase B, PointBase P)      //点P到线段AB的最短距离
        {
            double r = ((P.X - A.X) * (B.X - A.X) + (P.Y - A.Y) * (B.Y - A.Y)) / DistanceToPow(A, B);
            if (r <= 0) return Math.Sqrt(DistanceToPow(A, P));
            else if (r >= 1) return Math.Sqrt(DistanceToPow(B, P));
            else
            {
                double AC = r * Math.Sqrt(DistanceToPow(A, B));
                return Math.Sqrt(DistanceToPow(A, P) - AC * AC);
            }
        }

        double DistanceToPow(PointBase a, PointBase b)                //点a、b距离的平方
        {
            return (a.X - b.X) * (a.X - b.X) + (a.Y - b.Y) * (a.Y - b.Y);
        }

    }
}
