private void ConnectTargets(EventNode Event, ActionNode Action)
        {
            if (!(Action.DotaAction is TargetedAction)) return; //An action without targets doesn't need it's nodes resolved
            TargetedAction ta = Action.DotaAction as TargetedAction;


            if (ta.Target.Preset == null) return; //Not a preset.  TODO: Generated a Make Target node with the details of this target key

            var outputItem = Event.GetTargetNodeFor(ta.Target.Preset);

            if (outputItem == null) return;

            graphControl1.Connect(outputItem, Action.TargetPin);
            
            
        }
        private void treeView1_ItemDrag(object sender, ItemDragEventArgs e)
        {
            if (e.Button != MouseButtons.Left) return;

            //Ignore non-TreeNode objects being dragged
            if (!(e.Item is TreeNode)) return;

            //Get the dragged item from the event
            var SelectedNode = e.Item as TreeNode;

            Node Node = null;

            if ((string)SelectedNode.Tag == "Action")
            {
                var Action = DotaActionFactory.CreateNewAction(SelectedNode.Text);
                Node = new ActionNode(Action);

            }
            if ((string)SelectedNode.Tag == "Event")
            {
                var Event = DotaData.Events.FirstOrDefault(x => x.ClassName == SelectedNode.Text);
                Node = new EventNode(Event, Ability.ActionList.GetOrCreateCollection(Event));
            }
            if ((string)SelectedNode.Tag == "Variable")
            {
                var Var = Ability.ActionList.Variables.First(x => x.Name == (string)SelectedNode.Text);
                Node = new VariableNode(Var);

            }
            if((string)SelectedNode.Tag == "Target")
            {
                var Target = new TargetKey();
                if (SelectedNode.Name == "line")
                {
                    Target.Shape = TargetKey.ShapeE.LINE;
                }
                else if(SelectedNode.Name == "circle")
                {
                    Target.Shape = TargetKey.ShapeE.CIRCLE;
                }

                Node = new CustomTargetNode(SelectedNode.Name, Target);
            }

            //The node can be null if an item with an unknown tag was drag-dropped
            if (Node != null)
            {
                Node.Location = new PointF(0, 0);
                this.DoDragDrop(Node, DragDropEffects.Copy);
            }
        }
        private void PlaceEvents()
        {
            GeneratingGraph = true;

            PointF Position = new PointF(EventColumn, 0);
            Graphics g = graphControl1.GetLayoutGraphics();


            foreach (DotaActionCollection kvEvents in Ability.ActionList)
            {
                var Event = DotaData.Events.FirstOrDefault(x => x.ClassName == kvEvents.ClassName);

                if (Event.RespectsTargetFlag && Ability.AbilityBehavior.HasFlag(DotaAbility.AbilityBehaviorFlags.DOTA_ABILITY_BEHAVIOR_UNIT_TARGET))
                {
                    //Add the target pin
                    Event.Targets = Event.Targets | DotaEvent.TargetsFlags.TARGET;
                }

                var EventNode = new EventNode(Event, Ability.ActionList.GetActionCollection(Event));
                EventNode.Location = Position;

               

                EventNode.PerformLayout(g);

                graphControl1.AddNode(EventNode);

                PointF col = Position;
                col.X = EventNode.Bounds.Right + ColumnSpacing; //Move this node to the left of the event node + spacing
                PointF previousCol = col;

                ExecuteNodeItem ExNode = EventNode.OutputExecute;

                float columnHeight = EventNode.Bounds.Height;
                foreach(var kvAction in kvEvents)
                {
                    if (kvAction == null) continue;
                       
                    var ActionNode = new ActionNode(kvAction);
                    ActionNode.Location = col;
                    
                    graphControl1.AddNode(ActionNode);
                    ActionNode.PerformLayout(g);

                    //Connect the execute nodes
                    var inputNode = ActionNode.InputExecute;
                    graphControl1.Connect(ExNode, inputNode);
                    ExNode = ActionNode.OutputExecute;

                    ConnectTargets(EventNode, ActionNode);


                    var varRefs = ActionNode.VariableReferences;

                    foreach(var Ref in varRefs)
                    {
                        var pos = previousCol;
                        pos.Y += columnHeight;

                        //Get the data variable for this reference
                        var actionVariable = ability.ActionList.Variables.FirstOrDefault(x => x.Name == Ref.VariableName.Replace("%", ""));
                        if (actionVariable == null)
                        {
                            MessageBox.Show("Found a reference to " + Ref.VariableName + "but could not find it in the variable table!");
                            continue;
                        }

                        //Create the variable node and add it to the graph
                        VariableNode varNode = new VariableNode(actionVariable);
                        varNode.Location = pos;
                        varNode.PerformLayout(g);
                        graphControl1.AddNode(varNode);

                        //Connect it's output to the referenced input pins

                        foreach(var inputPin in Ref.InputPins)
                        {
                            graphControl1.Connect(varNode.OutputPin, inputPin);
                        }

                        columnHeight += varNode.Bounds.Height + VariableSpacing;
                    }

                  
                    //Move the pen right to place the next action node
                    previousCol = col;
                    col.X = ActionNode.Bounds.Right + ColumnSpacing;
                    columnHeight = Math.Max(ActionNode.Bounds.Height, columnHeight);
                }


                Position.Y += columnHeight + EventSpacing;

            }

            GeneratingGraph = false;
        }
        private void treeView1_ItemDrag(object sender, ItemDragEventArgs e)
        {
            if (e.Button != MouseButtons.Left) return;

            var SelectedNode = treeView1.SelectedNode;

            if (SelectedNode == null) return; //If we don't have a selection, don't bother with this.

            Node Node = null;

            if ((string)SelectedNode.Tag == "Action")
            {
                var Action = DotaActionFactory.CreateNewAction(SelectedNode.Text);
                Node = new ActionNode(Action);

            }
            if ((string)SelectedNode.Tag == "Event")
            {
                var Event = DotaData.Events.FirstOrDefault(x => x.ClassName == SelectedNode.Text);
                Node = new EventNode(Event, Ability.ActionList.GetOrCreateCollection(Event));
            }
            if ((string)SelectedNode.Tag == "Variable")
            {
                var Var = Ability.ActionList.Variables.First(x => x.Name == (string)SelectedNode.Text);
                Node = new VariableNode(Var);

            }
            if((string)SelectedNode.Tag == "Target")
            {
                var Target = new TargetKey();
                if (SelectedNode.Name == "line")
                {
                    Target.Shape = TargetKey.ShapeE.LINE;
                }
                else if(SelectedNode.Name == "circle")
                {
                    Target.Shape = TargetKey.ShapeE.CIRCLE;
                }

                Node = new CustomTargetNode(SelectedNode.Name, Target);
            }

            Node.Location = new PointF(0, 0);
            this.DoDragDrop(Node, DragDropEffects.Copy);
        }