using System;
using System.Collections.Generic;
using KernelPanic.Data;
using KernelPanic.Meta;
using UnityEngine;
using UnityEngine.TextCore.Text;
using UnityEngine.UIElements;
namespace KernelPanic.UI
{
///
/// Renders banner selection and pull controls for the gacha screen.
///
[Serializable]
public sealed class GachaScreenController
{
private const string SelectedClassName = "selected";
private readonly List _bannerRows = new();
private readonly string[] _bannerIds =
{
GachaService.BeginnerBannerId,
GachaService.StandardBannerId,
GachaService.LimitedBannerId
};
private VisualElement _bannerList;
private VisualElement _bannerDetail;
private DistroDatabase _distroDatabase;
private FontAsset _monospaceFont;
private GachaService _gachaService;
private PlayerCollection _playerCollection;
private EntropyWallet _wallet;
private Func, PullResolutionResult> _resolvePulledDistros;
private Action _onChanged;
private Action _requestRootCreditExchange;
private Action _requestPullCutscene;
private int _selectedBannerIndex;
private int _pendingPullCount;
private int _pendingMissingTokens;
private bool _hasOpened;
private string _resultBannerId;
private string _resultText;
private readonly List _resultRewardLines = new();
private readonly List _resultRewardStars = new();
private bool _resultRevealed;
public void Bind(VisualElement root, DistroDatabase database, FontAsset artFont, GachaService service, PlayerCollection collection, EntropyWallet entropyWallet, Func, PullResolutionResult> pullResolver, Action changedCallback, Action rootCreditExchangeCallback, Action pullCutsceneCallback)
{
_distroDatabase = database;
_monospaceFont = artFont;
_gachaService = service;
_playerCollection = collection;
_wallet = entropyWallet;
_resolvePulledDistros = pullResolver;
_onChanged = changedCallback;
_requestRootCreditExchange = rootCreditExchangeCallback;
_requestPullCutscene = pullCutsceneCallback;
_bannerList = root.Q("GachaBannerList");
_bannerDetail = root.Q("GachaBannerDetail");
}
public void Open()
{
if (!_hasOpened)
{
_selectedBannerIndex = 0;
_hasOpened = true;
}
Refresh();
}
public void Refresh()
{
if (_bannerList == null || _bannerDetail == null || _gachaService == null)
{
return;
}
_bannerRows.Clear();
_bannerList.Clear();
for (int i = 0; i < _bannerIds.Length; i++)
{
int index = i;
VisualElement row = BuildBannerRow(_bannerIds[i]);
row.RegisterCallback(_ => SelectBanner(index));
_bannerList.Add(row);
_bannerRows.Add(row);
}
_selectedBannerIndex = Mathf.Clamp(_selectedBannerIndex, 0, _bannerRows.Count - 1);
ApplySelectedBanner();
}
public void HandleKeyDown(KeyDownEvent evt)
{
// Pulls are deliberately click-only to avoid accidental currency spend.
}
private VisualElement BuildBannerRow(string bannerId)
{
VisualElement row = new();
row.AddToClassList("gacha-banner-row");
row.Add(new Label(">") { name = $"GachaBannerCursor_{bannerId}" });
row.ElementAt(0).AddToClassList("command-cursor");
row.Add(new Label(GetBannerTitle(bannerId)) { name = $"GachaBannerName_{bannerId}" });
row.ElementAt(1).AddToClassList("command-text");
row.Add(new Label(GetBannerStatus(bannerId)) { name = $"GachaBannerStatus_{bannerId}" });
row.ElementAt(2).AddToClassList("command-description");
return row;
}
private void SelectBanner(int index)
{
if (_bannerRows.Count == 0)
{
return;
}
_selectedBannerIndex = (index + _bannerRows.Count) % _bannerRows.Count;
ApplySelectedBanner();
}
private void ApplySelectedBanner()
{
for (int i = 0; i < _bannerRows.Count; i++)
{
bool selected = i == _selectedBannerIndex;
_bannerRows[i].EnableInClassList(SelectedClassName, selected);
_bannerRows[i].Q