﻿using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class GameManager : MonoBehaviour
{
	#region Singleton
	private static GameManager instance;

	private void Awake()
	{
		if (instance != null)
		{
			Destroy(this);
			return;
		}

		instance = this;
	}
	#endregion

	[SerializeField] private GameObject turretPrefab;
	[SerializeField] private GameObject turretNopePrefab;
	[SerializeField] private GameObject wallPrefab;
	[SerializeField] private GameObject wallNopePrefab;
	[SerializeField] private GameObject reapEffectPrefab;
	[SerializeField] private GameObject landingPadPrefab;
	public static GameObject TurretPrefab  { get{ return instance.turretPrefab; }}
	public static GameObject TurretNopePrefab { get{return instance.turretNopePrefab; }}
	public static GameObject WallPrefab { get{return instance.wallPrefab; }}
	public static GameObject WallNopePrefab { get{ return instance.wallNopePrefab; }}
	public static GameObject ReapEffectPrefab { get { return instance.reapEffectPrefab; } }

	[SerializeField] private LayerMask groundLayers;
	[SerializeField] private LayerMask unitsLayers;
	[SerializeField] private LayerMask objectsLayers;
	[SerializeField] private LayerMask attackableLayers;
	[SerializeField] private LayerMask uiLayers;
	public static LayerMask GroundLayers { get { return instance.groundLayers; } }
	public static LayerMask UnitsLayers { get { return instance.unitsLayers; } }
	public static LayerMask ObjectsLayers { get { return instance.objectsLayers; } }
	public static LayerMask AttackableLayers { get { return instance.attackableLayers; } }
	public static LayerMask UILayers { get { return instance.uiLayers; } }

	[SerializeField] float harvest = 100;
	[SerializeField] float maxHarvest = 10000;
	public static float Harvest { get { return instance.harvest; } }
	public static float MaxHarvest { get { return instance.maxHarvest; } }

	private bool isQuitting = false;
	private bool isRetreating = false;
	public static bool IsQuitting { get { return instance.isQuitting; } set { instance.isQuitting = true; } }
	public static bool IsRetreating { get { return instance.isRetreating; } }

	private PlacementManager placementManager;
	private InteractionManager interactionManager;
	private LandingPad landingPad;
	public static PlacementManager PlacementManager { get { return instance.placementManager; } }
	public static InteractionManager InteractionManager { get { return instance.interactionManager; } }
	public static LandingPad LandingPad { get { return instance.landingPad; } }

	public static Ship Ship { get; set; }
	public static bool Interactable { get; set; }
	public static PromptManager PromptManager { get; set; }

	public static bool WeWin { get; private set; }

	private void Start()
	{
		if (placementManager == null)
		{
			placementManager = gameObject.AddComponent<PlacementManager>();
		}

		if (interactionManager == null)
		{
			interactionManager = gameObject.AddComponent<InteractionManager>();
			interactionManager.interactableMask = objectsLayers;
			interactionManager.currentInteraction = InteractionTypes.Place;
		}

		GameObject landingPadGameObject = Instantiate(landingPadPrefab, Vector3.zero, Quaternion.identity);
		landingPad = landingPadGameObject.GetComponent<LandingPad>();
	}

	public static void Lose()
	{
		PromptManager.Lose();
	}

	public static void Win()
	{
		WeWin = true;
		PromptManager.Win();
	}

	public static void Quit()
	{
#if UNITY_EDITOR
		UnityEditor.EditorApplication.isPlaying = false;
#elif UNITY_WEBGL
        Application.OpenURL(Application.absoluteURL);
#else
        Application.Quit();
#endif
	}

	public static void StopRetreat()
	{
		instance.isRetreating = false;
	}

	public  static void Retreat()
	{
		instance.isRetreating = true;
	}

	private void OnApplicationQuit()
	{
		isQuitting = true;
	}

	private void OnLevelWasLoaded(int level)
	{
		isQuitting = false;
		WeWin = false;
	}

	public static void Reap(float harvest)
	{
		instance.harvest += harvest;

		if (instance.harvest > instance.maxHarvest)
		{
			instance.harvest = instance.maxHarvest;
		}
	}

	public static void Sow(float harvest)
	{
		instance.harvest -= harvest;

		if (instance.harvest < 0)
		{
			throw new System.Exception("Sow(" + harvest + ") dropping harvest below zero");
		}
	}
}
