﻿using System.IO;
using UnityEngine;
using UnityEngine.SceneManagement;
using UnityEditor.SceneManagement;
using UnityEditor;

public class RenameCurrentMapWindow : SearchableEditorWindow {

	public static Scene currentScene;
	public static string currentName, mapName, oldID, newName = "";
	public static bool foundMap;
	public Vector2 scrollSpot;
	const string randomChars = "BbCcDdFfGgHhJjKkLlMmNnPpQqRrSsTtVvWwXxYyZz0123456789";
	public static string[] removeChars = { "/", "\\", "\"", ":", "?", "<", ">", "|", "*", "~", ".", "@", "#", "$", "%", "^", "(", ")", "{", "}", "[", "]", "`", ";", ",", "!", "'", "+", "=", "Level Maker", "Tutorial Island", "GameIsland", "BR - Esports Launcher" };

	[MenuItem("Battle Royale/Custom Map Tools/Rename Current Map", false, 3)]
	public static void RenameTrack()
	{
		RenameCurrentMapWindow window = GetWindow<RenameCurrentMapWindow>("Map Renamer");

		newName = "";

		foundMap = FindCurrentMap();

		if (foundMap)
        {
			window.minSize = new Vector2(450, 162);
	        
			DebugChannelSO.OverrideRaise(
				"RenameCurrentMapWindow", 
				"Custom scene file for " + currentName + " found.", 
				new Color(148f/256f, 84f/256f, 0f/256f));
        }
        else
        {
	        window.minSize = new Vector2(320, 252);
	        
	        DebugChannelSO.OverrideRaise(
		        "RenameCurrentMapWindow", 
		        "Custom scene file for " + currentName + " not found!", 
		        new Color(148f/256f, 84f/256f, 0f/256f));
        }

		window.maxSize = window.minSize;
	}

	public static bool FindCurrentMap()
    {
		string[] tempNames = Directory.GetFiles(Application.dataPath + "/Scenes");

		if (tempNames.Length < 1)
        {
			return false;
		}

		foreach (string map in tempNames)
		{
			if (!map.Contains(".meta") && map.Contains(".unity") && map.Contains(SceneManager.GetActiveScene().name))
			{
				currentScene = SceneManager.GetActiveScene();

				currentName = currentScene.name;

				string[] splitArray = currentName.Split(char.Parse("_"));
				mapName = splitArray[0];
				oldID = splitArray[1];

				break;
            }
            else
            {
				mapName = "";
            }
        }

		if (mapName == "")
        {
			return false;
        }

		return true;
    }

