using System.Linq;
using UnityEngine;

using Gamelogic.Grids;

namespace Gamelogic.Grids.Examples
{
	public class Honeycomb : GLMonoBehaviour, IResetable
	{
		public GameObject playerPrefab;
		public HoneyCombBlock HoneyCombBlockPrefab;
		public GameObject root;

		private PointyHexGrid<HoneyCombBlock> grid;
		private MyMap map;
		private GameObject player;


		public class MyMap : IMap3D<PointyHexPoint>
		{
			private readonly IMap3D<PointyHexPoint> map;

			public MyMap()
			{
				map = new PointyHexMap(new Vector2(.69f, .80f)*0.34f*10)
					.Scale(1.2f)
					.To3DXZ();
			}

			public Vector3 this[PointyHexPoint point]
			{
				get
				{
					var worldPoint = map[point];

					return new Vector3(worldPoint.x, point.Magnitude()*-1, worldPoint.z);
				}
			}

			public PointyHexPoint this[Vector3 point]
			{
				get { return map[point]; }
			}

			public IMap<PointyHexPoint> To2D()
			{
				return map.To2D();
			}
		}

		public void Start()
		{
			Reset();
		}

		public void Reset()
		{

			root.transform.DestroyChildren();

			if (player != null)
			{
				Destroy(player.gameObject);
			}

			BuildGrid();

			player = Instantiate(playerPrefab);
			player.transform.localPosition = map[PointyHexPoint.Zero];
			player.transform.SetLocalY(10);
		}

		public void BuildGrid()
		{
			const int size = 25;
			grid = PointyHexGrid<HoneyCombBlock>.Hexagon(size);

			map = new MyMap();

			foreach (var point in grid)
			{
				var block = Instantiate(HoneyCombBlockPrefab);

				block.transform.parent = root.transform;
				block.transform.localPosition = map[point];

				if (point == PointyHexPoint.Zero || IsBorderCell(point))
				{
					block.Height = 0;
				}
				else if (point.GetColor2_4() == 0)
				{
					if ((point/2).GetColor2_4() == 0)
					{
						block.Height = 80;
					}
					else
					{
						block.Height = 40;
					}
				}
				else
				{
					block.Height = 3;
					block.IsCrusher = true;
				}
				
				float gray = 1 - (point.Magnitude())/(float) size;
				
				block.SetColor(new Color(Random.value*0.2f + 0.8f, 1 - gray + Random.value*0.4f - 0.2f,
					1f + Random.value*0.3f - 0.2f));
			}
		}

		public void Update()
		{
			if (player.transform.position.y < -100 || Input.GetKeyDown(KeyCode.R))
			{
				Reset();
			}
		}

		public bool IsBorderCell(PointyHexPoint point)
		{
			return grid.GetNeighbors(point).Count() < 6;
		}
	}
}