/// <summary>
        /// Warning : there are events on collection DestConnector, SourceConnector, Points
        /// </summary>
        /// <returns></returns>
        public ConnectionViewModel Copy()
        {
            ConnectionViewModel newConn = new ConnectionViewModel();

            newConn.DestConnector        = DestConnector;
            newConn.DestConnectorHotspot = DestConnectorHotspot;
            newConn.Points                 = Points;
            newConn.SourceConnector        = SourceConnector;
            newConn.SourceConnectorHotspot = SourceConnectorHotspot;

            return(newConn);
        }
        public void BuildGraph(Node root)
        {
            if (!root.ChildNodes.Any())
            return;

              this.prevPosition = this.prevPosition + this.verticalOffset;
              var rootBlock = this.CreateNode(root.Payload.ToString(), new Point(10, 10));
              foreach (var childNode in root.ChildNodes)
              {
            var childBlock = this.CreateNode(childNode.Payload.ToString(), new Point(10, prevPosition));
            var connection = new ConnectionViewModel
            {
              SourceConnector = rootBlock.Connectors[2],
              DestConnector = childBlock.Connectors[0]
            };
            this.Network.Connections.Add(connection);
              }
              foreach (var child in root.ChildNodes)
            this.BuildGraph(child);
        }
 /// <summary>
 /// Called as the user continues to drag the connection.
 /// </summary>
 public void ConnectionDragging(Point curDragPoint, ConnectionViewModel connection)
 {
     if (connection.DestConnector == null)
     {
         connection.DestConnectorHotspot = curDragPoint;
     }
     else
     {
         connection.SourceConnectorHotspot = curDragPoint;
     }
 }
        /// <summary>
        /// Called when the user has finished dragging out the new connection.
        /// </summary>
        public void ConnectionDragCompleted(ConnectionViewModel newConnection, ConnectorViewModel connectorDraggedOut, ConnectorViewModel connectorDraggedOver)
        {
            if (connectorDraggedOver == null)
            {
                //
                // The connection was unsuccessful.
                // Maybe the user dragged it out and dropped it in empty space.
                //
                this.Network.Connections.Remove(newConnection);
                return;
            }

            //
            // Only allow connections from output connector to input connector (ie each
            // connector must have a different type).
            // Also only allocation from one node to another, never one node back to the same node.
            //
            bool connectionOk = connectorDraggedOut.ParentNode != connectorDraggedOver.ParentNode &&
                                connectorDraggedOut.Type != connectorDraggedOver.Type
                                && connectorDraggedOver.AttachedConnections.Count == 0;

            if (!connectionOk)
            {
                //
                // Connections between connectors that have the same type,
                // eg input -> input or output -> output, are not allowed,
                // Remove the connection.
                //
                this.Network.Connections.Remove(newConnection);
                return;
            }

            //
            // The user has dragged the connection on top of another valid connector.
            //

            //
            // Remove any existing connection between the same two connectors.
            //
            var existingConnection = FindConnection(connectorDraggedOut, connectorDraggedOver);
            if (existingConnection != null)
            {
                this.Network.Connections.Remove(existingConnection);
            }

            //
            // Finalize the connection by attaching it to the connector
            // that the user dragged the mouse over.
            //
            if (newConnection.DestConnector == null)
            {
                newConnection.DestConnector = connectorDraggedOver;
            }
            else
            {
                newConnection.SourceConnector = connectorDraggedOver;
            }

            if (newConnection.DestConnector != null && newConnection.SourceConnector != null)
            {
                LibnoiseNode sourceNode = newConnection.SourceConnector.ParentNode.Module;
                LibnoiseNode destinationNode = newConnection.DestConnector.ParentNode.Module;
                ModuleBase sourceModule = newConnection.SourceConnector.ParentNode.Module.LibnoiseModule;
                ModuleBase destinationModule = newConnection.DestConnector.ParentNode.Module.LibnoiseModule;

                // get destination type, connector name, assign to correct module
                if(newConnection.DestConnector.Name.Equals("Input"))
                {
                    destinationModule.Modules[0] = sourceModule;
                    destinationNode.Inputs[0] = sourceNode;
                }
                else if(newConnection.DestConnector.Name.Equals("Left"))
                {
                    destinationModule.Modules[0] = sourceModule;
                    destinationNode.Inputs[0] = sourceNode;
                }
                else if(newConnection.DestConnector.Name.Equals("Right"))
                {
                    destinationModule.Modules[1] = sourceModule;
                    destinationNode.Inputs[1] = sourceNode;
                }
                else if(newConnection.DestConnector.Name.Equals("Operator"))
                {
                    destinationModule.Modules[2] = sourceModule;
                    destinationNode.Inputs[2] = sourceNode;
                }
                else if(newConnection.DestConnector.Name.Equals("Primary"))
                {
                    destinationModule.Modules[0] = sourceModule;
                    destinationNode.Inputs[0] = sourceNode;
                }
                else if(newConnection.DestConnector.Name.Equals("Secondary"))
                {
                    destinationModule.Modules[1] = sourceModule;
                    destinationNode.Inputs[1] = sourceNode;
                }
                else if(newConnection.DestConnector.Name.Equals("Controller"))
                {
                    destinationModule.Modules[2] = sourceModule;
                    destinationNode.Inputs[2] = sourceNode;
                }
                else if(newConnection.DestConnector.Name.Equals("X"))
                {
                    destinationModule.Modules[1] = sourceModule;
                    destinationNode.Inputs[1] = sourceNode;
                }
                else if(newConnection.DestConnector.Name.Equals("Y"))
                {
                    destinationModule.Modules[2] = sourceModule;
                    destinationNode.Inputs[2] = sourceNode;
                }
                else if(newConnection.DestConnector.Name.Equals("Z"))
                {
                    destinationModule.Modules[3] = sourceModule;
                    destinationNode.Inputs[3] = sourceNode;
                }
            }
        }
        /// <summary>
        /// Warning : there are events on collection DestConnector, SourceConnector, Points
        /// </summary>
        /// <returns></returns>
        public ConnectionViewModel Copy()
        {
            ConnectionViewModel newConn = new ConnectionViewModel();

            newConn.DestConnector = DestConnector;
            newConn.DestConnectorHotspot = DestConnectorHotspot;
            newConn.Points = Points;
            newConn.SourceConnector = SourceConnector;
            newConn.SourceConnectorHotspot = SourceConnectorHotspot;

            return newConn;
        }
 /// <summary>
 /// 
 /// </summary>
 public CreateConnectionUndoCommand(FlowGraphControlViewModel fgvm_, ConnectionViewModel connectionVM_)
 {
     m_FlowGraphVM = fgvm_;
     //m_ConnectionVM = connectionVM_.Copy();
     m_DestConnector = connectionVM_.DestConnector;
     m_DestConnectorHotspot = connectionVM_.DestConnectorHotspot;
     m_Points = connectionVM_.Points;
     m_SourceConnector = connectionVM_.SourceConnector;
     m_SourceConnectorHotspot = connectionVM_.SourceConnectorHotspot;
 }
        /// <summary>
        /// 
        /// </summary>
        public void Undo()
        {
            ConnectionViewModel copy = new ConnectionViewModel();
            copy.DestConnector = m_DestConnector;
            copy.DestConnectorHotspot = m_DestConnectorHotspot;
            copy.Points = m_Points;
            copy.SourceConnector = m_SourceConnector;
            copy.SourceConnectorHotspot = m_SourceConnectorHotspot;

            m_FlowGraphVM.AddConnection(copy);
            m_ConnectionVM = copy;
        }
        /// <summary>
        /// 
        /// </summary>
        public void Undo()
        {
            List<ConnectionViewModel> connList = new List<ConnectionViewModel>();

            for (int i = 0; i < m_ConnectionInfoList.Count; i++)
            {
                ConnectionViewModel copy = new ConnectionViewModel();
                copy.DestConnector = m_ConnectionInfoList[i].DestConnector;
                copy.DestConnectorHotspot = m_ConnectionInfoList[i].DestConnectorHotspot;
                copy.Points = m_ConnectionInfoList[i].Points;
                copy.SourceConnector = m_ConnectionInfoList[i].SourceConnector;
                copy.SourceConnectorHotspot = m_ConnectionInfoList[i].SourceConnectorHotspot;

                connList.Add(copy);

                ConnectionInfo inf = m_ConnectionInfoList[i];
                inf.ConnectionVM = copy;
                m_ConnectionInfoList[i] = inf;
            }

            m_FlowGraphVM.AddConnections(connList);
        }
        /// <summary>
        /// Called when the user has started to drag out a connector, thus creating a new connection.
        /// </summary>
        public ConnectionViewModel ConnectionDragStarted(ConnectorViewModel draggedOutConnector, Point curDragPoint)
        {
            if (draggedOutConnector.AttachedConnections.Any())
              {
            //
            // There is an existing connection attached to the connector that has been dragged out.
            // Remove the existing connection from the view-model.
            //
            this.Network.Connections.RemoveRange(draggedOutConnector.AttachedConnections as IEnumerable);
              }

              //
              // Create a new connection to add to the view-model.
              //
              var connection = new ConnectionViewModel();

              //
              // Link the source connector to the connector that was dragged out.
              //
              connection.SourceConnector = draggedOutConnector;

              //
              // Set the position of destination connector to the current position of the mouse cursor.
              //
              connection.DestConnectorHotspot = curDragPoint;

              //
              // Add the new connection to the view-model.
              //
              this.Network.Connections.Add(connection);

              return connection;
        }
        /// <summary>
        /// Utility method to delete a connection from the view-model.
        /// </summary>
        public void DeleteConnection(ConnectionViewModel connection, bool saveUndo_ = false)
        {
            if (saveUndo_ == true)
            {
                m_UndoManager.Add(new DeleteConnectionUndoCommand(this, connection));
            }

            this.Network.Connections.Remove(connection);
        }
        /// <summary>
        /// Called when the user has finished dragging out the new connection.
        /// </summary>
        public void ConnectionDragCompleted(
            ConnectionViewModel newConnection, 
            ConnectorViewModel connectorDraggedOut, 
            ConnectorViewModel connectorDraggedOver)
        {
            if (connectorDraggedOver == null)
            {
                //
                // The connection was unsuccessful.
                // Maybe the user dragged it out and dropped it in empty space.
                //
                this.Network.Connections.Remove(newConnection);
            //                 m_connectorDraggedOut = connectorDraggedOut;
            //                 m_ConnectorDraggedOver = connectorDraggedOver;
            //
            //                 //Open contextMenu
            //                 if (ContextMenuOpened != null)
            //                 {
            //                     ContextMenuOpened(this, null);
            //                 }

                return;
            }

            //
            // Only allow connections from output connector to input connector (ie each
            // connector must have a different type).
            // Also only allocation from one node to another, never one node back to the same node.
            //
            string dummy = string.Empty;
            bool connectionOk = IsValidConnection(connectorDraggedOut, connectorDraggedOver, ref dummy);

            if (!connectionOk)
            {
                //
                // Connections between connectors that have the same type,
                // eg input -> input or output -> output, are not allowed,
                // Remove the connection.
                //
                this.Network.Connections.Remove(newConnection);
                return;
            }

            //
            // The user has dragged the connection on top of another valid connector.
            //

            //
            // Remove any existing connection between the same two connectors.
            //
            var existingConnection = FindConnection(connectorDraggedOut, connectorDraggedOver);
            if (existingConnection != null)
            {
                this.Network.Connections.Remove(existingConnection);
            }

            // Finalize the connection by reordering the source & destination
            // if necessary
            if (newConnection.DestConnector == null)
            {
                if (connectorDraggedOver.SourceSlot.ConnectionType == SlotType.VarInOut)
                {
                    if (newConnection.SourceConnector.SourceSlot.ConnectionType == SlotType.VarIn)
                    {
                        ConnectorViewModel dest = newConnection.SourceConnector;
                        newConnection.SourceConnector = connectorDraggedOver;
                        newConnection.DestConnector = dest;
                    }
                    else
                    {
                        newConnection.DestConnector = connectorDraggedOver;
                    }
                }
                else if (connectorDraggedOver.SourceSlot.ConnectionType == SlotType.NodeIn
                    || connectorDraggedOver.SourceSlot.ConnectionType == SlotType.VarIn)
                {
                    newConnection.DestConnector = connectorDraggedOver;
                }
                else
                {
                    ConnectorViewModel dest = newConnection.SourceConnector;
                    newConnection.SourceConnector = connectorDraggedOver;
                    newConnection.DestConnector = dest;
                }
            }
            else // connector source is null
            {
                if (connectorDraggedOver.SourceSlot.ConnectionType == SlotType.VarInOut)
                {
                    if (newConnection.DestConnector.SourceSlot.ConnectionType == SlotType.VarIn)
                    {
                        newConnection.SourceConnector = connectorDraggedOver;
                    }
                    else
                    {
                        ConnectorViewModel dest = newConnection.DestConnector;
                        newConnection.DestConnector = connectorDraggedOver;
                        newConnection.SourceConnector = dest;
                    }
                }
                else if (connectorDraggedOver.SourceSlot.ConnectionType == SlotType.NodeIn
                    || connectorDraggedOver.SourceSlot.ConnectionType == SlotType.VarIn)
                {
                    newConnection.SourceConnector = connectorDraggedOver;
                }
                else
                {
                    ConnectorViewModel dest = newConnection.DestConnector;
                    newConnection.SourceConnector = connectorDraggedOver;
                    newConnection.DestConnector = dest;
                }
            }

            //special case variable from 2 SequenceNode directly connected
            if (newConnection.SourceConnector.SourceSlot is NodeSlotVar
                && newConnection.DestConnector.SourceSlot is NodeSlotVar)
            {
                ConnectorViewModel src = newConnection.SourceConnector;
                newConnection.SourceConnector = newConnection.DestConnector;
                newConnection.DestConnector = src;
            }

            m_UndoManager.Add(new CreateConnectionUndoCommand(this, newConnection));
        }
        public static void LoadLibnoiseXml(XmlDocument doc, DesignerViewer LibnoiseDesigner)
        {
            XmlNodeList moduleList = doc.GetElementsByTagName("Module");
            List<LoadedModule> loadedModules = GetModules(moduleList);

            LibnoiseDesigner.ViewModel.DeleteAllNodes();

            //loop through modules, create nodes
            foreach (LoadedModule lm in loadedModules)
            {
                NodeViewModel node = LibnoiseDesigner.ViewModel.CreateNode(lm.Module, lm.Location, false);
                node.Module.ID = lm.ID;
            }

            foreach (LoadedModule lm in loadedModules)
            {
                int count = 0;
                NodeViewModel destinationNodeModel = LibnoiseDesigner.ViewModel.Network.Nodes.First(n => n.Module.ID.Equals(lm.ID));
                foreach (string link in lm.Links)
                {
                    NodeViewModel sourceNodeModel = LibnoiseDesigner.ViewModel.Network.Nodes.First(n => n.Module.ID.Equals(link));

                    ConnectionViewModel cvm = new ConnectionViewModel();
                    cvm.DestConnector = destinationNodeModel.InputConnectors[count];
                    cvm.SourceConnector = sourceNodeModel.OutputConnectors[0]; // only ever one output connector in our Libnoise model

                    LibnoiseNode sourceNode = sourceNodeModel.Module;
                    LibnoiseNode destinationNode = destinationNodeModel.Module;
                    ModuleBase sourceModule = sourceNode.LibnoiseModule;
                    ModuleBase destinationModule = destinationNode.LibnoiseModule;

                    destinationModule.Modules[count] = sourceModule;
                    destinationNode.Inputs[count] = sourceNode;

                    LibnoiseDesigner.ViewModel.Network.Connections.Add(cvm);

                    count++;
                }
            }
        }
        /// <summary>
        /// Called when the user has finished dragging out the new connection.
        /// </summary>
        public void ConnectionDragCompleted(ConnectionViewModel newConnection, ConnectorViewModel connectorDraggedOut, ConnectorViewModel connectorDraggedOver)
        {
            if (connectorDraggedOver == null)
              {
            //
            // The connection was unsuccessful.
            // Maybe the user dragged it out and dropped it in empty space.
            //
            this.Network.Connections.Remove(newConnection);
            return;
              }

              //
              // The user has dragged the connection on top of another valid connector.
              //

              var existingConnections = connectorDraggedOver.AttachedConnections;
              if (existingConnections != null)
              {
            //
            // There is already a connection attached to the connector that was dragged over.
            // Remove the existing connection from the view-model.
            //
            this.Network.Connections.RemoveRange(existingConnections as IEnumerable);
              }

              //
              // Finalize the connection by attaching it to the connector
              // that the user dropped the connection on.
              //
              newConnection.DestConnector = connectorDraggedOver;
        }
        /// <summary>
        /// Called when the user has started to drag out a connector, thus creating a new connection.
        /// </summary>
        public ConnectionViewModel ConnectionDragStarted(ConnectorViewModel draggedOutConnector, Point curDragPoint)
        {
            //
            // Create a new connection to add to the view-model.
            //
            var connection = new ConnectionViewModel();

            if (draggedOutConnector.Type == ConnectorType.Output)
            {
                //
                // The user is dragging out a source connector (an output) and will connect it to a destination connector (an input).
                //
                connection.SourceConnector = draggedOutConnector;
                connection.DestConnectorHotspot = curDragPoint;
            }
            else
            {
                //
                // The user is dragging out a destination connector (an input) and will connect it to a source connector (an output).
                //
                connection.DestConnector = draggedOutConnector;
                connection.SourceConnectorHotspot = curDragPoint;
            }

            //
            // Add the new connection to the view-model.
            //
            this.Network.Connections.Add(connection);

            return connection;
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="node_"></param>
        public void Load(XmlNode node_)
        {
            try
            {
                int version = int.Parse(node_.Attributes["version"].Value);

                int graphId = int.Parse(node_.Attributes["id"].Value);
                Sequence = GraphDataManager.Instance.GetByID(graphId);

                foreach (SequenceNode node in Sequence.Nodes)
                {
                    XmlNode nodeNode = node_.SelectSingleNode("NodeList/Node[@id='" + node.Id + "']");

                    int versionNode = int.Parse(nodeNode.Attributes["version"].Value);

                    if (nodeNode != null)
                    {
                        NodeViewModel nodeVM = new NodeViewModel(node);
                        nodeVM.X = double.Parse(nodeNode.Attributes["x"].Value);
                        nodeVM.Y = double.Parse(nodeNode.Attributes["y"].Value);
                        nodeVM.ZIndex = int.Parse(nodeNode.Attributes["z"].Value);
                        Network.Nodes.Add(nodeVM);
                    }
                    else
                    {
                        throw new InvalidOperationException("Can't find node from xml " + string.Format("id={0}", nodeNode.Attributes["id"].Value));
                    }
                }

                foreach (XmlNode linkNode in node_.SelectNodes("ConnectionList/Connection"))
                {
                    int versionLink = int.Parse(linkNode.Attributes["version"].Value);

                    ConnectionViewModel cvm = new ConnectionViewModel();
                    NodeViewModel srcNode = GetNodeVMBySequenceID(int.Parse(linkNode.Attributes["srcNodeID"].Value));
                    NodeViewModel destNode = GetNodeVMBySequenceID(int.Parse(linkNode.Attributes["destNodeID"].Value));
                    cvm.SourceConnector = srcNode.GetConnectorFromSlotId(int.Parse(linkNode.Attributes["srcNodeSlotID"].Value));
                    cvm.DestConnector = destNode.GetConnectorFromSlotId(int.Parse(linkNode.Attributes["destNodeSlotID"].Value));
                    Network.Connections.Add(cvm);
                }

                m_XmlNodeLoaded = node_;
            }
            catch (System.Exception ex)
            {
                LogManager.Instance.WriteException(ex);
            }
        }
        /// <summary>
        /// Utility method to delete a connection from the view-model.
        /// </summary>
        public void DeleteConnection(ConnectionViewModel connection)
        {
            ModuleBase sourceModule = connection.SourceConnector.ParentNode.Module.LibnoiseModule;
            ModuleBase destinationModule = connection.DestConnector.ParentNode.Module.LibnoiseModule;

            // get destination type, connector name, assign to correct module
            if(connection.DestConnector.Name.Equals("Input"))
            {
                destinationModule.Modules[0] = null;
            }
            else if(connection.DestConnector.Name.Equals("Left"))
            {
                destinationModule.Modules[0] = null;
            }
            else if(connection.DestConnector.Name.Equals("Right"))
            {
                destinationModule.Modules[1] = null;
            }
            else if(connection.DestConnector.Name.Equals("Operator"))
            {
                destinationModule.Modules[2] = null;
            }
            else if(connection.DestConnector.Name.Equals("Primary"))
            {
                destinationModule.Modules[0] = null;
            }
            else if(connection.DestConnector.Name.Equals("Secondary"))
            {
                destinationModule.Modules[1] = null;
            }
            else if(connection.DestConnector.Name.Equals("Controller"))
            {
                destinationModule.Modules[2] = null;
            }
            else if(connection.DestConnector.Name.Equals("X"))
            {
                destinationModule.Modules[1] = null;
            }
            else if(connection.DestConnector.Name.Equals("Y"))
            {
                destinationModule.Modules[2] = null;
            }
            else if(connection.DestConnector.Name.Equals("Z"))
            {
                destinationModule.Modules[3] = null;
            }

            this.Network.Connections.Remove(connection);
        }
 /// <summary>
 /// Called as the user continues to drag the connection.
 /// </summary>
 public void ConnectionDragging(ConnectionViewModel connection, Point curDragPoint)
 {
     //
       // Update the destination connection hotspot while the user is dragging the connection.
       //
       connection.DestConnectorHotspot = curDragPoint;
 }