	void OnGUI()
    {
		GUILayout.Space(6);
		GUILayout.BeginHorizontal();
		#region

			GUILayout.Space(6);
			GUILayout.BeginVertical();
			#region

				GUILayout.BeginVertical("Rename Your Map", "window");
				#region

					GUILayout.Space(5);

					GUIStyle myStyle = new GUIStyle(GUI.skin.label);
					myStyle.fontStyle = FontStyle.Bold;

					if (foundMap)
					{
						// ENTER NEW NAME DISPLAY //
						#region

						GUILayout.BeginHorizontal();
						#region

							GUILayout.Space(position.width / 2 - 153);

							GUILayout.Label("Current Map Name:", myStyle);

							GUILayout.Space(10);

							myStyle.fontStyle = FontStyle.Italic;

							GUILayout.Label(mapName, myStyle);

							GUILayout.FlexibleSpace();

						#endregion
						GUILayout.EndHorizontal();
						GUILayout.Space(10);

						myStyle = new GUIStyle(GUI.skin.textField);
						myStyle.alignment = TextAnchor.MiddleCenter;
						myStyle.fontSize = 18;
						myStyle.fixedHeight = 40;

						newName = GUILayout.TextField(newName, myStyle);

						GUILayout.FlexibleSpace();

						#endregion
					}
					else
					{
						// ASSET NOT FOUND DISPLAY //
						#region

						GUILayout.Label("Uh oh! We couldn't locate your Custom Map scene.", EditorStyles.wordWrappedLabel);

						GUILayout.Space(10);

						GUILayout.Label("Make sure your scene is placed in the Scenes folder.", EditorStyles.wordWrappedLabel);

						GUILayout.Space(10);

						GUILayout.Label("You can access the folder by clicking 'Window' at the top of your screen, then 'General -> Project'. The Scenes folder can be found in the default 'Assets' directory.", EditorStyles.wordWrappedLabel);

						GUILayout.Space(10);

						GUILayout.Label("Ask your instructor for help moving your scene, or you may contact one of our Tech Support agents by clicking the button below:", EditorStyles.wordWrappedLabel);

						GUILayout.Space(10);

						if (GUILayout.Button("Black Rocket Support"))
						{
							Application.OpenURL("https://www.blackrocket.com/help");
						}

						#endregion
					}

				#endregion
				GUILayout.EndVertical();

				if (foundMap)
				{
					// RANDOMIZE AND RENAME BUTTONS //
					#region

					GUILayout.BeginHorizontal();
					#region

						myStyle = new GUIStyle(GUI.skin.button);
						myStyle.fontStyle = FontStyle.Bold;

						if (GUILayout.Button("Randomize Name", myStyle, GUILayout.Height(50), GUILayout.Width(position.width / 2 - 12)))
						{
							newName = new RandomNames().RandomName;
	        
							DebugChannelSO.OverrideRaise(
								"RenameCurrentMapWindow", 
								"Name randomized to " + newName, 
								new Color(148f/256f, 84f/256f, 0f/256f));
						}

						if (newName != "")
						{
							foreach (string c in removeChars)
							{
								newName = newName.Replace(c, string.Empty);
							}
						}

						if (GUILayout.Button("Rename Map", myStyle, GUILayout.Height(50), GUILayout.Width(position.width / 2 - 12)))
						{
							if (newName == "")
							{
								EditorUtility.DisplayDialog("No New Map Name", "New map name was empty. Please enter a valid name to rename the map.", "Ok");
							}
							else if (newName == mapName)
							{
								EditorUtility.DisplayDialog("No New Map Name", "New map name was the same as the current name. Please enter a different name to rename the map.", "Ok");
							}
							else
							{
								
								DebugChannelSO.OverrideRaise(
									"RenameCurrentMapWindow", 
									"Renaming level to " + newName + "_" + oldID, 
									new Color(148f/256f, 84f/256f, 0f/256f));
									
								// Set our new name plus the old ID code
								newName = newName + "_" + oldID;

								// UPDATE LEVEL PREFAB //
								#region
                                
								// Find our terrain object
								Terrain currentTerrain = FindObjectOfType<Terrain>();
								
								// Get our level as the parent of our terrain
								GameObject _level = currentTerrain.transform.parent.gameObject;
								
								_level.GetComponent<LevelEditor>().NameEnforcementEnabled(false);
								
								_level.GetComponent<LevelEditor>().SetLevelName(newName);
								
								// Set the level name
								_level.name = newName;
								
								DebugChannelSO.OverrideRaise(
									"RenameCurrentMapWindow", 
									"Level prefab renamed to " + _level.name, 
									new Color(148f/256f, 84f/256f, 0f/256f));
                                
								// Rename the terrain in our scene
								currentTerrain.gameObject.name = newName + " Terrain";
								
								DebugChannelSO.OverrideRaise(
									"RenameCurrentMapWindow", 
									"Renamed terrain name to " + currentTerrain.gameObject.name, 
									new Color(148f/256f, 84f/256f, 0f/256f));
								
								if (PrefabUtility.IsPartOfPrefabInstance(_level)){
									PrefabUtility.UnpackPrefabInstance(_level, PrefabUnpackMode.Completely, InteractionMode.AutomatedAction);
									
									DebugChannelSO.OverrideRaise(
										"RenameCurrentMapWindow", 
										"Unpacked active level prefab", 
										new Color(148f/256f, 84f/256f, 0f/256f));
								}
								
                                // UPDATE TERRAIN OBJECT AND PREFAB //
                                #region
                                
                                // Rename the existing terrain asset
                                AssetDatabase.CopyAsset("Assets/Do Not Edit Or Delete/Terrains/" + currentName + " Terrain.asset", "Assets/Do Not Edit Or Delete/Terrains/" + newName + " Terrain.asset");
								
								DebugChannelSO.OverrideRaise(
									"RenameCurrentMapWindow", 
									"Copied current terrain from Assets/Do Not Edit Or Delete/Terrains/" + currentName + " Terrain.asset" +
									" to Assets/Do Not Edit Or Delete/Terrains/" + newName + " Terrain.asset", 
									new Color(148f/256f, 84f/256f, 0f/256f));

								currentTerrain.terrainData = (TerrainData)AssetDatabase.LoadAssetAtPath("Assets/Do Not Edit Or Delete/Terrains/" + newName + " Terrain.asset", typeof(Object));
								
								currentTerrain.GetComponent<TerrainCollider>().terrainData = currentTerrain.terrainData;
								
								DebugChannelSO.OverrideRaise(
									"RenameCurrentMapWindow", 
									"Terrain data set to new terrain data asset.", 
									new Color(148f/256f, 84f/256f, 0f/256f));
								
								#endregion

								// Create a new prefab 
								PrefabUtility.SaveAsPrefabAsset(_level, "Assets/Levels/" + _level.name + ".prefab");
								
								DebugChannelSO.OverrideRaise(
									"RenameCurrentMapWindow", 
									"Saved renamed level prefab as Assets/Levels/" + _level.name + ".prefab", 
									new Color(148f/256f, 84f/256f, 0f/256f));

								#endregion

								// CREATE NEW SCENE //
								#region
								EditorSceneManager.SaveOpenScenes();

								// Save the current scene under the new name
								EditorSceneManager.SaveScene(SceneManager.GetActiveScene(), "Assets/Scenes/" + newName + ".unity");
								
								DebugChannelSO.OverrideRaise(
									"RenameCurrentMapWindow", 
									"Copying current scene from Assets/Scenes/" + currentName + ".unity" +
									" to Assets/Scenes/" + newName + ".unity", 
									new Color(148f/256f, 84f/256f, 0f/256f));

                                // Open the renamed copy
								EditorSceneManager.OpenScene("Assets/Scenes/" + newName + ".unity");
								
								DebugChannelSO.OverrideRaise(
									"RenameCurrentMapWindow", 
									"Opened new scene at Assets/Scenes/" + newName + ".unity", 
									new Color(148f/256f, 84f/256f, 0f/256f));
                                
								#endregion

								
								// INSTANTIATE NEW LEVEL PREFAB //
								#region
								Terrain _newTerrain = FindObjectOfType<Terrain>();

								_newTerrain.terrainData = (TerrainData)AssetDatabase.LoadAssetAtPath("Assets/Do Not Edit Or Delete/Terrains/" + newName + " Terrain.asset", typeof(Object));

								_newTerrain.GetComponent<TerrainCollider>().terrainData = _newTerrain.terrainData;
								#endregion

                                // DELETE PREVIOUS LEVEL //
                                #region
                                
                                // Delete the old scene
								AssetDatabase.DeleteAsset("Assets/Scenes/" + currentName + ".unity");
								
								DebugChannelSO.OverrideRaise(
									"RenameCurrentMapWindow", 
									"Deleted old scene file at Assets/Scenes/" + currentName + ".unity", 
									new Color(148f/256f, 84f/256f, 0f/256f));

								// Delete the old prefab
								AssetDatabase.DeleteAsset("Assets/Levels/" + currentName + ".prefab");
								
								DebugChannelSO.OverrideRaise(
									"RenameCurrentMapWindow", 
									"Deleted old prefab file at Assets/Levels/" + currentName + ".prefab", 
									new Color(148f/256f, 84f/256f, 0f/256f));

								// Delete the old terrain
								AssetDatabase.DeleteAsset("Assets/Do Not Edit Or Delete/Terrains/" + currentName + " Terrain.asset");
								
								DebugChannelSO.OverrideRaise(
									"RenameCurrentMapWindow", 
									"Deleted old prefab file at Assets/Do Not Edit Or Delete/Terrains/" + currentName + " Terrain.asset", 
									new Color(148f/256f, 84f/256f, 0f/256f));

                                #endregion

								_newTerrain.transform.parent.gameObject.GetComponent<LevelEditor>().NameEnforcementEnabled(true);
								
								DebugChannelSO.OverrideRaise(
									"RenameCurrentMapWindow", 
									new string[] {
										"Map has been renamed!",
										"Thank you for your patience."}, 
									new Color(148f/256f, 84f/256f, 0f/256f));

                                this.Close();
							}
						}

					#endregion
					GUILayout.EndHorizontal();

					#endregion
				}

			#endregion
			GUILayout.EndVertical();
			GUILayout.Space(6);

		#endregion
		GUILayout.EndHorizontal();
		GUILayout.Space(6);
	}
}
