/// <summary>
        /// WARNING: This assumes the path has already been validated to exist.
        /// </summary>
        /// <param name="pathToScript"></param>
        private void OpenScript(string pathToScript)
        {
            StreamReader reader     = new StreamReader(pathToScript);
            string       fileString = reader.ReadToEnd();

            reader.Close();
            if (string.IsNullOrEmpty(fileString))
            {
                EditorPrefs.SetString(lastOpenScriptKey, "");
                Debug.Log("File is empty or invalid: " + pathToScript);
                return;
            }

            try
            {
                ScenimaticScript script = JsonUtility.FromJson <ScenimaticScript>(fileString);

                scenimaticGraph = new ScenimaticScriptGraph();
                if (window == null)
                {
                    CreateWindows();
                }
                window.position = new Rect(script.savedScreenPos, script.savedScreenSize);

                scenimaticGraph.Initialize(script);
            }
            catch (System.Exception e)
            {
                EditorPrefs.SetString(lastOpenScriptKey, "");
                Debug.LogError("Error parsing JSON in " + pathToScript + ":\n" + e.Message);
                return;
            }


            if (zoomer == null)
            {
                zoomer = new ZoomWindow();
            }


            zoomer.Reset(scenimaticGraph.zoomerSettings);

            EditorPrefs.SetString(lastOpenScriptKey, pathToScript);

            sceneFileName = Path.GetFileNameWithoutExtension(pathToScript);

            AssetDatabase.SaveAssets();
            AssetDatabase.Refresh();
            EditorUtility.SetDirty(this);
        }
        void OnGUI()
        {
            if (rectStyle == null)
            {
                if (!CreateStyles())
                {
                    return;                     // couldn't create styles
                }
            }

            if (scenimaticGraph == null || scenimaticGraph.script == null)
            {
                if (EditorPrefs.HasKey(lastOpenScriptKey))
                {
                    string lastOpenedScript = EditorPrefs.GetString(lastOpenScriptKey);
                    if (!string.IsNullOrEmpty(lastOpenedScript) &&
                        File.Exists(lastOpenedScript))
                    {
                        OpenScript(lastOpenedScript);
                    }
                }
            }

            Rect headerRect = EditorGUILayout.BeginVertical(rectStyle);

            {
                // header toolbar
                EditorGUILayout.BeginHorizontal();
                {
                    if (scenimaticGraph == null)
                    {
                        GUILayout.Label(new GUIContent("No scene loaded"));
                    }
                    else
                    {
                        GUILayout.Label(sceneFileName);
                        scenimaticGraph.script.sceneName = GUILayout.TextField(scenimaticGraph.script.sceneName);
                        if (Event.current.type == EventType.MouseDown)
                        {
                            GUI.FocusControl(null);                             // deselects the textfield on a button click
                        }
                        if (GUILayout.Button("Save Scene"))
                        {
                            SaveScript(false);                             // this stuff should be done in update to prevent annoying error messages
                        }

                        if (GUILayout.Button("Save Scene As"))
                        {
                            SaveScript(true);                             // this stuff should be done in update to prevent annoying error messages
                        }
                    }

                    if (GUILayout.Button("Load Scene"))
                    {
                        LoadScene();
                    }

                    if (GUILayout.Button("New Scene"))
                    {
                        NewScene();
                    }
                }
                GUILayout.FlexibleSpace();
                EditorGUILayout.EndHorizontal();

                if (scenimaticGraph != null)
                {
                    scenimaticGraph.spriteAtlas = (SpriteAtlas)EditorGUILayout.ObjectField(
                        "SpriteAtlas", scenimaticGraph.spriteAtlas,
                        typeof(SpriteAtlas), false);
                    if (scenimaticGraph.spriteAtlas != null)
                    {
                        scenimaticGraph.script.spriteAtlas = scenimaticGraph.spriteAtlas.name;
                    }
                    else
                    {
                        scenimaticGraph.script.spriteAtlas = "";
                    }
                }
            }
            EditorGUILayout.EndVertical();

            if (scenimaticGraph == null)
            {
                return;
            }

            if (zoomer == null)
            {
                zoomer = new ZoomWindow();
                zoomer.Reset(scenimaticGraph.zoomerSettings);
            }

            zoomer.HandleEvents(Event.current);

            if (Event.current.type == EventType.Repaint)
            {
                zoomRect.position = new Vector2(
                    ZOOM_BORDER,
                    headerRect.yMax + TAB_HEIGHT + ZOOM_BORDER);
                zoomRect.size = new Vector2(
                    window.position.width - ZOOM_BORDER * 2,
                    window.position.height - (headerRect.height + ZOOM_BORDER * 2 + RESERVED_AREA_BELOW_ZOOM_HEIGHT));
            }

            zoomer.Begin(zoomRect);
            {
                scenimaticGraph.OnGui(Event.current, zoomer);
            }
            zoomer.End(new Rect(
                           0, zoomRect.yMax - headerRect.height,
                           window.position.width, window.position.height));

            headerRect = EditorGUILayout.BeginVertical(rectStyle);
            {
                if (GUILayout.Button("New Dialog Branch"))
                {
                    scenimaticGraph.AddBranch(CreateNewBranch(Vector2.zero));
                }
            }
            EditorGUILayout.EndVertical();

            //if (GUI.changed) // adding this check means there is a delay when hovering over connection points.
            Repaint();
        }