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 Action onChanged;
private Action requestRootCreditExchange;
private int selectedBannerIndex;
private int pendingPullCount;
private int pendingMissingTokens;
private bool hasOpened;
private string resultBannerId;
private string resultText;
public void Bind(VisualElement root, DistroDatabase database, FontAsset artFont, GachaService service, PlayerCollection collection, EntropyWallet entropyWallet, Action changedCallback, Action rootCreditExchangeCallback)
{
distroDatabase = database;
monospaceFont = artFont;
gachaService = service;
playerCollection = collection;
wallet = entropyWallet;
onChanged = changedCallback;
requestRootCreditExchange = rootCreditExchangeCallback;
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