﻿using System.IO;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
using UnityEditor.SceneManagement;
using UnityEngine.Animations;
using UnityEditor;

public class CreateNewMapWindow : SearchableEditorWindow
{

	public string mapName = "My Map Name", sceneName = "", additionalChars = "";
	const string randomChars = "BbCcDdFfGgHhJjKkLlMmNnPpQqRrSsTtVvWwXxYyZz0123456789";
	string[] removeChars = { "/", "\\", "\"", ":", "?", "<", ">", "|", "*", "~", ".", "@", "#", "$", "%", "^", "(", ")", "{", "}", "[", "]", "`", ";", ",", "!", "'", "+", "=", "Level Maker", "Tutorial Island", "GameIsland", "BR - Esports Launcher" };

	public GameObject defaultLevel, defaultPlane;
	public string levelName;
	public string meshName;
	public bool makeLevel = false;
	public bool destroyMe = false;


	[MenuItem("Battle Royale/Custom Map Tools/Create New Map", false, 2)]
	public static void CreateNewMap()
	{
		EditorSceneManager.SaveCurrentModifiedScenesIfUserWantsTo();
		CreateNewMapWindow window = GetWindow<CreateNewMapWindow>("Map Creator");
		window.minSize = new Vector2(450, 162);
		window.maxSize = window.minSize;
	}

