using Cthangover.Mods.Interface.Base.Lists;
using Cthangover.Core.UI.Theming;
using Godot;
using Cthangover.Mods.Interface.Theming;
namespace Cthangover.Mods.Skills
{
///
/// Grid card of one collected skill. Pure presentation: the panel binds a
/// through and toggles
/// selection through , while every colour comes
/// from so the same rarity reads identically on
/// the card, the study plate and the rarity filter tabs.
///
/// Clicking is intentionally not handled here: the panel subscribes to
/// GuiInput, so the card keeps a single responsibility and can be
/// hosted by any list without knowing its owner. Hover is handled inside
/// because it only repaints the card itself.
///
public partial class SkillCardBehaviour : ListItem
{
[Export] private Panel bg;
[Export] private Panel accent;
[Export] private PanelContainer art;
[Export] private TextureRect imgCard;
[Export] private Label txtName;
[Export] private Label txtGems;
[Export] private PanelContainer badgeBox;
[Export] private Label badgeLabel;
[Export] private HBoxContainer effectRow;
[Export] private Label effectValue;
[Export] private Label effectLabel;
private bool _selected;
private bool _hover;
/// Configures the card to accept mouse input for hover/selection feedback.
public override void _Ready()
{
MouseFilter = MouseFilterEnum.Stop;
MouseEntered += OnMouseEntered;
MouseExited += OnMouseExited;
}
///
/// Binds the skill definition to the card: artwork, translated name,
/// rarity gems (one diamond per tier), the type badge and the first
/// numeric effect as the card's short line. Skills without effects hide
/// the effect row instead of leaving an empty band; a skill without
/// artwork keeps the empty well, which is a valid authored state.
///
public override void Construct(SkillInfo skillInfo)
{
base.Construct(skillInfo);
ResolveNodes();
if (art != null)
art.AddThemeStyleboxOverride("panel", UiKit.Frame(UiTokens.RadiusSm, UiTokens.Well, UiTokens.Line));
if (skillInfo == null)
return;
if (imgCard != null)
imgCard.Texture = skillInfo.Sprite;
if (txtName != null)
{
txtName.Text = TranslationServer.Translate(skillInfo.Name);
txtName.AddThemeFontSizeOverride("font_size", UiTokens.FontBodySmall);
txtName.AddThemeColorOverride("font_color", UiTokens.InkBright);
}
if (txtGems != null)
{
txtGems.Text = new string('◆', Mathf.Clamp((int)skillInfo.RareType + 1, 1, 5));
txtGems.AddThemeFontSizeOverride("font_size", UiTokens.FontMicro);
txtGems.AddThemeColorOverride("font_color", SkillPalette.RarityColor(skillInfo.RareType));
}
ApplyTypeBadge(skillInfo);
ApplyEffect(skillInfo);
RefreshStyle();
}
///
/// Applies the panel-owned selection state: the selected card gets the
/// golden surface, rarity border and a soft rarity glow, while hover
/// only lifts the border. Both are repainted from scratch so the card
/// can never end up half-styled after a filter rebuild.
///
public void SetSelected(bool selected)
{
_selected = selected;
RefreshStyle();
}
/// Frees the node; the panel owns the card's lifetime and rebuilds the grid.
public override void Destruct()
{
QueueFree();
}
private void ResolveNodes()
{
bg ??= GetNodeOrNull("Bg");
accent ??= GetNodeOrNull("Accent");
art ??= GetNodeOrNull("Art");
imgCard ??= GetNodeOrNull("Art/ImgCard");
txtName ??= GetNodeOrNull