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

namespace AIStudio.Wpf.DiagramDesigner
{
    public static partial class DiagramViewModelHelper
    {
        static List<IAttachTo> AttachTos
        {
            get; set;
        } = new List<IAttachTo>();

        public static DesignerItemViewModelBase GetConnectorDataItem(IEnumerable<SelectableDesignerItemViewModelBase> items, Guid conectorDataItemId, Type connectorDataItemType)
        {
            DesignerItemViewModelBase dataItem = items.OfType<DesignerItemViewModelBase>().Single(x => x.Id == conectorDataItemId);
            return dataItem;
        }

        public static RectangleBase GetBoundingRectangle(IEnumerable<DesignerItemViewModelBase> items)
        {
            double x1 = Double.MaxValue;
            double y1 = Double.MaxValue;
            double x2 = Double.MinValue;
            double y2 = Double.MinValue;

            foreach (DesignerItemViewModelBase item in items)
            {
                x1 = Math.Min(item.Left, x1);
                y1 = Math.Min(item.Top, y1);

                x2 = Math.Max(item.Left + item.GetItemWidth(), x2);
                y2 = Math.Max(item.Top + item.GetItemHeight(), y2);
            }

            return new RectangleBase(new PointBase(x1, y1), new PointBase(x2, y2));
        }

        public static RectangleBase GetBoundingRectangle(DesignerItemViewModelBase item)
        {
            return GetBoundingRectangle(new DesignerItemViewModelBase[] { item });
        }

        #region 自动依附节点
        public static FullyCreatedConnectorInfo FindNearPortToAttachTo(this IDiagramViewModel diagramViewModel, ConnectionViewModel partialConnection, ConnectorVertexType connectorVertexType)
        {
            if (partialConnection == null)
                return null;

            diagramViewModel.ClearAttachTo();
            foreach (var port in diagramViewModel.Items.OfType<DesignerItemViewModelBase>().ToList().SelectMany(n => n.Connectors))
            {
                if (connectorVertexType == ConnectorVertexType.Start)
                {
                    if (partialConnection.SourceConnectorInfo.Position.DistanceTo(port.Position) < diagramViewModel.DiagramOption.SnappingOption.SnappingRadius)
                    {
                        if (partialConnection.SinkConnectorInfo?.CanAttachTo(port) == true)
                        {
                            port.DataItem.ShowConnectors = true;
                            diagramViewModel.AddAttachTo(port, true);
                            return port;
                        }
                        else
                        {
                            port.DataItem.ShowConnectors = true;
                            diagramViewModel.AddAttachTo(port, false);
                            return null;
                        }
                    }
                }
                else if (connectorVertexType == ConnectorVertexType.End)
                {
                    if (partialConnection.SinkConnectorInfo.Position.DistanceTo(port.Position) < diagramViewModel.DiagramOption.SnappingOption.SnappingRadius)
                    {
                        if (partialConnection.SourceConnectorInfo?.CanAttachTo(port) == true)
                        {
                            port.DataItem.ShowConnectors = true;
                            diagramViewModel.AddAttachTo(port, true);
                            return port;
                        }
                        else
                        {
                            port.DataItem.ShowConnectors = true;
                            diagramViewModel.AddAttachTo(port, false);
                            return null;
                        }
                    }
                }
            }

            return null;
        }

        public static FullyCreatedConnectorInfo FindNearPortToAttachTo(this IDiagramViewModel diagramViewModel, ConnectionViewModel partialConnection)
        {
            if (partialConnection == null)
                return null;

            diagramViewModel.ClearAttachTo();
            foreach (var port in diagramViewModel.Items.OfType<DesignerItemViewModelBase>().ToList().SelectMany(n => n.Connectors))
            {
                if (partialConnection.OnGoingPosition.DistanceTo(port.Position) < diagramViewModel.DiagramOption.SnappingOption.SnappingRadius)
                {
                    port.DataItem.ShowConnectors = true;
                    if (partialConnection.SourceConnectorInfo?.CanAttachTo(port) == true)
                    {
                        diagramViewModel.AddAttachTo(port, true);
                        return port;
                    }
                    else
                    {
                        diagramViewModel.AddAttachTo(port, false);
                        return null;
                    }

                }
            }        
            return null;
        }

        public static void AddAttachTo(this IDiagramViewModel diagramViewModel, IAttachTo item, bool beAttachTo)
        {
            if (beAttachTo)
            {
                item.BeAttachTo = true;
            }
            else
            {
                item.DisableAttachTo = true;
            }
            AttachTos.Add(item);
        }

        public static void ClearAttachTo(this IDiagramViewModel diagramViewModel)
        {
            AttachTos.ForEach(p => {
                p.DisableAttachTo = false;
                p.BeAttachTo = false;
            });
            AttachTos.Clear();
        }
        #endregion



    }
}
