using System; using System.Collections.Generic; using UnityEngine; namespace AibisDream.UI.Terminal { public enum TerminalPage { None, Start, Setting, Chapter, Record } public enum TerminalOpenSource { None, MainMenu, InGame } public class TerminalPanel : MonoBehaviour, IUIPanel { [SerializeField] private TerminalHeaderView header; [SerializeField] private TerminalStartPanel startPage; [SerializeField] private TerminalSettingPanel settingPage; [SerializeField] private TerminalChapterPanel chapterPage; [SerializeField] private TerminalRecordPanel recordPage; private readonly Stack _backStack = new(); private TerminalPage _currentPage = TerminalPage.None; private TerminalOpenSource _source = TerminalOpenSource.None; private bool _pausedByTerminal; public bool IsOpen => gameObject.activeSelf && _currentPage != TerminalPage.None; public bool IsCloseable => _source == TerminalOpenSource.InGame; public TerminalPage CurrentPage => _currentPage; public TerminalOpenSource Source => _source; public void Initialize(RectTransform searchRoot) { startPage ??= searchRoot.GetComponentInChildren(true); settingPage ??= searchRoot.GetComponentInChildren(true); chapterPage ??= searchRoot.GetComponentInChildren(true); recordPage ??= searchRoot.GetComponentInChildren(true); startPage?.SetOwner(this); settingPage?.SetOwner(this); chapterPage?.SetOwner(this); recordPage?.SetOwner(this); Close(); } public bool HasRequiredPages() { return startPage != null && settingPage != null && chapterPage != null && recordPage != null; } public void Show() { Open(TerminalPage.Start, TerminalOpenSource.MainMenu); } public void Hide() { Close(); } public void Open(TerminalPage page, TerminalOpenSource source) { if (!HasRequiredPages()) { return; } if (!IsOpen || _source != source) { _backStack.Clear(); } gameObject.SetActive(true); _source = source; PauseIfNeeded(page, source); SwitchTo(page, pushCurrent: false); } public void SwitchTo(TerminalPage page, bool pushCurrent = true) { if (page == TerminalPage.None || page == _currentPage) { return; } if (pushCurrent && _currentPage != TerminalPage.None) { _backStack.Push(_currentPage); } HidePage(_currentPage); _currentPage = page; ShowPage(_currentPage); } public void Back() { if (_source == TerminalOpenSource.InGame) { Close(); return; } if (_backStack.Count > 0) { var previous = _backStack.Pop(); HidePage(_currentPage); _currentPage = previous; ShowPage(_currentPage); return; } if (_currentPage != TerminalPage.Start) { SwitchTo(TerminalPage.Start, pushCurrent: false); } } public bool HandleEscape() { if (!IsOpen) { return false; } if (_currentPage == TerminalPage.Start) { return true; } Back(); return true; } public void CloseThen(Action action) { Close(); action?.Invoke(); } public void Close() { HideAllPages(); _backStack.Clear(); _currentPage = TerminalPage.None; _source = TerminalOpenSource.None; ContinueIfPaused(); gameObject.SetActive(false); } public void CloseToMainMenu() { Close(); GameManager.Instance.QuitGame(); } public void AppendDialogLine(LineInfo lineInfo) { recordPage?.AppendDialogLine(lineInfo); } public void ClearDialog() { recordPage?.ClearDialog(); } public void SetHeader(string title, string status = "") { header?.SetText(title, status); } private void PauseIfNeeded(TerminalPage page, TerminalOpenSource source) { if (source != TerminalOpenSource.InGame || page is not (TerminalPage.Setting or TerminalPage.Record)) { return; } if (!_pausedByTerminal) { GameManager.Instance.PauseGame(); _pausedByTerminal = true; } } private void ContinueIfPaused() { if (!_pausedByTerminal) { return; } GameManager.Instance.ContinueGame(); _pausedByTerminal = false; } private void ShowPage(TerminalPage page) { switch (page) { case TerminalPage.Start: startPage?.Show(); break; case TerminalPage.Setting: settingPage?.Show(); break; case TerminalPage.Chapter: chapterPage?.Show(); break; case TerminalPage.Record: recordPage?.Show(); break; } } private void HidePage(TerminalPage page) { switch (page) { case TerminalPage.Start: startPage?.Hide(); break; case TerminalPage.Setting: settingPage?.Hide(); break; case TerminalPage.Chapter: chapterPage?.Hide(); break; case TerminalPage.Record: recordPage?.Hide(); break; } } private void HideAllPages() { startPage?.Hide(); settingPage?.Hide(); chapterPage?.Hide(); recordPage?.Hide(); } } }