//Resets link related values
 private void DeselectLink()
 {
     this.selectedLink              = null;
     this.Node1NumericUpDown.Value  = 0;
     this.Node2NumericUpDown.Value  = 0;
     this.WeightNumericUpDown.Value = 0;
 }
        //If there is a selected link check if inputed nodes both exist and are different
        //and a link doesn't already exist between them.
        //If it doesn't call RemoveLink in graph with than call AddLink method in graph and set it as the selected link
        //and redraw panel.
        //If a link already exists then check if new and old weights are different.
        //If they are change the weight and redraw panel.
        private void EditLinkButton_Click(object sender, EventArgs e)
        {
            if (this.selectedLink != null)
            {
                INode newNode1  = this.graph.Nodes.FirstOrDefault(n => n.NodeNumber == this.Node1NumericUpDown.Value);
                INode newNode2  = this.graph.Nodes.FirstOrDefault(n => n.NodeNumber == this.Node2NumericUpDown.Value);
                int   newWeight = (int)this.WeightNumericUpDown.Value;

                if (newNode1 != null && newNode2 != null && newNode1 != newNode2)
                {
                    bool linkExists = newNode1.ConnectedLinks.Any(l =>
                                                                  (l.ConnectedNodes.Item1 == newNode1 && l.ConnectedNodes.Item2 == newNode2) ||
                                                                  (l.ConnectedNodes.Item2 == newNode1 && l.ConnectedNodes.Item1 == newNode2));

                    if (!linkExists)
                    {
                        this.graph.RemoveLink(this.selectedLink.Link);
                        this.selectedLink = new LinkDraw(this.graph.AddLink(newNode1, newNode2, newWeight));

                        this.Visualization.Refresh();
                    }
                    else if (linkExists && newWeight != this.selectedLink.Link.Weight)
                    {
                        this.selectedLink.Link.ChangeWeight(newWeight);

                        this.Visualization.Refresh();
                    }
                }
            }
        }
        public GraphCreator(IGraph graph, IExporter exporter, IImporter importer)
        {
            InitializeComponent();

            this.graph           = graph;
            this.exporter        = exporter;
            this.importer        = importer;
            this.selectedLink    = null;
            this.selectedNode    = null;
            this.currentMaxLayer = DEFAULT_CURRENT_MAX_LAYER;
            this.source          = null;
            this.destination     = null;
        }
        //If a mouse button is presed saves coordinates of cursor.
        //If its the left mouse button visually deselect link or node if any.
        //Than check if cursor is on any node.
        //If true than increase current layer, deselect link, set node to selected node change its layer and redraw it in red.
        //If false then check if currsor is on any link
        //If true then deselect node, set link as selected link, redraw it and set its values from input.
        //If cursor is not on any link or node then deselect currently selected node and link if any
        private void Visualization_MouseDown(object sender, MouseEventArgs e)
        {
            this.mouseDownXCoordinate = e.X;
            this.mouseDownYCoordinate = e.Y;

            if (e.Button == MouseButtons.Left)
            {
                IPoint cursorPosition = new Point(e.X, e.Y);

                if (this.selectedNode != null)
                {
                    if (this.source != null && this.selectedNode.Node == this.source.Node)
                    {
                        this.selectedNode.Draw(this.Visualization.CreateGraphics(), Color.Blue);
                    }
                    else if (this.destination != null && this.selectedNode.Node == this.destination.Node)
                    {
                        this.selectedNode.Draw(this.Visualization.CreateGraphics(), Color.Green);
                    }
                    else
                    {
                        this.selectedNode.Draw(this.Visualization.CreateGraphics(), Color.Black);
                    }
                }

                if (this.selectedLink != null)
                {
                    this.selectedLink.Draw(this.Visualization.CreateGraphics(), Color.Black);
                }

                bool cursorIsOnAnyLinkOrNode = false;

                foreach (INode node in this.graph.Nodes.OrderByDescending(n => n.Layer))
                {
                    bool isInsideNode = node.Contains(cursorPosition);

                    if (isInsideNode)
                    {
                        this.currentMaxLayer += 1;

                        this.selectedNode = new NodeDraw(node);
                        DeselectLink();

                        this.selectedNode.Node.ChangeCurrentLayer(this.currentMaxLayer);

                        this.selectedNode.Draw(this.Visualization.CreateGraphics(), Color.Red);

                        cursorIsOnAnyLinkOrNode = true;

                        break;
                    }
                }
                if (!cursorIsOnAnyLinkOrNode)
                {
                    foreach (INode node in this.graph.Nodes)
                    {
                        foreach (ILink link in node.ConnectedLinks)
                        {
                            bool isInsideLink = link.Contains(cursorPosition);

                            if (isInsideLink)
                            {
                                this.selectedLink = new LinkDraw(link);
                                this.selectedNode = null;

                                this.selectedLink.Draw(this.Visualization.CreateGraphics(), Color.Red);

                                this.Node1NumericUpDown.Value  = this.selectedLink.Link.ConnectedNodes.Item1.NodeNumber;
                                this.Node2NumericUpDown.Value  = this.selectedLink.Link.ConnectedNodes.Item2.NodeNumber;
                                this.WeightNumericUpDown.Value = this.selectedLink.Link.Weight;

                                cursorIsOnAnyLinkOrNode = true;

                                break;
                            }
                        }

                        if (cursorIsOnAnyLinkOrNode)
                        {
                            break;
                        }
                    }
                }

                if (!cursorIsOnAnyLinkOrNode)
                {
                    this.selectedNode = null;
                    DeselectLink();
                }
            }
        }