using System;
using System.Collections.Generic;
using Convai.Scripts;
using Convai.Scripts.Utils;
using TMPro;
using UnityEngine;
///
/// This class is used to control the appearance settings of the UI.
/// It requires a UIMicrophoneSettings, AudioSource, and MicrophoneInputChecker components to work.
///
public class UIAppearanceSettings : MonoBehaviour
{
[Header("Settings Panel Animation Values")]
[SerializeField]
[Tooltip("Duration of the appearance preview animation.")]
private float _appearancePreviewDuration = 1f;
[Header("References")] [Tooltip("Dropdown for selecting the appearance.")] [SerializeField]
private TMP_Dropdown _appearanceDropdown;
///
/// FadeCanvas for handling appearance transitions.
///
[SerializeField] private FadeCanvas _fadeCanvas;
///
/// Duration for fade in animation.
///
private readonly float _fadeInDuration = 0.3f;
///
/// Duration for fade out animation.
///
private readonly float _fadeOutDuration = 0.45f;
///
/// Currently active appearance.
///
private IChatUI _currentActiveAppearance;
///
/// Reference to the UISettingsPanel for coordinating with appearance changes.
///
private UISettingsPanel _uiSettingsPanel;
///
/// Action notifying the change of appearance.
///
public Action OnAppearanceChanged;
///
/// Initialization when the script is loaded.
///
private void Awake()
{
// Clear existing options in the dropdown.
_appearanceDropdown.ClearOptions();
// Get reference to the UISettingsPanel.
_uiSettingsPanel = GetComponent();
}
private void Start()
{
InitializeAppearanceDropdown();
}
///
/// Subscribe to events when this component is enabled.
///
private void OnEnable()
{
// Subscribe to the event when saved data is loaded.
UISaveLoadSystem.Instance.OnLoad += UISaveLoadSystem_OnLoad;
// Subscribe to the event when data is saved.
UISaveLoadSystem.Instance.OnSave += UISaveLoadSystem_OnSave;
ConvaiNPCManager.Instance.OnActiveNPCChanged += ConvaiNPCManager_OnActiveNPCChanged;
}
///
/// Unsubscribe from events when this component is disabled.
///
private void OnDisable()
{
// Unsubscribe from the event when saved data is loaded.
UISaveLoadSystem.Instance.OnLoad -= UISaveLoadSystem_OnLoad;
// Unsubscribe from the event when data is saved.
UISaveLoadSystem.Instance.OnSave -= UISaveLoadSystem_OnSave;
ConvaiNPCManager.Instance.OnActiveNPCChanged -= ConvaiNPCManager_OnActiveNPCChanged;
}
///
/// Initialize the appearance dropdown with available options.
///
private void InitializeAppearanceDropdown()
{
List appearanceNames = new();
foreach (KeyValuePair appearance in ConvaiChatUIHandler.Instance
.GetUIAppearances) appearanceNames.Add(appearance.Key.ToString());
_appearanceDropdown.AddOptions(appearanceNames);
int value = (int)UISaveLoadSystem.Instance.UIType;
_appearanceDropdown.value = value;
// Subscribe to the appearance change event.
_appearanceDropdown.onValueChanged.AddListener(ChangeAppearance);
}
///
/// Event handler for when the active NPC changes.
///
private void ConvaiNPCManager_OnActiveNPCChanged(ConvaiNPC newActiveNPC)
{
if (newActiveNPC != null)
_fadeCanvas.StartFadeIn(_currentActiveAppearance.GetCanvasGroup(), _fadeInDuration);
else _fadeCanvas.StartFadeOut(_currentActiveAppearance.GetCanvasGroup(), _fadeOutDuration);
}
///
/// Event handler when saved data is loaded.
///
private void UISaveLoadSystem_OnLoad()
{
// Set the current active appearance based on loaded data.
_currentActiveAppearance = ConvaiChatUIHandler.Instance.GetCurrentUI();
}
///
/// Event handler when data is saved.
///
private void UISaveLoadSystem_OnSave()
{
}
///
/// Event handler for appearance change.
///
private void ChangeAppearance(int selectedOptionNumber)
{
// Initiate Settings Panel transition.
_uiSettingsPanel.FadeOutFadeinWithGap(_fadeInDuration, _fadeOutDuration, _appearancePreviewDuration);
// Deactivate the current appearance.
_currentActiveAppearance.DeactivateUI();
ConvaiChatUIHandler.UIType newUIType = (ConvaiChatUIHandler.UIType)_appearanceDropdown.value;
ConvaiChatUIHandler.Instance.SetUIType(newUIType);
_currentActiveAppearance = ConvaiChatUIHandler.Instance.GetChatUIByUIType(newUIType);
// Update the current active appearance reference.
_currentActiveAppearance.ActivateUI();
// Initiate appearance transition.
FadeInFadeOutWithGap();
OnAppearanceChanged?.Invoke();
}
///
/// Fade out the currently active appearance.
///
public void FadeOutCurrentAppearance()
{
_fadeCanvas.StartFadeOut(_currentActiveAppearance.GetCanvasGroup(), _fadeOutDuration);
}
///
/// Fade in the currently active appearance.
///
public void FadeInCurrentAppearance()
{
_fadeCanvas.StartFadeIn(_currentActiveAppearance.GetCanvasGroup(), _fadeInDuration);
}
///
/// Perform a fade-in, fade-out transition with a gap in between.
///
private void FadeInFadeOutWithGap()
{
_fadeCanvas.StartFadeInFadeOutWithGap(_currentActiveAppearance.GetCanvasGroup(), _fadeInDuration,
_fadeOutDuration, _appearancePreviewDuration);
}
///
/// Get the currently active appearance.
///
public IChatUI GetCurrentActiveAppearance()
{
return _currentActiveAppearance;
}
}