public DialogGraphGUI()
    {
        menuDict.Add("New Statement", delegate {
            DialogStatement statement = ScriptableObject.CreateInstance <DialogStatement>();
            statement.Id       = idGenerator;
            statement.NodeRect = new Rect(lastMousePos, new Vector2(160, 50));
            statement.name     = "New Statement " + statement.Id;
            Nodes().Add(statement);

            AssetDatabase.AddObjectToAsset(statement, host.ActiveContainer);
            statement.hideFlags = HideFlags.HideInHierarchy;
            AssetDatabase.SaveAssets();
            AssetDatabase.ImportAsset(AssetDatabase.GetAssetPath(host.ActiveContainer));
        });

        nodeDict.Add("Add Transition", delegate(object data) {
            startNode    = Nodes().First(n => n.Id == (int)data);
            controllMode = ControllMode.DRAWEDGE;
        });
        nodeDict.Add("Mark as Starting Node", delegate(object data) {
            host.ActiveContainer.StartingPoint = Nodes().First(n => n.Id == (int)data);
        });
        nodeDict.Add("Delete Node", delegate(object data) {
            Edges().RemoveAll(e => e.From.Id == (int)data || e.To.Id == (int)data);
            Nodes().RemoveAll(n => n.Id == (int)data);
        });

        edgeDict.Add("Delete Edge", delegate(object data) {
            var ed = Edges().First(e => e.Id == (int)data);
            ed.From.Answers.Remove(ed);
        });
    }
    private void OnNodeDraw(DialogStatement node)
    {
        int    i = node == host.ActiveContainer.StartingPoint ? 5 : 0;
        string s = node == selectedNode ? " on" : "";

        GUIStyle style = $"flow node {i}{s}";

        var labelstyle = GUI.skin.label;

        labelstyle.alignment = TextAnchor.MiddleCenter;
        EditorGUIUtility.AddCursorRect(node.NodeRect, MouseCursor.MoveArrow);
        GUI.BeginGroup(node.NodeRect, style);
        GUI.Label(new Rect(0, 0, node.NodeRect.width, node.NodeRect.height), $"{node.name}", GUI.skin.label);
        GUI.EndGroup();
    }
    private void OnNodeEvent(DialogStatement node)
    {
        var rect = node.NodeRect;

        if (rect.Contains(Event.current.mousePosition))
        {
            if (Event.current.type == EventType.ContextClick)
            {
                EditorContextMenu(nodeDict, node.Id);
                Event.current.Use();
            }
            if (Event.current.type == EventType.MouseDown)
            {
                if (controllMode == ControllMode.DRAWEDGE && startNode != node)
                {
                    DialogAnswer answer = ScriptableObject.CreateInstance <DialogAnswer>();
                    answer.From = startNode;
                    answer.To   = node;
                    answer.Id   = idGenerator;
                    startNode.Answers.Add(answer);
                    AssetDatabase.AddObjectToAsset(answer, host.ActiveContainer);
                    answer.hideFlags = HideFlags.HideInHierarchy;
                    answer.parent    = host.ActiveContainer;
                    AssetDatabase.SaveAssets();
                    AssetDatabase.ImportAsset(AssetDatabase.GetAssetPath(host.ActiveContainer));
                    controllMode = ControllMode.SELECTION;
                }
                else
                {
                    selectedNode           = node;
                    Selection.activeObject = node;
                }
                Event.current.Use();
            }
        }
        if (selectedNode != node)
        {
            return;
        }
        if (Event.current.type == EventType.MouseDrag)
        {
            node.NodeRect.position += Event.current.delta;
            EditorUtility.SetDirty(node);
            Event.current.Use();
        }
    }
    public override void OnInspectorGUI()
    {
        DialogStatement statement = (DialogStatement)target;

        EditorGUILayout.BeginHorizontal();

        EditorGUI.BeginChangeCheck();
        statement.name = EditorGUILayout.TextField("DialogWindow Statement", statement.name);
        if (EditorGUI.EndChangeCheck())
        {
            Undo.RecordObject(target, "Changed statement Name");
        }

        EditorGUILayout.LabelField(statement.Id.ToString(), GUILayout.MaxWidth(30));
        EditorGUILayout.EndHorizontal();
        EditorGUILayout.LabelField(name);

        EditorGUI.BeginChangeCheck();
        statement.speaker = EditorGUILayout.TextField("Speaker Name", statement.speaker);
        if (EditorGUI.EndChangeCheck())
        {
            Undo.RecordObject(target, "Changed speaker Name");
        }

        EditorStyles.textArea.wordWrap  = true;
        EditorStyles.textField.wordWrap = true;

        EditorGUI.BeginChangeCheck();
        statement.text = EditorGUILayout.TextArea(statement.text, GUILayout.MaxHeight(EditorGUIUtility.singleLineHeight * 4));
        if (EditorGUI.EndChangeCheck())
        {
            Undo.RecordObject(target, "Changed spoken text");
        }

        statement.Answers.ForEach(DialogAnswerInspector.Draw);
        EditorGUILayout.Space();
    }
    private void HandleMouseActions()
    {
        Vector2 v = Event.current.mousePosition;

        if (Event.current.button == 0 && Event.current.type == EventType.mouseDrag &&
            selectedNode == null && selectedEdge == null)
        {
            if (Vector2.Distance(lastMousePos, v) < 50)
            {
                ScrollPosition -= Event.current.delta;
                Event.current.Use();
            }
            lastMousePos = v;
        }

        if (Event.current.type != EventType.MouseDown)
        {
            return;
        }


        selectedNode = null;
        selectedEdge = null;
        foreach (var edge in Edges())
        {
            if (Vector2.Distance(v, ((edge.BoundingRect.size + edge.BoundingRect.position) * 0.5f)) >
                (edge.BoundingRect.position - edge.BoundingRect.size).magnitude * 0.5f
                ||
                !(PointdistanceToLine(Event.current.mousePosition, edge.BoundingRect.position, edge.BoundingRect.size) <
                  6))
            {
                continue;
            }
            selectedEdge           = edge;
            Selection.activeObject = edge;
            Event.current.Use();

            if (Event.current.button == 1)
            {
                // rightclick:
                EditorContextMenu(edgeDict, edge.Id);
            }

            return;
        }
        if (Event.current.button > 1)
        {
            return;
        }
        Selection.activeObject = null;
        if (Event.current.button == 1)
        {
            // rightclick:
            if (controllMode == ControllMode.DRAWEDGE)
            {
                controllMode = ControllMode.SELECTION;
            }
            else
            {
                EditorContextMenu(menuDict);
            }
        }
        Event.current.Use();
    }