using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Sirenix.OdinInspector;
using KairoEngine.Core;
using KairoEngine.UI;
namespace KairoEngine.UI.ActivityMessages
{
//* This is the simplest possible implementation of this controller
// Todo: Add icons to activity messages
// Todo: Add autohide prorperty to messages
// Todo: Cleanup list of activeMessages that have been destroyed
///
/// Controller for showing activity messages to the player.
/// Use the ActivityMessageEvents.Send() to send a message to this controller.
///
[HideMonoScript]
public class ActivityMessageController : MonoBehaviour , IUiSystemElement
{
[BoxGroup("Settings")] public string elementTitle = "ActivityMessages";
[BoxGroup("Settings")] public Canvas canvas;
[BoxGroup("Settings")] public bool startVisible = false;
[BoxGroup("Settings")] public int defaultGroupIndex = 0;
[BoxGroup("Settings")] public int defaultPrefabIndex = 0;
[BoxGroup("Settings")] public bool removeOldMessages = true;
[PropertySpace(4,4)]
public List groups = new List();
[PropertySpace(4,4), Tooltip("The GameObject prefab for the ActivityMessage.")]
public List prefabs;
[ReadOnly, PropertySpace(4,0)] public List activeMessages;
private bool isVisible = true;
private void Start()
{
if(startVisible) UiManager.ShowElement(this);
else UiManager.HideElement(this);
}
private void OnEnable()
{
UiManager.RegisterElement(elementTitle, this, this.transform, isVisible);
ActivityMessageEvents.OnActivityMessage += NewActivityMessage;
ActivityMessageEvents.OnTimedActivityMessage += NewTimedActivityMessage;
ActivityMessageEvents.OnStickyActivityMessage += NewStickyActivityMessage;
ActivityMessageEvents.OnFullMessage += NewFullMessage;
ActivityMessageEvents.OnUpdateActivityMessage += UpdateActivityMessage;
ActivityMessageEvents.OnRemoveActivityMessage += DestroyActivityMessage;
}
private void OnDisable()
{
UiManager.UnregisterElement(this);
ActivityMessageEvents.OnActivityMessage -= NewActivityMessage;
ActivityMessageEvents.OnTimedActivityMessage -= NewTimedActivityMessage;
ActivityMessageEvents.OnStickyActivityMessage -= NewStickyActivityMessage;
ActivityMessageEvents.OnFullMessage -= NewFullMessage;
ActivityMessageEvents.OnUpdateActivityMessage -= UpdateActivityMessage;
ActivityMessageEvents.OnRemoveActivityMessage -= DestroyActivityMessage;
}
public void Hide()
{
isVisible = false;
canvas.gameObject.SetActive(false);
}
public void Show()
{
isVisible = true;
canvas.gameObject.SetActive(true);
}
public bool IsVisible() => isVisible;
private void NewActivityMessage(string msg)
{
ActivityMessage message = new ActivityMessage(msg);
CreateMessage(message, defaultGroupIndex, defaultPrefabIndex).Setup(this, message);
}
private void NewTimedActivityMessage(string msg, float time)
{
ActivityMessage message = new ActivityMessage(msg, "", "", "", null, time, false, true, null, "", "");
CreateMessage(message, defaultGroupIndex, defaultPrefabIndex).Setup(this, message);
}
private void NewStickyActivityMessage(string msg, bool sticky)
{
ActivityMessage message = new ActivityMessage(msg, "", "", "", null, 0f, true, true, null, "", "");
CreateMessage(message, defaultGroupIndex, defaultPrefabIndex).Setup(this, message);
}
private void NewFullMessage(string text, string id, string group, string prefab, Sprite icon, float time, bool sticky, bool hideOnClick,
Action action, string tooltipHeader, string tooltipBody, string tooltipType)
{
ActivityMessage message = new ActivityMessage(text, id, group, prefab, icon, time, sticky, hideOnClick, action, tooltipHeader, tooltipBody, tooltipType);
int groupIndex = GetGroupIndexByTitle(group);
int prefabIndex = GetPrefabIndexByTitle(prefab);
CreateMessage(message, groupIndex, prefabIndex).Setup(this, message);
}
private void UpdateActivityMessage(string id, string newText, Sprite newSprite, float time, bool sticky, bool hideOnClick,
Action action, string tooltipHeader, string tooltipBody, string tooltipType)
{
for (int i = 0; i < activeMessages.Count; i++)
{
if(activeMessages[i].message.text == id || activeMessages[i].message.id == id)
{
activeMessages[i].message.text = newText;
if(newSprite != null) activeMessages[i].message.icon = newSprite;
activeMessages[i].message.time = time;
activeMessages[i].message.sticky = sticky;
activeMessages[i].message.hideOnClick = hideOnClick;
activeMessages[i].message.tooltipHeader = tooltipHeader;
activeMessages[i].message.tooltipBody = tooltipBody;
activeMessages[i].message.tooltipType = tooltipType;
if(action != null) activeMessages[i].message.action = action;
activeMessages[i].Setup(this, activeMessages[i].message);
return;
}
}
}
private void DestroyActivityMessage(string text)
{
for (int i = 0; i < activeMessages.Count; i++)
{
if(activeMessages[i].message.text == text || activeMessages[i].message.id == text)
{
activeMessages[i].Remove();
}
}
}
public void RemoveActivityMessageFromList(ActivityMessage message)
{
for (int i = 0; i < activeMessages.Count; i++)
{
if(activeMessages[i].message.text == message.text || activeMessages[i].message.id == message.id)
{
activeMessages.RemoveAt(i);
}
}
}
private ActivityMessageUi CreateMessage(ActivityMessage message, int groupIndex, int prefabIndex)
{
groups[groupIndex].messages.Add(message);
GameObject obj = Instantiate(prefabs[prefabIndex].prefab, groups[groupIndex].container);
ActivityMessageUi msgUi = obj.GetComponent();
activeMessages.Add(msgUi);
if(removeOldMessages) RemoveOldMessages(groupIndex);
return msgUi;
}
public bool GroupExits(string title)
{
for (int i = 0; i < groups.Count; i++)
{
if(groups[i].title == title) return true;
}
return false;
}
public int GetGroupIndexByTitle(string title)
{
for (int i = 0; i < groups.Count; i++)
{
if(groups[i].title == title) return i;
}
return defaultGroupIndex;
}
public bool PrefabExits(string title)
{
for (int i = 0; i < prefabs.Count; i++)
{
if(prefabs[i].title == title) return true;
}
return false;
}
public int GetPrefabIndexByTitle(string title)
{
for (int i = 0; i < prefabs.Count; i++)
{
if(prefabs[i].title == title) return i;
}
return defaultPrefabIndex;
}
public void RemoveOldMessages(int groupIndex)
{
if(groups[groupIndex].container.childCount > groups[groupIndex].maxVisibleMessages)
{
int n = groups[groupIndex].container.childCount - groups[groupIndex].maxVisibleMessages;
for (int i = 0; i < n; i++)
{
Destroy(groups[groupIndex].container.GetChild(0).gameObject);
}
}
if(groups[groupIndex].messages.Count > groups[groupIndex].maxHistoryMessages)
{
int n = groups[groupIndex].messages.Count - groups[groupIndex].maxHistoryMessages;
groups[groupIndex].messages.RemoveRange(0, n);
}
}
}
}