using UnityEngine;
using System.Collections.Generic;

public class Map {
	private static Vector2 altitudePerlinOffset = new Vector2(1, 0);
	private static Vector2 temperaturePerlinOffset = new Vector2(100, 0);
	private static Vector2 humidityPerlinOffset = new Vector2(0, 100);

	public static HashSet<Region> regions = new HashSet<Region>();

	public static void init(uint width, uint height) {
		Helper.perlinCoeff = new Vector2(2, 2);

		Region[,] grid = new Region[width, height];

		Vector3 sum = new Vector3();
		for (uint w = 0; w < width; w++) {
			for (uint h = 0; h < height; h++) {
				float offsetH = w % 2 == 0 ? 0 : Region.height / 2;
				Vector3 pos = new Vector3(w * Region.compressedWidth, h * Region.height + offsetH, 0);
				Region region = GameObject.Instantiate(Controller.regionTemplate, pos, Quaternion.identity).GetComponent<Region>();

				region.altitude = Helper.getPerlinValue((float)w/width, (float)h/height, altitudePerlinOffset);

				float normH = ((float)h/(height-1));
				float noiseTemperature = Helper.getPerlinValue((float)w/width, (float)h/height, temperaturePerlinOffset);
				region.temperature = Mathf.Clamp01((-Mathf.Pow((normH*2 - 1), 2) + 1) + noiseTemperature * 0.3f);
				region.humidity = Helper.getPerlinValue((float)w/width, (float)h/height, humidityPerlinOffset);

				region.assignBiome();
				region.updateSprite(Controller.MapMode.Terrain);

				regions.Add(region);

				grid[w, h] = region;
				region.setPos(w, h);

				sum += pos;
			}
		}
		sum.z = -(width * height);
		Controller.mainCamera.transform.position = sum / (width * height);

		//Ngh computation
		for (uint w = 0; w < width; w++) {
			for (uint h = 0; h < height; h++) {
				grid[w, h].nghs.Add(grid[(w + width - 1) % width, h]);
				grid[w, h].nghs.Add(grid[(w + width + 1) % width, h]);

				if (w % 2 == 0) {
					if (h >= 1) {
						grid[w, h].nghs.Add(grid[(w + width - 1) % width, h - 1]);
						grid[w, h].nghs.Add(grid[(w + width + 1) % width, h - 1]);
					}

				}
				else {
					if (h < height - 1) {
						grid[w, h].nghs.Add(grid[(w + width - 1) % width, h + 1]);
						grid[w, h].nghs.Add(grid[(w + width + 1) % width, h + 1]);
					}
				}

				if (h >= 1) {
					grid[w, h].nghs.Add(grid[w, h - 1]);
				}
				if (h < height - 1) {
					grid[w, h].nghs.Add(grid[w, h + 1]);
				}
			}
		}
	}
}
