private StorySegmentNodeModel GetNodeRelatedToStorySegment(StorySegmentModel storySegment)
 {
     for (int i = 0; i < _nodes.Count; i++)
     {
         if (_nodes[i].StorySegment == storySegment)
         {
             return(_nodes[i]);
         }
     }
     return(null);
 }
        private StorySegmentNodeModel CreateStoryNode(StorySegmentModel storySegment)
        {
            StorySegmentNodeModel node = ScriptableObject.CreateInstance <StorySegmentNodeModel>();

            node.Story        = _story;
            node.StorySegment = storySegment;
            _nodes.Add(node);
            AssetDatabase.CreateAsset(node, AssetDatabase.GenerateUniqueAssetPath("Assets" + StorySegmentNodeModel.DEFAULT_NODES_PATH + "/Node.asset"));
            AssetDatabase.SaveAssets();
            return(node);
        }
        private void NodeExitSelection(Event e)
        {
            if (_selectingExitFor == null)
            {
                return;
            }

            if (e.button == EXIT_SELECTION_MOUSEBUTTON && e.type == EventType.MouseDown)
            {
                StorySegmentNodeModel selectedNode = GetNodeUnderMouse(e);
                if (selectedNode == null)
                {
                    // Create new node.
                    string path = EditorUtility.OpenFilePanel("Create New Story Element", INK_FILES_PATH, "json");

                    if (!string.IsNullOrEmpty(path))
                    {
                        path = path.Replace(Application.dataPath, "Assets");
                        TextAsset jsonFile = (TextAsset)AssetDatabase.LoadAssetAtPath(path, typeof(TextAsset));

                        StorySegmentModel storySegment = ScriptableObject.CreateInstance <StorySegmentModel>();
                        storySegment.InkScript = jsonFile;
                        AssetDatabase.CreateAsset(storySegment, AssetDatabase.GenerateUniqueAssetPath("Assets" + StorySegmentModel.DEFAULT_LOCATION + "/StorySegement.asset"));
                        AssetDatabase.SaveAssets();
                        _selectingExitFor.StorySegment.NextSegments.Add(storySegment);

                        StorySegmentNodeModel node = CreateStoryNode(storySegment);
                        node.GraphLocation = e.mousePosition - _viewPoint;
                    }
                }
                else
                {
                    // Join existing node.
                    if (!_selectingExitFor.StorySegment.NextSegments.Contains(selectedNode.StorySegment) && _selectingExitFor != selectedNode)
                    {
                        _selectingExitFor.StorySegment.NextSegments.Add(selectedNode.StorySegment);
                    }
                }

                _selectingExitFor = null;
            }

            if (_selectingExitFor != null)
            {
                DrawConnection(_selectingExitFor.rect, e.mousePosition);
                Repaint();
            }
        }
        private void DrawNode(Event e, StorySegmentModel storySegment, Rect?connectingRect, int?exitNumber)
        {
            if (_drawnSegments.Contains(storySegment))
            {
                // This has been drawn before, so just draw the connection.
                if (connectingRect != null)
                {
                    StorySegmentNodeModel n = GetNodeRelatedToStorySegment(storySegment);
                    DrawConnection((Rect)connectingRect, n.rect, (int)exitNumber);
                }
                return;
            }
            EditorUtility.SetDirty(storySegment);

            // Create node if this storysegment doesn't already have one.
            StorySegmentNodeModel node = GetNodeRelatedToStorySegment(storySegment);

            if (node == null)
            {
                node = CreateStoryNode(storySegment);
            }

            // Draw the node on the window. todo: move to StorySegmentNodeExtensions.
            Rect rect = new Rect(node.GraphLocation.x + _viewPoint.x, node.GraphLocation.y + _viewPoint.y, StorySegmentNodeModel.NODE_WIDTH, StorySegmentNodeModel.NODE_HEIGHT);

            if (e.type == EventType.Layout)
            {
                node.rect = rect;
                string title = string.Format("{0}{1}", storySegment.InkScript.name, _story.FirstStorySegment == storySegment ? " (START)" : string.Empty);
                GUILayout.Window(node.GetInstanceID(), rect, (int windowId) =>
                {
                    EditorGUILayout.BeginHorizontal();

                    // First collumn.
                    EditorGUILayout.BeginVertical();
                    node.StorySegment.InkScript = (TextAsset)EditorGUILayout.ObjectField(node.StorySegment.InkScript, typeof(TextAsset), false,
                                                                                         GUILayout.Height(StorySegmentNodeModel.OBJECT_FIELD_HEIGHT), GUILayout.Width(StorySegmentNodeModel.NODE_WIDTH * 0.6f)) as TextAsset;

                    if (!_selectingExitFor && GUILayout.Button("Edit Ink Script"))
                    {
                        string path = AssetDatabase.GetAssetPath(node.StorySegment.InkScript).Replace(".json", ".ink");
                        Object obj  = AssetDatabase.LoadAssetAtPath(path, typeof(Object));
                        AssetDatabase.OpenAsset(obj);
                    }

                    EditorGUILayout.EndVertical();
                    GUILayout.FlexibleSpace();

                    // Second collumn.
                    EditorGUILayout.BeginVertical();
                    if (storySegment.NextSegments.Count != 0)
                    {
                        for (int i = 0; i < storySegment.NextSegments.Count; i++)
                        {
                            GUILayout.BeginHorizontal("box");
                            GUILayout.FlexibleSpace();
                            EditorGUILayout.LabelField("            Exit " + i, GUILayout.Width(StorySegmentNodeModel.NODE_WIDTH * 0.4f));
                            GUILayout.FlexibleSpace();
                            if (GUILayout.Button("x"))
                            {
                                storySegment.NextSegments.RemoveAt(i);
                                _nodes = null;
                                Repaint();
                            }
                            GUILayout.EndHorizontal();
                        }
                    }
                    else
                    {
                        GUILayout.FlexibleSpace();
                        EditorGUILayout.LabelField("        Finish", GUILayout.Width(StorySegmentNodeModel.NODE_WIDTH * 0.4f));
                        GUILayout.FlexibleSpace();
                    }

                    if (!_selectingExitFor && GUILayout.Button("Add Exit"))
                    {
                        _selectingExitFor = node;
                        Repaint();
                    }

                    EditorGUILayout.EndVertical();
                    EditorGUILayout.EndHorizontal();
                }, title /*, _guiStyle*/);
            }

            // Draw connection if previous rect.
            if (e.type == EventType.Repaint && connectingRect != null)
            {
                DrawConnection((Rect)connectingRect, rect, (int)exitNumber);
            }

            _drawnSegments.Add(storySegment);

            // Draw the nodes that flow from this node.
            for (int i = 0; i < storySegment.NextSegments.Count; i++)
            {
                if (storySegment.NextSegments[i] != null)
                {
                    DrawNode(e, storySegment.NextSegments[i], rect, i);
                }
            }
        }