using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using UnityEngine.EventSystems;

/// <summary>
/// Define player position, planets, enemy ships and other things in in star system
/// </summary>
public class StarSystemState : SpaceStateController
{
//	static StarSystemState instance = null;
	static StarMap.StarSystem currentSystem = null;
	
	[SerializeField] Camera playerCamera = null; // Set from editor
	[SerializeField] GameObject shipMarker = null; // Set from editor

	List<PlanetarController> spaceObjects = new List<PlanetarController>();
	
	public override void OnStateShow (bool fromBigger)
	{
		CameraController.SetPosition (Vector3.zero, false);
		if (currentSystem != StarMap.Stars [Player.info.StarId])
		{
			currentSystem = StarMap.Stars [Player.info.StarId];
			Regenerate (currentSystem);
		}
		float distance = 0;
		if (fromBigger)
		{
			distance = maxCameraDistance + 5f;
		}
		CameraController.SetNeedDistance (8f);
		CameraController.SetBorders (distance, minCameraDistance, maxCameraDistance, cameraMinYAngle, cameraMaxYAngle);
		MoveShipToSpaceObject (Player.info.currentObjectId, false);
	}

	void Regenerate(StarMap.StarSystem system)
	{
		if (system == null)
		{
			return;
		}
		// clear old system
		foreach (var obj in spaceObjects)
		{
			Destroy(obj.gameObject);
		}
		spaceObjects.Clear();
		foreach(var obj in system.objects)
		{
			spaceObjects.Add(PlanetarController.Generate(transform, obj));
		//	GalaxyMap.StarSystem
		}
	}

	void Start ()
	{
	}
	
	void Update ()
	{
		TracePlayerTouch ();
	}

	void SelectSpaceObject(int id)
	{
		MoveShipToSpaceObject (id);
	}

	// make ship marker
	const float shipSpeed = 12f; // Unit per second
	int timerId = -1;
	void MoveShipToSpaceObject(int id = 0, bool withAnimation = true)
	{
		if (shipMarker != null && spaceObjects != null && spaceObjects.Count > 0)
		{
			Vector3 startPoint = shipMarker.transform.position;
			Vector3 needPoint = spaceObjects[id].planetarMesh.transform.position + new Vector3(0, spaceObjects[id].planetarMesh.radius * 1.2f);
			Player.info.currentObjectId = id;
			Timer.Stop(timerId);
			if (withAnimation)
			{
				CameraController.SetPosition(spaceObjects[id].planetarMesh.transform.position);
				// TODO make special class for ship animation
				timerId = Timer.Add((startPoint - needPoint).magnitude / shipSpeed, (anim) =>
				{
					shipMarker.transform.position = Vector3.Lerp(startPoint, needPoint, anim);
				},
				() =>
				{
					shipMarker.transform.position = needPoint;
					timerId = -1;
				});
			}
			else
			{
				CameraController.SetPosition(spaceObjects[id].planetarMesh.transform.position, false);
				shipMarker.transform.position = needPoint;
			}
			StarSystemUI.ShowScanButton(StarMap.Stars[Player.info.StarId].objects[Player.info.currentObjectId].points != null);
		}
	}
	
	void TracePlayerTouch()
	{
		if (playerCamera == null)
		{
			Debug.LogError("StarMapController " + name + " does not set player camera");
			return;
		}
		if (!EventSystem.current.IsPointerOverGameObject ())
		{
			if (Input.GetMouseButtonUp (0))
			{
				RaycastHit hitInfo;
				if (Physics.Raycast (playerCamera.ScreenPointToRay (Input.mousePosition), out hitInfo, 50f))
				{
					if (hitInfo.collider != null)
					{
						for(int i = 0; i < spaceObjects.Count; i++)
						{
							// TODO - change collider to same object
							if (hitInfo.collider.transform.parent.gameObject == spaceObjects[i].gameObject)
							{
								SelectSpaceObject (i);
								break;
							}
						}
					}
				}
			}
		}
	}
}