	void OnGUI()
	{
		GUILayout.Space(6);

		GUILayout.BeginHorizontal();
		#region

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

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

					GUILayout.Space(5);

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

					GUILayout.Label("Maps can be renamed later!", myStyle);

					GUILayout.Space(10);

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

					mapName = GUILayout.TextField(mapName, myStyle);

					GUILayout.FlexibleSpace();

				#endregion
				GUILayout.EndVertical();

				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)))
					{
						mapName = new RandomNames().RandomName;
	        
						DebugChannelSO.OverrideRaise(
							"CreateNewMapWindow", 
							"Name randomized to " + mapName, 
							Color.cyan);
					}

					AdjustMapName();
					
					if (GUILayout.Button("Create Map", myStyle, GUILayout.Height(50), GUILayout.Width(position.width / 2 - 12)))
					{
						mapName = mapName.Replace("My Map Name", string.Empty);
						
						if (mapName == "")
						{
							EditorUtility.DisplayDialog("Missing Name", "Please enter a valid map name.", "Ok");

							mapName = "My Map Name";

							return;
						}

						AssetDatabase.CopyAsset("Assets/Do Not Edit OR Delete/Core Scenes/Level Maker/Level Maker Empty.unity", "Assets/Scenes/" + sceneName + ".unity");
						
						DebugChannelSO.OverrideRaise(
							"CreateNewMapWindow", 
							"New Map Scene Created", 
							Color.cyan);
						
						EditorSceneManager.OpenScene("Assets/Scenes/" + sceneName + ".unity", OpenSceneMode.Single);

						DebugChannelSO.OverrideRaise(
							"CreateNewMapWindow", 
							"Opened " + mapName, 
							Color.cyan);
						
						InstantiateNewMapPrefab();

						this.Close();
					}

				#endregion
				GUILayout.EndHorizontal();

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

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

    void AdjustMapName()
	{

		foreach (string c in removeChars)
		{
			mapName = mapName.Replace(c, string.Empty);
		}

		additionalChars = "";

		for (int i = 0; i < 6; i++)
		{
			additionalChars += randomChars[Random.Range(0, randomChars.Length)];
		}

		sceneName = mapName + "_" + additionalChars;
	}

	void InstantiateNewMapPrefab()
    {
		if (!defaultLevel)
		{
			defaultLevel = AssetDatabase.LoadAssetAtPath("Assets/Do Not Edit OR Delete/Terrains/Prefabs/In Use/Scene Setup/Default Level Prefab.prefab", typeof(GameObject)) as GameObject;
		}

		if (defaultLevel)
		{
			// Instantiate the level prefab
			GameObject myLevel = GameObject.Instantiate(defaultLevel);
			myLevel.name = sceneName;

			DebugChannelSO.OverrideRaise(
				"CreateNewMapWindow", 
				"Appending random characters: " + additionalChars, 
				Color.cyan);
				
			DebugChannelSO.OverrideRaise(
				"CreateNewMapWindow", 
				"Level prefab instantiated.", 
				Color.cyan);

			myLevel.GetComponent<LevelEditor>().SetLevelName(sceneName);
				
			DebugChannelSO.OverrideRaise(
				"CreateNewMapWindow", 
				"Level Editor name set to " + sceneName + ".", 
				Color.cyan);

			// Generate terrain data
			TerrainData myData = new TerrainData();
			myData.size = new Vector3(50, 400, 50);
			myData.heightmapResolution = 257;
			myData.baseMapResolution = 1024;
			myData.SetDetailResolution(1024, 8);
			
			DebugChannelSO.OverrideRaise(
				"CreateNewMapWindow", 
				"Terrain data initialized.", 
				Color.cyan);
			
            string[] _layerNames = new string[]
            {
                "00 - Green",
                "01 - Brown",
                "02 - Blue",
                "03 - Orange",
                "04 - Yellow",
                "05 - Red",
                "06 - Purple",
                "07 - Magenta",
                "08 - Black",
                "09 - White"
            };

            TerrainLayer[] _layers = new TerrainLayer[10];
            
            for(int i = 0; i < 10; i++)
                _layers[i] = AssetDatabase.LoadAssetAtPath<TerrainLayer>("Assets/Textures/Terrain Textures/" + _layerNames[i] + ".terrainlayer");
            
            myData.terrainLayers = _layers;

			DebugChannelSO.OverrideRaise(
				"CreateNewMapWindow", 
				"Terrain layers applied.", 
				Color.cyan);

            // Instantiate terrain and assign its data
            AssetDatabase.CreateAsset(myData, "Assets/Do Not Edit OR Delete/Terrains/" + sceneName + " Terrain.asset");
			GameObject myTerrain = Terrain.CreateTerrainGameObject(myData);
			myTerrain.name = sceneName + " Terrain";
			myTerrain.transform.SetParent(myLevel.transform);
			myTerrain.transform.position = Vector3.one * -200;

			DebugChannelSO.OverrideRaise(
				"CreateNewMapWindow", 
				"Terrain asset created as " + sceneName + " Terrain.asset.", 
				Color.cyan);

			// Set up texture data for the terrain
			string[] tGuids = AssetDatabase.FindAssets("t:Texture2D", new string[] { "Assets/Textures/Terrain Textures" });
			TerrainData checkData = myTerrain.GetComponent<Terrain>().terrainData;
			SplatPrototype[] terrainTextures = new SplatPrototype[tGuids.Length];

			// Assign texture data
			for (int t = 0; t < tGuids.Length; t++)
			{
				string myAssetPath = AssetDatabase.GUIDToAssetPath(tGuids[t]);
				terrainTextures[t] = new SplatPrototype();
				terrainTextures[t].texture = AssetDatabase.LoadAssetAtPath<Texture2D>(myAssetPath);
			}

			DebugChannelSO.OverrideRaise(
				"CreateNewMapWindow", 
				"Terrain texture data assigned.", 
				Color.cyan);

			// Assign terrain height data
			int terrainX = checkData.heightmapWidth;
			int terrainY = checkData.heightmapHeight;
			float[,] heights = checkData.GetHeights(0, 0, terrainX, terrainY);
			for (int x = 0; x < terrainX; x++)
			{
				for (int y = 0; y < terrainY; y++)
				{
					heights[x, y] = 0.5f;
				}
			}

			myTerrain.GetComponent<Terrain>().terrainData.SetHeights(0, 0, heights);
			
			DebugChannelSO.OverrideRaise(
				"CreateNewMapWindow", 
				"Terrain height map generated.", 
				Color.cyan);
				
			DebugChannelSO.OverrideRaise(
				"CreateNewMapWindow", 
				new string[]{
					"Level generation complete!",
					"Happy building!"}, 
				Color.cyan);
		}
        else
        {
			EditorUtility.DisplayDialog("Missing Default Level Prefab", "The default level prefab is missing. If you have made any changes to your 'Do Not Edit' folder, please open a fresh project or contact Black Rocket Tech Support at https://www.blackrocket.com/help.", "Ok");
		
	        DebugChannelSO.OverrideRaise(
		        "CreateNewMapWindow", 
		        new string[] {
		        	"The default level prefab is missing!", 
		        	"Contact support at https://www.blackrocket.com/help"},
		        Color.cyan,
		        DebugChannelSO.Severity.Error);
        }
	}
}
