﻿using Gamelogic;
using Gamelogic.Grids;
using UnityEngine;

namespace Gamelogic.Grids.Examples
{
	public class FEVTest : GLMonoBehaviour
	{
		public SpriteCell faceCell;
		public SpriteCell edgeCell;
		public SpriteCell vertexCell;

		private int selectionMode = 0;
		private PointyHexGrid<SpriteCell> faces;
		private IMap3D<PointyHexPoint> faceMap;
		private PointyRhombGrid<SpriteCell> edges;
		private IMap3D<PointyRhombPoint> edgeMap;
		private FlatTriGrid<SpriteCell> vertices;
		private IMap3D<FlatTriPoint> vertexMap;

		public void Start()
		{
			faces = PointyHexGrid<SpriteCell>.Hexagon(3);

			faceMap = new PointyHexMap(faceCell.Dimensions)
				.WithWindow(ExampleUtils.ScreenRect)
				.AlignMiddleCenter(faces)
				.To3DXY();

			foreach (var point in faces)
			{
				var cell = Instantiate(faceCell);

				cell.transform.parent = transform;
				cell.transform.localScale = Vector3.one;
				cell.transform.localRotation = Quaternion.identity;
				cell.transform.localPosition = faceMap[point];

				cell.HighlightOn = false;
				cell.Color = ExampleUtils.Colors[0];

				faces[point] = cell;
			}

			edges = faces.MakeEdgeGrid<SpriteCell>() as PointyRhombGrid<SpriteCell>;

			edgeMap = new PointyRhombMap(new Vector2(.7f, .6f))
				.WithWindow(ExampleUtils.ScreenRect)
				.AlignMiddleCenter(edges)
				.To3DXY();

			foreach (var point in edges)
			{
				var cell = Instantiate(edgeCell);

				cell.transform.parent = transform;
				cell.transform.localScale = Vector3.one;
				cell.transform.localRotation = Quaternion.identity;
				cell.transform.localPosition = edgeMap[point] + Vector3.back;

				cell.SetAngle(-120*point.I);

				cell.HighlightOn = false;
				cell.Color = ExampleUtils.Colors[3];

				edges[point] = cell;
			}

			vertices = faces.MakeVertexGrid<SpriteCell>() as FlatTriGrid<SpriteCell>;

			vertexMap = new FlatTriMap(vertexCell.Dimensions)
				.WithWindow(ExampleUtils.ScreenRect)
				.AlignMiddleCenter(vertices)
				.To3DXY();

			foreach (var point in vertices)
			{
				var cell = Instantiate(vertexCell);

				cell.transform.parent = transform;
				cell.transform.localScale = Vector3.one - 2*Vector3.forward;
				cell.transform.localRotation = Quaternion.identity;
				cell.transform.localPosition = vertexMap[point] + 2*Vector3.back;

				cell.SetAngle(180*point.I);

				cell.HighlightOn = false;
				cell.Color = ExampleUtils.Colors[2];

				vertices[point] = cell;
			}
		}

		public void Update()
		{
			if (Input.GetKeyDown(KeyCode.UpArrow))
			{
				selectionMode++;
				if (selectionMode >= 3)
				{
					selectionMode = 0;
				}
			}

			if (Input.GetKeyDown(KeyCode.DownArrow))
			{
				selectionMode--;
				if (selectionMode < 0)
				{
					selectionMode = 2;
				}
			}

			if (Input.GetMouseButtonDown(0))
			{
				var mousePosition = Input.mousePosition;

				var worldPosition = GridBuilderUtils.ScreenToWorld(mousePosition);

				switch (selectionMode)
				{
					case 0:
						ClickFace(worldPosition);
						break;
					case 1:
						ClickEdge(worldPosition);
						break;
					case 2:
						ClickVertex(worldPosition);
						break;
				}
			}

			if (Input.GetMouseButtonDown(1))
			{
				var mousePosition = Input.mousePosition;

				var worldPosition = GridBuilderUtils.ScreenToWorld(mousePosition);

				ClickAll(worldPosition);
			}
		}

		private void ClickAll(Vector3 worldPosition)
		{
			var gridPoint = faceMap[worldPosition];

			if (faces.Contains(gridPoint))
			{
				var cell = faces[gridPoint];
				cell.HighlightOn = !cell.HighlightOn;

				cell.Color = cell.HighlightOn ? ExampleUtils.Colors[4] : ExampleUtils.Colors[0];

				var faceEdges = gridPoint.GetEdges();

				foreach (var point in faceEdges)
				{
					if (edges.Contains(point))
					{
						edges[point].Color = Color.black;
					}
				}

				var faveVertices = gridPoint.GetVertices();

				foreach (var point in faveVertices)
				{
					if (vertices.Contains(point))
					{
						vertices[point].Color = Color.black;
					}
				}
			}
		}

		private void ClickVertex(Vector3 worldPosition)
		{
			var gridPoint = vertexMap[worldPosition];
			if (vertices.Contains(gridPoint))
			{
				var cell = vertices[gridPoint];
				cell.HighlightOn = !cell.HighlightOn;
				cell.Color = cell.HighlightOn ? ExampleUtils.Colors[6] : ExampleUtils.Colors[2];
			}
		}

		private void ClickEdge(Vector3 worldPosition)
		{
			var gridPoint = edgeMap[worldPosition];

			if (edges.Contains(gridPoint))
			{
				var cell = edges[gridPoint];
				cell.HighlightOn = !cell.HighlightOn;
				cell.Color = cell.HighlightOn ? ExampleUtils.Colors[7] : ExampleUtils.Colors[3];
			}
		}

		private void ClickFace(Vector3 worldPosition)
		{
			var gridPoint = faceMap[worldPosition];

			if (faces.Contains(gridPoint))
			{
				var cell = faces[gridPoint];
				cell.HighlightOn = !cell.HighlightOn;
				cell.Color = cell.HighlightOn ? ExampleUtils.Colors[4] : ExampleUtils.Colors[0];
			}
		}
	}
}