/// <summary>
        /// Return true if the scene belongs to the persistant scene bundle
        /// </summary>
        /// <param name="scene"></param>
        /// <returns></returns>
        public static bool IsPersistantScene(this SceneAsset scene)
        {
            if (scene == null)
            {
                return(false);
            }
            SceneBundleList currentList = EnhancedSceneManager.GetCurrentSceneList();

            if (currentList == null)
            {
                return(false);
            }
            if (currentList.PersistantScenesBundle == null)
            {
                return(false);
            }

            for (int i = 0; i < currentList.PersistantScenesBundle.ScenesCount; i++)
            {
                if (currentList.PersistantScenesBundle.ContainsScene(scene.name))
                {
                    return(true);
                }
            }

            return(false);
        }
        /// <summary>
        /// Display the full list of scene bundles
        /// </summary>
        private void DisplaySceneBundles(SceneBundleList targetList)
        {
            EditorGUILayout.LabelField("Load Scene Bundle");

            int columnsPerRow = (int)displayMode;
            int columnIndex   = 0;

            EditorGUILayout.BeginHorizontal();

            for (int i = 0; i < targetList.ScenesBundles.Length; i++)
            {
                if (targetList.ScenesBundles[i] == null)
                {
                    continue;
                }
                DisplaySceneBundleButton(targetList.ScenesBundles[i]);

                columnIndex++;

                if (columnIndex >= columnsPerRow)
                {
                    columnIndex = 0;
                    EditorGUILayout.EndHorizontal();
                    EditorGUILayout.BeginHorizontal();
                }
                else
                {
                    GUILayout.Space(10f);
                }
            }
            EditorGUILayout.EndHorizontal();
        }
        /// <summary>
        /// Set a scene bundle list has current in the application
        /// </summary>
        /// <param name="list"></param>
        public static void SetSceneBundleListHasCurrent(SceneBundleList list)
        {
            Type       sceneBundleListType       = typeof(EnhancedSceneManager);
            MethodInfo setCurrentSceneListMethod = sceneBundleListType.GetMethod("SetCurrentSceneList", BindingFlags.NonPublic | BindingFlags.Static);

            setCurrentSceneListMethod.Invoke(null, new object[] { list });
            EnhancedSceneBuildManager.UpdateBuildScenes();
        }
        /// <summary>
        /// Display the current scene list field
        /// </summary>
        private void DisplayCurrentSceneList()
        {
            EditorGUI.BeginChangeCheck();
            SceneBundleList list = EditorGUILayout.ObjectField("Current Bundle List", EnhancedSceneManager.GetCurrentSceneList(), typeof(SceneBundleList), false) as SceneBundleList;

            if (EditorGUI.EndChangeCheck() && list != null)
            {
                EditorEnhancedSceneManager.SetSceneBundleListHasCurrent(list);
            }
        }
        /// <summary>
        /// Creates a new Scene Bundle List in the target bundle
        /// </summary>
        private void CreateSceneBundleList()
        {
            string path = EditorUtility.SaveFilePanelInProject("Create new Scene Bundle List", "NewSceneBundleList.asset", "asset", "Please enter a name to the Scene Bundle list");

            if (path.Length <= 0)
            {
                return;
            }

            SceneBundleList newSceneBundleList = SceneBundleList.CreateInstance <SceneBundleList>();

            AssetDatabase.CreateAsset(newSceneBundleList, path);
            AssetDatabase.SaveAssets();
            AssetDatabase.Refresh();

            EditorEnhancedSceneManager.SetSceneBundleListHasCurrent(newSceneBundleList);
        }
        /// <summary>
        /// Check the scene data and scene bundles
        /// </summary>
        /// <returns></returns>
        private static void CheckDatas()
        {
            SceneBundleList           currentSceneList  = EnhancedSceneManager.GetCurrentSceneList();
            List <SerializedProperty> propertiesToCheck = new List <SerializedProperty>();

            if (currentSceneList.PersistantScenesBundle != null)
            {
                SerializedObject sceneBundleObject = new SerializedObject(currentSceneList.PersistantScenesBundle);
                sceneBundleObject.FindProperty("sceneAssets").CleanNullOrSimilarRefs();
            }

            SerializedObject   sceneListSO          = new SerializedObject(currentSceneList);
            SerializedProperty sceneBundlesProperty = sceneListSO.FindProperty("scenesBundles");

            for (int i = 0; i < sceneBundlesProperty.arraySize; i++)
            {
                SceneBundleEditor.GenerateSceneLabels(new SerializedObject(sceneBundlesProperty.GetArrayElementAtIndex(i).objectReferenceValue));
            }

            //Reupdate the build scenes
            UpdateBuildScenes();
        }
        /// <summary>
        /// Update all build scenes, check if
        /// </summary>
        public static void UpdateBuildScenes()
        {
            SceneBundleList currentSceneList = EnhancedSceneManager.GetCurrentSceneList();

            if (currentSceneList == null)
            {
                return;
            }

            //Create the container of build scenes
            var buildSettingsScenes = new List <EditorBuildSettingsScene>();

            //Add Startup Scene
            SceneAsset startupSceneAsset = Resources.Load <SceneAsset>("StartupScene");
            var        startupScene      = new EditorBuildSettingsScene(AssetDatabase.GetAssetPath(startupSceneAsset), true);

            buildSettingsScenes.Add(startupScene);

            bool BuildContainsScene(string path)
            {
                for (int i = 0; i < buildSettingsScenes.Count; i++)
                {
                    if (buildSettingsScenes[i].path == path)
                    {
                        return(true);
                    }
                }
                return(false);
            }

            //Add persistant scenes
            if (currentSceneList.PersistantScenesBundle != null)
            {
                SceneAsset[] peristantScenes = SceneBundleEditor.GetBundleScenesAssets(currentSceneList.PersistantScenesBundle);
                foreach (SceneAsset sceneAsset in peristantScenes)
                {
                    var persistantBuildScene = new EditorBuildSettingsScene(AssetDatabase.GetAssetPath(sceneAsset), true);

                    if (!BuildContainsScene(persistantBuildScene.path))
                    {
                        buildSettingsScenes.Add(persistantBuildScene);
                    }
                }
            }

            //Add scenes
            foreach (SceneBundle bundle in currentSceneList.ScenesBundles)
            {
                SceneAsset[] sceneAssets = SceneBundleEditor.GetBundleScenesAssets(bundle);
                foreach (SceneAsset sceneAsset in sceneAssets)
                {
                    var buildScene = new EditorBuildSettingsScene(AssetDatabase.GetAssetPath(sceneAsset), true);

                    if (!BuildContainsScene(buildScene.path))
                    {
                        buildSettingsScenes.Add(buildScene);
                    }
                }
            }

            //Replace the current build setting scenes with new list
            EditorBuildSettings.scenes = buildSettingsScenes.ToArray();
        }
        /// <summary>
        /// Setup the scene assets reorderable list display and callbacks
        /// </summary>
        private void SetupSceneAssetsReorderableList()
        {
            sceneAssetsList = new ReorderableList(serializedObject, serializedObject.FindProperty("sceneAssets"), true, true, true, true)
            {
                drawHeaderCallback = rect => {
                    EditorGUI.LabelField(rect, "Scenes");
                },

                drawElementCallback = (rect, index, a, h) => {
                    Rect propertyRect = rect;
                    propertyRect.height = EditorGUIUtility.singleLineHeight;
                    GUIContent label = new GUIContent();

                    if (index == 0)
                    {
                        label.text = "Active Scene";
                        EditorUtils.BeginColorField(EditorUtils.validColor);
                    }
                    else
                    {
                        label.text = "Scene " + index;
                    }

                    SceneBundleList currentSceneList = EnhancedSceneManager.GetCurrentSceneList();

                    EditorGUI.BeginChangeCheck();
                    SerializedProperty property = sceneAssetsList.serializedProperty.GetArrayElementAtIndex(index);
                    EditorGUI.PropertyField(propertyRect, property, label);

                    if (EditorGUI.EndChangeCheck())
                    {
                        if (currentSceneList.PersistantScenesBundle != target && (property.objectReferenceValue as SceneAsset).IsPersistantScene())
                        {
                            Debug.LogWarning("Cannot register persistant scenes");
                            property.objectReferenceValue = null;
                        }
                        else
                        {
                            //Update the generated labels
                            UpdateScenesLabels();

                            //If this scene doesn't exist in the build settings, refresh it
                            if (property.objectReferenceValue != null && !EnhancedSceneBuildManager.IsSceneInBuild(property.objectReferenceValue as SceneAsset))
                            {
                                EnhancedSceneBuildManager.UpdateBuildScenes();
                            }
                        }
                    }

                    if (index == 0)
                    {
                        EditorUtils.EndColorField();
                    }
                },

                onReorderCallback = list => {
                    UpdateScenesLabels();
                },

                onAddCallback = list => {
                    AddScene();
                },

                onCanRemoveCallback = list => {
                    return(list.index != 0);
                },

                onRemoveCallback = list => {
                    SerializedProperty prop = list.serializedProperty;
                    if (prop.GetArrayElementAtIndex(list.index) != null)
                    {
                        prop.DeleteArrayElementAtIndex(list.index);
                    }
                    prop.DeleteArrayElementAtIndex(list.index);
                    UpdateScenesLabels();
                    EnhancedSceneBuildManager.UpdateBuildScenes();
                }
            };
        }