/// <summary>
        /// Create a node and add it to the view-model.
        /// </summary>
        public NodeViewModel CreateNode(ModuleBase moduleBase, Point nodeLocation, bool centerNode)
        {
            System.Windows.Media.Brush generatorBrush = new LinearGradientBrush(Colors.White, Colors.Orange, 90.0);
            System.Windows.Media.Brush operatorBrush = new LinearGradientBrush(Colors.White, Colors.PowderBlue, 90.0);
            System.Windows.Media.Brush finalBrush = new LinearGradientBrush(Colors.White, Colors.YellowGreen, 90.0);

            NodeViewModel node = new NodeViewModel(new LibnoiseNode(moduleBase));
            node.Module.ID = moduleBase.GetType().Name + "_" + (Network.Nodes.Count(n => n.Module.ModuleType.Equals(moduleBase.GetType().Name)) + 1);
            node.X = nodeLocation.X;
            node.Y = nodeLocation.Y;

            node.StrokeBrush = System.Windows.Media.Brushes.Black;

            // this can be simplified, for sure, but I left in the giant ugly switch
            // in the event I want to do something unique by type, such as any additional
            // colouring or whatever. It's a little gross to look at, but it does the job
            switch (moduleBase.GetType().Name)
            {
                    // Generators should not have any input values
                case "Billow":
                    node.FillBrush = generatorBrush;
                    break;
                case "Checker":
                    node.FillBrush = generatorBrush;
                    break;
                case "Const":
                    node.FillBrush = generatorBrush;
                    break;
                case "Cylinders":
                    node.FillBrush = generatorBrush;
                    break;
                case "Perlin":
                    node.FillBrush = generatorBrush;
                    break;
                case "RidgedMultifractal":
                    node.FillBrush = generatorBrush;
                    break;
                case "Spheres":
                    node.FillBrush = generatorBrush;
                    break;
                case "Voronoi":
                    node.FillBrush = generatorBrush;
                    break;
                case "Abs":
                    node.FillBrush = operatorBrush;
                    node.InputConnectors.Add(new ConnectorViewModel("Input"));
                    break;
                case "Add":
                    node.FillBrush = operatorBrush;
                    node.InputConnectors.Add(new ConnectorViewModel("Left"));
                    node.InputConnectors.Add(new ConnectorViewModel("Right"));
                    break;
                case "Blend":
                    node.FillBrush = operatorBrush;
                    node.InputConnectors.Add(new ConnectorViewModel("Left"));
                    node.InputConnectors.Add(new ConnectorViewModel("Right"));
                    node.InputConnectors.Add(new ConnectorViewModel("Operator"));
                    break;
                case "Cache":
                    node.FillBrush = operatorBrush;
                    node.InputConnectors.Add(new ConnectorViewModel("Input"));
                    break;
                case "Clamp":
                    node.FillBrush = operatorBrush;
                    node.InputConnectors.Add(new ConnectorViewModel("Input"));
                    break;
                case "Curve":
                    node.FillBrush = operatorBrush;
                    node.InputConnectors.Add(new ConnectorViewModel("Input"));
                    break;
                case "Displace":
                    node.FillBrush = operatorBrush;
                    node.InputConnectors.Add(new ConnectorViewModel("Primary"));
                    node.InputConnectors.Add(new ConnectorViewModel("X"));
                    node.InputConnectors.Add(new ConnectorViewModel("Y"));
                    node.InputConnectors.Add(new ConnectorViewModel("Z"));
                    break;
                case "Exponent":
                    node.FillBrush = operatorBrush;
                    node.InputConnectors.Add(new ConnectorViewModel("Input"));
                    break;
                case "Invert":
                    node.FillBrush = operatorBrush;
                    node.InputConnectors.Add(new ConnectorViewModel("Input"));
                    break;
                case "Max":
                    node.FillBrush = operatorBrush;
                    node.InputConnectors.Add(new ConnectorViewModel("Left"));
                    node.InputConnectors.Add(new ConnectorViewModel("Right"));
                    break;
                case "Min":
                    node.FillBrush = operatorBrush;
                    node.InputConnectors.Add(new ConnectorViewModel("Left"));
                    node.InputConnectors.Add(new ConnectorViewModel("Right"));
                    break;
                case "Multiply":
                    node.FillBrush = operatorBrush;
                    node.InputConnectors.Add(new ConnectorViewModel("Left"));
                    node.InputConnectors.Add(new ConnectorViewModel("Right"));
                    break;
                case "Power":
                    node.FillBrush = operatorBrush;
                    node.InputConnectors.Add(new ConnectorViewModel("Left"));
                    node.InputConnectors.Add(new ConnectorViewModel("Right"));
                    break;
                case "Rotate":
                    node.FillBrush = operatorBrush;
                    node.InputConnectors.Add(new ConnectorViewModel("Input"));
                    break;
                case "Scale":
                    node.FillBrush = operatorBrush;
                    node.InputConnectors.Add(new ConnectorViewModel("Input"));
                    break;
                case "ScaleBias":
                    node.FillBrush = operatorBrush;
                    node.InputConnectors.Add(new ConnectorViewModel("Input"));
                    break;
                case "Select":
                    node.FillBrush = operatorBrush;
                    node.InputConnectors.Add(new ConnectorViewModel("Primary"));
                    node.InputConnectors.Add(new ConnectorViewModel("Secondary"));
                    node.InputConnectors.Add(new ConnectorViewModel("Controller"));
                    break;
                case "Subtract":
                    node.FillBrush = operatorBrush;
                    node.InputConnectors.Add(new ConnectorViewModel("Left"));
                    node.InputConnectors.Add(new ConnectorViewModel("Right"));
                    break;
                case "Terrace":
                    node.FillBrush = operatorBrush;
                    node.InputConnectors.Add(new ConnectorViewModel("Input"));
                    break;
                case "Translate":
                    node.FillBrush = operatorBrush;
                    node.InputConnectors.Add(new ConnectorViewModel("Input"));
                    break;
                case "Turbulence":
                    node.FillBrush = operatorBrush;
                    node.InputConnectors.Add(new ConnectorViewModel("Input"));
                    break;
                case "Final":
                    node.FillBrush = finalBrush;
                    node.InputConnectors.Add(new ConnectorViewModel("Input"));
                    break;
                default:
                    break;
            }

            // for the 'Final' node, don't add any outputs.
            if (!moduleBase.GetType().Name.Equals("Final"))
            {
                node.OutputConnectors.Add(new ConnectorViewModel("Output"));
            }

            if (centerNode)
            {
                //
                // We want to center the node.
                //
                // For this to happen we need to wait until the UI has determined the
                // size based on the node's data-template.
                //
                // So we define an anonymous method to handle the SizeChanged event for a node.
                //
                // Note: If you don't declare sizeChangedEventHandler before initializing it you will get
                //       an error when you try and unsubscribe the event from within the event handler.
                //
                EventHandler<EventArgs> sizeChangedEventHandler = null;
                sizeChangedEventHandler =
                    delegate(object sender, EventArgs e)
                    {
                        //
                        // This event handler will be called after the size of the node has been determined.
                        // So we can now use the size of the node to modify its position.
                        //
                        node.X -= node.Size.Width / 2;
                        node.Y -= node.Size.Height / 2;

                        //
                        // Don't forget to unhook the event, after the initial centering of the node
                        // we don't need to be notified again of any size changes.
                        //
                        node.SizeChanged -= sizeChangedEventHandler;
                    };

                //
                // Now we hook the SizeChanged event so the anonymous method is called later
                // when the size of the node has actually been determined.
                //
                node.SizeChanged += sizeChangedEventHandler;
            }

            //
            // Add the node to the view-model.
            //
            this.Network.Nodes.Add(node);

            return node;
        }
        // simple recursive call to cycle through a selected module
        // and their connected children and set the seed value to the
        // seed selected by the user. If a seed value already exists,
        // then leave it alone... or maybe add it together?
        private void SetSeeds(ModuleBase module, int seed)
        {
            switch (module.GetType().Name)
            {
                case "Billow":
                    if (((Billow)module).Seed == 0) ((Billow)module).Seed = seed;
                    break;
                case "Perlin":
                    if (((Perlin)module).Seed == 0) ((Perlin)module).Seed = seed;
                    break;
                case "RidgedMultifractal":
                    if (((RidgedMultifractal)module).Seed == 0) ((RidgedMultifractal)module).Seed = seed;
                    break;
                case "Voronoi":
                    if (((Voronoi)module).Seed == 0) ((Voronoi)module).Seed = seed;
                    break;
                case "Turbulence":
                    if (((Turbulence)module).Seed == 0) ((Turbulence)module).Seed = seed;
                    break;
                default:
                    break;
            }

            if (module.Modules != null && module.Modules.Count() > 0)
            {
                foreach (ModuleBase mb in module.Modules)
                {
                    SetSeeds(mb, seed);
                }
            }
        }