﻿using UnityEngine;
using Gamelogic.AbstractStrategy.Grids;
using Gamelogic.Diagnostics;
using Gamelogic.Grids;

namespace Gamelogic.AbstractStrategy.Examples
{
	public class YourOwnPieces : GLMonoBehaviour
	{
		private GridGameManager manager;
		private Player<RectPoint, GridGamePieceSettings> bluePlayer, bluePlayer2, blueDimondPlayer, blueFlatHexPlayer, blueFlatTriPlayer, blueHexDecisionPlayer, oPlayer;
		private Player<RectPoint, GridGamePieceSettings> redPlayer, redPlayer2, redDimondPlayer, redFlatHexPlayer, redFlatTriPlayer, redHexDecisionPlayer, xPlayer;
		private IPieceProperties selectedPiece;

		public void Start()
		{
			InitializeGameManager();
			InitializePlayers();

			manager.StartGame();
		}

		public void Update()
		{
			if (Input.GetKeyDown(KeyCode.Space))
			{
				manager.StartGame(); //Reset Game
			}
		}

		public void OnClick(RectPoint point)
		{
			var currentPlayer = manager.CurrentPlayer;

			if (currentPlayer is GridHumanPlayer &&
				manager.MoveManager.Done)
			{
				// If a block is occupied, try to select
				var state = manager.State;
				var piece = state.TestPosition(point);

				if (piece != null)
				{
					if (piece.playerID == currentPlayer.PlayerID)
					{
						SelectPiece(piece);
					}
				}
				else if (selectedPiece != null)
				{
					// Try to commit move
					var selectedPos = state.FindPiece(selectedPiece);
					var move = state.CreateMovePieceMove(selectedPiece, selectedPos, point);

					if (manager.CommitMove(move))
					{
						DeselectPiece();
					}
				}
			}
		}

		private void InitializeGameManager()
		{
			manager = GetComponent<GridGameManager>();

			if (manager == null)
			{
				GLDebug.LogError("You must have a GridGameManager attached to the same game object as this component");
			}
		}

		private void InitializePlayers()
		{
			bluePlayer = new GridHumanPlayer("blue");
			bluePlayer2 = new GridHumanPlayer("blue2");
			blueDimondPlayer = new GridHumanPlayer("blueDimond");
			blueFlatHexPlayer = new GridHumanPlayer("blueFlatHex");
			blueFlatTriPlayer = new GridHumanPlayer("blueFlatTri");
			blueHexDecisionPlayer = new GridHumanPlayer("blueHexDecision");
			oPlayer = new GridHumanPlayer("O");

			redPlayer = new GridHumanPlayer("red");
			redPlayer2 = new GridHumanPlayer("red2");
			redDimondPlayer = new GridHumanPlayer("redDimond");
			redFlatHexPlayer = new GridHumanPlayer("redFlatHex");
			redFlatTriPlayer = new GridHumanPlayer("redFlatTri");
			redHexDecisionPlayer = new GridHumanPlayer("redHexDecision");
			xPlayer = new GridHumanPlayer("X");
			
			manager.RegisterPlayer(bluePlayer);
			manager.RegisterPlayer(bluePlayer2);
			manager.RegisterPlayer(blueDimondPlayer);
			manager.RegisterPlayer(blueFlatHexPlayer);
			manager.RegisterPlayer(blueFlatTriPlayer);
			manager.RegisterPlayer(blueHexDecisionPlayer);
			manager.RegisterPlayer(oPlayer);

			manager.RegisterPlayer(redPlayer);
			manager.RegisterPlayer(redPlayer2);
			manager.RegisterPlayer(redDimondPlayer);
			manager.RegisterPlayer(redFlatHexPlayer);
			manager.RegisterPlayer(redFlatTriPlayer);
			manager.RegisterPlayer(redHexDecisionPlayer);
			manager.RegisterPlayer(xPlayer);
		}

		private void DeselectPiece()
		{
			if (selectedPiece != null)
			{
				UpdateVisualSelectionState(false);
			}

			selectedPiece = null;
		}

		private void SelectPiece(IPieceProperties piece)
		{
			if (selectedPiece != null)
			{
				DeselectPiece();
			}

			selectedPiece = piece;

			UpdateVisualSelectionState(true);
		}

		private void UpdateVisualSelectionState(bool selectionOn)
		{
			var visualPiece = manager.GetExistingVisualPiece(selectedPiece);
			var sprite = visualPiece.GetComponentInChildren<SpriteRenderer>();

			if (sprite != null)
			{
				var colour = sprite.color;
				colour.a = selectionOn ? 0.8f : 1.0f;
				sprite.color = colour;
			}
		}
	}
};