using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace AIStudio.Wpf.DiagramDesigner.Algorithms
{
    public static class LinksReconnectionAlgorithms
    {
        public static void ReconnectLinksToClosestPorts(this IDiagramViewModel diagram)
        {
            // Only refresh ports once
            //var portsToRefresh = new HashSet<FullyCreatedConnectorInfo>();

            foreach (var link in diagram.Items.OfType<ConnectionViewModel>())
            {
                if (link.IsFullConnection == false)
                    continue;

                var sourcePorts = link.SourceConnectorInfo.DataItem.Connectors;
                var targetPorts = link.SinkConnectorInfoFully.DataItem.Connectors;

                // Find the ports with minimal distance
                var minDistance = double.MaxValue;
                var minSourcePort = link.SourceConnectorInfo;
                var minTargetPort = link.SinkConnectorInfoFully;
                foreach (var sourcePort in sourcePorts)
                {
                    foreach (var targetPort in targetPorts)
                    {
                        var distance = sourcePort.Position.DistanceTo(targetPort.Position);
                        if (distance < minDistance)
                        {
                            minDistance = distance;
                            minSourcePort = sourcePort;
                            minTargetPort = targetPort;
                        }
                    }
                }

                // Reconnect
                if (link.SourceConnectorInfo != minSourcePort)
                {
                    //portsToRefresh.Add(link.SourceConnectorInfo);
                    //portsToRefresh.Add(minSourcePort);
                    link.SetSourcePort(minSourcePort);
                }

                if (link.SinkConnectorInfo != minTargetPort)
                {
                    //portsToRefresh.Add(link.SinkConnectorInfoFully);
                    //portsToRefresh.Add(minTargetPort);
                    link.SetSinkPort(minTargetPort);
                }
            }

            //foreach (var port in portsToRefresh)
            //    port.Refresh();
        }
    }
}
