using GadgetCore.API;
using HarmonyLib;
using System.Collections;
using System.Reflection;
using UnityEngine;

namespace WorldPlatforms.Patches
{

  [HarmonyPatch(typeof(SpawnerScript))]
  [HarmonyPatch("World")]
  [HarmonyGadget("WorldPlatforms")]
  public static class Patch_SpawnerScript_World
  {
    [HarmonyPostfix]
    public static bool Prefix(SpawnerScript __instance, int[] s)
		{
			__instance.StartCoroutine(__instance.SpawnerScriptWorld(s));
      return false;
    }

    public static IEnumerator SpawnerScriptWorld(this SpawnerScript instance, int[] s)
    {
      if (GameScript.districtLevel == 0)
      {
        GameScript.districtLevel = 1;
      }

      var field = typeof(SpawnerScript).GetField("gameScript", BindingFlags.NonPublic | BindingFlags.GetField | BindingFlags.Instance);
      var gameScript = field.GetValue(instance) as GameScript;

      MenuScript.player.GetComponent<NetworkView>().RPC("Invis", RPCMode.All, new object[0]);
      gameScript.fadeObj.SendMessage("fadeOut2");
			yield return new WaitForSeconds(0.5f);
			MenuScript.player.SendMessage("Reset");
      GameScript.inInstance = true;
      instance.ship.SetActive(false);
      SpawnerScript.curBiome = s[0];
      SpawnerScript.lastBiome = s[0];
      instance.bg[0].GetComponent<Renderer>().material = (Material)Resources.Load("bg/b" + SpawnerScript.curBiome + "bg0");
      instance.bg[1].GetComponent<Renderer>().material = (Material)Resources.Load("bg/b" + SpawnerScript.curBiome + "bg1");
      instance.bg[2].GetComponent<Renderer>().material = (Material)Resources.Load("bg/b" + SpawnerScript.curBiome + "bg2");
      instance.bg[3].GetComponent<Renderer>().material = (Material)Resources.Load("bg/b" + SpawnerScript.curBiome + "bg3");
			//float[] pc = instance.GetParallaxColors(SpawnerScript.curBiome);
			//float[] lc = instance.GetLight(SpawnerScript.curBiome);
			//instance.mainLight.gameObject.SetActive(true);
			//instance.mainLight.GetComponent<Light>().color = new Color(lc[0], lc[1], lc[2], lc[3]);
			//instance.backLights.SetActive(true);
			//instance.backLights.GetComponent<Renderer>().material = (Material)Resources.Load("par/parallax" + SpawnerScript.curBiome);

			var fieldGridWidth = typeof(SpawnerScript).GetField("gridWidth", BindingFlags.NonPublic | BindingFlags.GetField | BindingFlags.Instance);
			var gridWidth = (int) fieldGridWidth.GetValue(instance);

			var fieldGridHeight = typeof(SpawnerScript).GetField("gridHeight", BindingFlags.NonPublic | BindingFlags.GetField | BindingFlags.Instance);
			var gridHeight = (int) fieldGridHeight.GetValue(instance);

			var fieldChunks = typeof(SpawnerScript).GetField("chunks", BindingFlags.NonPublic | BindingFlags.GetField | BindingFlags.Instance);
			var chunks = fieldChunks.GetValue(instance) as GameObject[];

			var fieldMidChunks = typeof(SpawnerScript).GetField("midChunks", BindingFlags.NonPublic | BindingFlags.GetField | BindingFlags.Instance);
			var midChunks = fieldMidChunks.GetValue(instance) as GameObject[];


			int[,] grid = new int[gridWidth,gridHeight];
			int b = 0;
			int temp = 1;
			int y = -64 * (gridHeight / 2);
			int num = 0;
			int midCounter = 0;
			for (int i = 0; i < gridWidth; i++)
			{
				for (b = 0; b <gridHeight; b++)
				{
					grid[i, b] = s[temp];
					temp++;
				}
			}
			chunks[num] = (GameObject)UnityEngine.Object.Instantiate(Resources.Load("z/entrance"), new Vector3(224.5f, 0f, 5f), Quaternion.Euler(0f, 0f, 0f));
			num++;
			Texture2D texture2DSolid = GadgetCoreAPI.LoadTexture2D("midCoverChunk0.png", false);
			Texture2D texture2DNonSolid = GadgetCoreAPI.LoadTexture2D("midHiddenChunk0.png", false);
			for (int i = 0; i < gridWidth; i++)
			{
				for (b = 0; b <gridHeight; b++)
				{
					if (grid[i, b] > 0)
					{
						chunks[num] = (GameObject)UnityEngine.Object.Instantiate(Resources.Load("z/chunk"), new Vector3((float)(300 + i * 128), (float)(y + b * 64), 5f), Quaternion.Euler(0f, 180f, 180f));
						int[] array = new int[4];
						if (b > 0 && grid[i, b + 1] > 0)
						{
							array[0] = 1;
						}
						if (i < gridWidth - 1 && grid[i + 1, b] > 0)
						{
							array[1] = 1;
						}
						if (b <gridHeight - 1 && grid[i, b - 1] > 0)
						{
							array[2] = 1;
						}
						if (i > 0 && grid[i - 1, b] > 0)
						{
							array[3] = 1;
						}
						chunks[num].SendMessage("InitializeSides", array);
						num++;
						if (SpawnerScript.curBiome != 8 && SpawnerScript.curBiome != 11)
						{

							GameObject gameObject = (GameObject)UnityEngine.Object.Instantiate(Resources.Load("z/midChunk0"), new Vector3((float)(300 + i * 128), (float)(y + b * 64), 5f), Quaternion.Euler(0f, 180f, 180f));
							gameObject.layer = 23;


							BoxCollider colliderRight = gameObject.GetComponent<BoxCollider>();
							colliderRight.size = new Vector3(0.0625f, 0.375f, 5);
							colliderRight.center = new Vector3(0.71875f, 0, 5);

							BoxCollider colliderTop = gameObject.AddComponent<BoxCollider>();
							colliderTop.size = new Vector3(1.5f, 0.0625f, 5);
							colliderTop.center = new Vector3(0f, -0.15625f, 5);

							BoxCollider colliderBottom = gameObject.AddComponent<BoxCollider>();
							colliderBottom.size = new Vector3(1.5f, 0.0625f, 5);
							colliderBottom.center = new Vector3(0f, 0.15625f, 5);

							GameObject triggerObject = new GameObject("Hidden Trigger");
							triggerObject.transform.SetParent(gameObject.transform);
							triggerObject.transform.localScale = new Vector3(1.4375f, 0.25f, 5);
							triggerObject.transform.localPosition = new Vector3(-0.03125f, 0f, 5);
							BoxCollider trigger = triggerObject.AddComponent<BoxCollider>();

							trigger.gameObject.layer = 0;
							trigger.isTrigger = true;

							NonSolidWallScript script =  trigger.gameObject.AddComponent<NonSolidWallScript>();
							script.InitVars(texture2DSolid, texture2DNonSolid, gameObject.GetComponent<Renderer>());
							


							midChunks[midCounter] = gameObject;
							midChunks[midCounter].gameObject.SendMessage("Init", chunks[num - 1]);
							midCounter++;
							/*
							if (grid[i, b] > 4)
							{
								midChunks[midCounter] = (GameObject)UnityEngine.Object.Instantiate(Resources.Load("z/midChunk0"), new Vector3((float)(300 + i * 128), (float)(y + b * 64), 5f), Quaternion.Euler(0f, 180f, 180f));
								midChunks[midCounter].gameObject.SendMessage("Init", chunks[num - 1]);
								midCounter++;
							}
							else if (grid[i, b] > 2)
							{
								GameObject gameObject = (GameObject)UnityEngine.Object.Instantiate(Resources.Load("z/midChunk0"), new Vector3((float)(300 + i * 128), (float)(y + b * 64), 5f), Quaternion.Euler(0f, 180f, 180f));
								BoxCollider collider = gameObject.GetComponent<BoxCollider>();
								collider.center = new Vector3(0.71875f, 0, 5);
								collider.size = new Vector3(0.0625f, 0.375f, 5);
								midChunks[midCounter] = gameObject;
								midChunks[midCounter].gameObject.SendMessage("Init", chunks[num - 1]);
								midCounter++;
							}
							else if (grid[i, b] > 0)
							{
								midChunks[midCounter] = (GameObject)UnityEngine.Object.Instantiate(Resources.Load("z/midChunk1"), new Vector3((float)(300 + i * 128), (float)(y + b * 64), 5f), Quaternion.Euler(0f, 180f, 180f));
								midChunks[midCounter].gameObject.SendMessage("Init", chunks[num - 1]);
								midCounter++;
							}*/
						}
					}
				}
			}
			chunks[num - 1].SendMessage("AlmostEnd");
			chunks[num] = (GameObject)UnityEngine.Object.Instantiate(Resources.Load("z/exit"), new Vector3(503.5f, chunks[num - 1].transform.position.y, 5f), Quaternion.Euler(0f, 0f, 180f));
			num++;
			if (Network.isServer)
			{
				//instance.SpawnObjectives(num - 1);
				chunks[num - 1].SendMessage("SpawnEndPortal");
			}

			gameScript.TeleportPlayer(0);
			yield return new WaitForSeconds(0.8f);
			instance.musicbox.SendMessage("PlayTune", SpawnerScript.curBiome);
      gameScript.fadeObj.SendMessage("fadeIn2");
      GameScript.wormBossCounter = 0;
      GameScript.hivemindCounter = 0;
    }
  }
}
