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

public class UIWrangler : MonoBehaviour
{
	// Helper for accessing the global object via script.
	public static UIWrangler ui;

	public DialogueBox dialogueBox;
	public CinematicBars cinematicBars;
	public GameObject worldText;
	public new Camera camera;
	public EventSystem eventSystem;
	public UIInventorySlot activeItemIcon;
	public Image fadeToBlack;
	public UIScreen hud;
	public UIScreen inGameMenu;
	public UIInventorySlot[] inventorySlots;

	public static float deltaTime;
	public static PlayerControl target;
	public static Item selectedItem;

	static bool showingMenu = false;
	static GameObject lastSelected;
	static Item _selectedItem;
	static Vector3 oldMouse = Vector3.zero;

	public bool gamePaused {
		get {
			foreach (UIScreen s in screens)
				if (s.pausesGame)
					return true;
			return false;
		}
	}

	public List<UIScreen> screens = new List<UIScreen>();

	void Awake() {
		ui = this;
		fadeToBlack.gameObject.SetActive(true);
	}

	public static void Select(GameObject obj) {
		lastSelected = obj;
		ui.eventSystem.SetSelectedGameObject(obj);
	}

	public void QuitGame() {
#if UNITY_EDITOR
		UnityEditor.EditorApplication.isPlaying = false;
#else
		Application.Quit();
#endif
	}

	void Update() {
		// Unity's unscaled time is bugged if we switched away or something.
		deltaTime = Time.unscaledDeltaTime;
		if (deltaTime > Time.maximumDeltaTime)
			deltaTime = 1.0f/60;

		// Hide the mouse. (not in the editor though)
		if (inGameMenu.shown) {
			if (Input.mousePosition != oldMouse)
				Cursor.visible = true;
		} else {
			if (!Application.isEditor)
				Cursor.visible = false;
		}
		oldMouse = Input.mousePosition;

		// Disable mouse when no cursor active.
		foreach (UIScreen screen in screens) {
			GraphicRaycaster rc = screen.GetComponent<GraphicRaycaster>();
			if (rc)
				rc.enabled = Cursor.visible;
		}

		// Squish the camera when using thin screens.
		// (assumes our standard 320x240 UI design)
		float screenAspect = (float)Screen.width / (float)Screen.height;
		if (screenAspect < 1.333333f)
			camera.orthographicSize = 0.5f * 320 / screenAspect;
		else
			camera.orthographicSize = 0.5f * 240;

		// Update the inventory whenever we switch to it.
		if (inGameMenu.shown && !showingMenu)
			UpdateTarget();
		showingMenu = inGameMenu.shown;

		if (selectedItem != _selectedItem) {
			_selectedItem = selectedItem;
			UpdateItemIcon();
		}

		// Make sure something's always selected.
		if (eventSystem.currentSelectedGameObject) {
			lastSelected = eventSystem.currentSelectedGameObject;
		} else {
			Select(lastSelected);
		}
	}

	void UpdateItemIcon() {
		activeItemIcon.Set(selectedItem, 1);
	}

	void UpdateTarget() {
		InventoryDatabase db = Game.game.inventoryDatabase;
		Entity entity = target ? target.GetComponent<Entity>() : null;

		GameObject select = null;
		int dest = 0;
		if (entity) {
			foreach (Item item in db.items) {
				if (item.shownInInventory && entity.inventory.TryGetValue(item.name, out Inventory info)) {
					UIInventorySlot slot = inventorySlots[dest++];
					slot.Set(item, info.count);

					if (!select && slot.isSlotSelectable)
						select = slot.gameObject;
				}
			}

		}

		// Clear out the rest.
		while (dest < inventorySlots.Length) {
			inventorySlots[dest++].Set(null, 0);
		}

		if (select)
			Select(select);
	}
}
