public freeGraphLinkBase GetClone()
        {
            freeGraphLinkBase link = new freeGraphLinkBase();

            link.type      = type;
            link.weight    = weight;
            link.nodeNameA = nodeNameA;
            link.nodeNameB = nodeNameB;
            link.linkLabel = linkLabel;
            return(link);
        }
        /// <summary>
        /// Gets the link - order of nodeNameA and nodeNameB is irrelevant for the query
        /// </summary>
        /// <param name="nodeNameA">The node name a.</param>
        /// <param name="nodeNameB">The node name b.</param>
        /// <returns></returns>
        public freeGraphLinkBase GetLink(String nodeNameA, String nodeNameB)
        {
            freeGraphLinkBase output = null;

            String key = GetLinkKey(nodeNameA, nodeNameB);

            if (linkDictionary.ContainsKey(key))
            {
                return(linkDictionary[key]);
            }

            return(output);
        }
        /// <summary>
        /// Registers the link, returns true if this link is redundant
        /// </summary>
        /// <param name="link">The link.</param>
        /// <param name="nodeDictionary">The node dictionary.</param>
        /// <returns></returns>
        public Boolean RegisterLink(freeGraphLinkBase link, Dictionary <String, freeGraphNodeBase> nodeDictionary)
        {
            Boolean isRedundant = false;

            if (!linkedAtoBDictionary.ContainsKey(link.nodeNameA))
            {
                linkedAtoBDictionary.Add(link.nodeNameA, new List <freeGraphNodeBase>());
                linkAtoBDictionary.Add(link.nodeNameA, new List <freeGraphLinkBase>());
            }
            if (!linkedBtoADictionary.ContainsKey(link.nodeNameB))
            {
                linkedBtoADictionary.Add(link.nodeNameB, new List <freeGraphNodeBase>());
                linkBtoADictionary.Add(link.nodeNameB, new List <freeGraphLinkBase>());
            }

            //if (nodeDictionary.ContainsKey(link.nodeNameA) && nodeDictionary.ContainsKey(link.nodeNameB))
            //{
            //if (linkedAtoBDictionary.ContainsKey(link.nodeNameA))
            //{
            if (linkedAtoBDictionary[link.nodeNameA].Contains(nodeDictionary[link.nodeNameB]))
            {
                isRedundant = true;
            }
            //}
            //if (linkedBtoADictionary.ContainsKey(link.nodeNameB))
            //{
            if (linkedBtoADictionary[link.nodeNameB].Contains(nodeDictionary[link.nodeNameA]))
            {
                isRedundant = true;
            }
            //}
            //}

            if (isRedundant)
            {
            }
            else
            {
                linkedAtoBDictionary[link.nodeNameA].Add(nodeDictionary[link.nodeNameB]);
                linkedBtoADictionary[link.nodeNameB].Add(nodeDictionary[link.nodeNameA]);
                linkAtoBDictionary[link.nodeNameA].Add(link);
                linkBtoADictionary[link.nodeNameB].Add(link);
                String k = GetLinkKey(link.nodeNameA, link.nodeNameB);
                if (!linkDictionary.ContainsKey(k))
                {
                    linkDictionary.Add(k, link);
                }
            }
            return(isRedundant);
        }
        /// <summary>
        /// Adds link if not found, returns existing if found. Weight and type are not set to existing link
        /// </summary>
        /// <param name="nodeNameA">The node name a.</param>
        /// <param name="nodeNameB">The node name b.</param>
        /// <param name="weight">The weight.</param>
        /// <param name="type">The type.</param>
        /// <returns></returns>
        public freeGraphLinkBase AddLink(String nodeNameA, String nodeNameB, Double weight = 1, Int32 type = 0)
        {
            if (!ContainsLink(nodeNameA, nodeNameB, false))
            {
                freeGraphLinkBase link = new freeGraphLinkBase();
                link.nodeNameA = nodeNameA;
                link.nodeNameB = nodeNameB;
                link.weight    = weight;
                link.type      = type;
                links.Add(link);
                linkRegistry.RegisterLink(link, nodeDictionary);
                return(link);
            }

            return(GetLink(nodeNameA, nodeNameB, false));
        }
        /// <summary>
        /// Gets link in one or the other direction, otherwise returns null;
        /// </summary>
        /// <param name="nodeNameA">The node name a.</param>
        /// <param name="nodeNameB">The node name b.</param>
        /// <param name="includeBtoALinks">if set to <c>true</c> [include bto a links].</param>
        /// <returns></returns>
        public freeGraphLinkBase GetLink(String nodeNameA, String nodeNameB, Boolean includeBtoALinks = false)
        {
            freeGraphLinkBase output = null;

            if (IsReady)
            {
                output = linkRegistry.GetLink(nodeNameA, nodeNameB);
            }
            else
            {
                output = links.FirstOrDefault(x => (x.nodeNameA == nodeNameA) && (x.nodeNameB == nodeNameB));
                if ((output == null) && includeBtoALinks)
                {
                    output = links.FirstOrDefault(x => (x.nodeNameB == nodeNameA) && (x.nodeNameA == nodeNameB));
                }
            }
            return(output);
        }
        /// <summary>
        /// Returns link instance, detached from the <see cref="freeGraph"/> model
        /// </summary>
        /// <param name="link">The link.</param>
        /// <param name="skipCheck">if set to <c>true</c> [skip check].</param>
        /// <returns></returns>
        public freeGraphLink GetLinkInstance(freeGraphLinkBase link, Boolean skipCheck = true)
        {
            freeGraphLink output = new freeGraphLink(link.GetClone());

            output.nodeA = GetNode(link.nodeNameA, skipCheck);

            if (output.nodeA != null)
            {
                output.nodeA = output.nodeA.GetQueryResultClone(0);
            }

            output.nodeB = GetNode(link.nodeNameB, skipCheck);
            if (output.nodeB != null)
            {
                output.nodeB = output.nodeB.GetQueryResultClone(0);
            }

            return(output);
        }
 /// <summary>
 /// Adds new link into graph or sums weight of the specified and existing - and applies type that is greater
 /// </summary>
 /// <param name="link">The link.</param>
 public void AddLinkOrSum(freeGraphLinkBase link)
 {
     if (!ContainsLink(link.nodeNameA, link.nodeNameB, true))
     {
         AddLink(link.nodeNameA, link.nodeNameB, link.weight, link.type);
     }
     else
     {
         var exLink = GetLink(link.nodeNameA, link.nodeNameB);
         if (exLink != null)
         {
             exLink.weight += link.weight;
             exLink.type    = Math.Max(exLink.type, link.type);
         }
         else
         {
             AddLink(link.nodeNameA, link.nodeNameB, link.weight, link.type);
         }
     }
 }
 public freeGraphLink(freeGraphLinkBase link)
 {
     //type = link.type;
     //weight = link.weight;
     linkBase = link;
 }