using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using DevExpress.Data.WcfLinq.Helpers;
using PXP.Crawler.API.Designers;
using PXP.Crawler.API.Designers.Controls;

namespace PXP.Crawler.API.Model
{
    public class ProgramDesigner : Designer<Program>
    {
        internal Program program;

        internal SortedDictionary<Guid, SortedDictionary<int, NodeDesignerPin>> inPins = new SortedDictionary<Guid, SortedDictionary<int, NodeDesignerPin>>();
        internal SortedDictionary<Guid, SortedDictionary<int, NodeDesignerPin>> outPins = new SortedDictionary<Guid, SortedDictionary<int, NodeDesignerPin>>();
        internal int currDPID = 0;


        internal Dictionary<int, NodeDesignerPin> availableConnPins = new Dictionary<int, NodeDesignerPin>();


        public ProgramDesigner(Program designObject) : base(designObject)
        {
            this.program = designObject;
        }

        public int GetNewDesignerPinID()
        {
            currDPID++;
            return currDPID;
        }

        public void AddInPin(Type pinType, NodeDesignerPin pin)
        {
            if (!inPins.ContainsKey(pinType.GUID))
            {
                inPins.Add(pinType.GUID, new SortedDictionary<int, NodeDesignerPin>());
            }
            inPins[pinType.GUID].Add(pin.id, pin);
        }

        public void AddOutPin(Type pinType, NodeDesignerPin pin)
        {
            if (!outPins.ContainsKey(pinType.GUID))
            {
                outPins.Add(pinType.GUID, new SortedDictionary<int, NodeDesignerPin>());
            }
            outPins[pinType.GUID].Add(pin.id, pin);
        }

        public void AddPin(Type pinType, NodeDesignerPin pin)
        {
            if (pin.isOutput)
            {
                AddOutPin(pinType, pin);
            }
            else
            {
                AddInPin(pinType, pin);
            }
        }

        public Dictionary<int, NodeDesignerPin> GetAvailablePins(NodeDesignerPin pin)
        {
            Dictionary<int, NodeDesignerPin> avPins = new Dictionary<int, NodeDesignerPin>();
            
            NodeDesignerControl ndc = (NodeDesignerControl)pin.node.designer.control;

            if (pin.isOutput)
            {
                if (inPins.ContainsKey(pin.pinType.GUID))
                {
                    foreach (KeyValuePair<int, NodeDesignerPin> inPin in inPins[pin.pinType.GUID])
                    {
                        avPins.Add(inPin.Key, inPin.Value);
                    }

                }                

                foreach (NodeDesignerPin cip in ndc.pinsInput)
                {
                    avPins.Remove(cip.id);
                }
            }
            else
            {
                if (outPins.ContainsKey(pin.pinType.GUID))
                {
                    foreach (KeyValuePair<int, NodeDesignerPin> oPin in outPins[pin.pinType.GUID])
                    {
                        avPins.Add(oPin.Key, oPin.Value);
                    }

                }

                foreach (NodeDesignerPin cip in ndc.pinsOutput)
                {
                    avPins.Remove(cip.id);
                }
            }

            return avPins;
        }

        public void UpdateAvailableConnPins(NodeDesignerPin pin)
        {
            availableConnPins = GetAvailablePins(pin);
        }
    }
}
