import 'package:flutter/material.dart'; import 'package:asciineverdie/data/game_text_l10n.dart' as game_l10n; import 'package:asciineverdie/l10n/app_localizations.dart'; import 'package:asciineverdie/src/core/l10n/game_data_l10n.dart'; import 'package:asciineverdie/src/core/model/class_traits.dart'; import 'package:asciineverdie/src/core/model/race_traits.dart' show StatType; import 'package:asciineverdie/src/shared/retro_colors.dart'; import 'package:asciineverdie/src/shared/widgets/retro_widgets.dart'; /// 직업 선택 섹션 class ClassSelectionSection extends StatelessWidget { const ClassSelectionSection({ super.key, required this.klasses, required this.selectedIndex, required this.scrollController, required this.onSelected, }); final List klasses; final int selectedIndex; final ScrollController scrollController; final ValueChanged onSelected; @override Widget build(BuildContext context) { return RetroPanel( title: L10n.of(context).classSection, child: SizedBox( height: 300, child: ListView.builder( controller: scrollController, itemCount: klasses.length, itemBuilder: (context, index) { final isSelected = index == selectedIndex; final klass = klasses[index]; return GestureDetector( onTap: () => onSelected(index), child: Container( padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 6), decoration: BoxDecoration( color: isSelected ? RetroColors.panelBgLight : null, border: isSelected ? Border.all(color: RetroColors.gold, width: 1) : null, ), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Row( children: [ Icon( isSelected ? Icons.arrow_right : Icons.remove, size: 12, color: isSelected ? RetroColors.gold : RetroColors.textDisabled, ), const SizedBox(width: 4), Expanded( child: Text( GameDataL10n.getKlassName(context, klass.name), style: TextStyle( fontFamily: 'PressStart2P', fontSize: 14, color: isSelected ? RetroColors.gold : RetroColors.textLight, ), ), ), ], ), if (isSelected) _ClassInfo(klass: klass), ], ), ), ); }, ), ), ); } } /// 클래스 정보 표시 위젯 class _ClassInfo extends StatelessWidget { const _ClassInfo({required this.klass}); final ClassTraits klass; String _statName(StatType type) { return switch (type) { StatType.str => game_l10n.statStr, StatType.con => game_l10n.statCon, StatType.dex => game_l10n.statDex, StatType.intelligence => game_l10n.statInt, StatType.wis => game_l10n.statWis, StatType.cha => game_l10n.statCha, }; } String _translatePassive(ClassPassive passive) { final percent = (passive.value * 100).round(); return switch (passive.type) { ClassPassiveType.hpBonus => game_l10n.passiveHpBonus(percent), ClassPassiveType.physicalDamageBonus => game_l10n.passivePhysicalBonus(percent), ClassPassiveType.defenseBonus => game_l10n.passiveDefenseBonus(percent), ClassPassiveType.magicDamageBonus => game_l10n.passiveMagicBonus(percent), ClassPassiveType.evasionBonus => game_l10n.passiveEvasionBonus(percent), ClassPassiveType.criticalBonus => game_l10n.passiveCritBonus(percent), ClassPassiveType.postCombatHeal => game_l10n.passiveHpRegen(percent), ClassPassiveType.healingBonus => passive.description, ClassPassiveType.multiAttack => passive.description, ClassPassiveType.firstStrikeBonus => passive.description, }; } @override Widget build(BuildContext context) { final statMods = []; for (final entry in klass.statModifiers.entries) { final sign = entry.value > 0 ? '+' : ''; statMods.add('${_statName(entry.key)} $sign${entry.value}'); } final passiveDesc = klass.passives.isNotEmpty ? klass.passives.map((p) => _translatePassive(p)).join(', ') : ''; return Padding( padding: const EdgeInsets.only(left: 16, top: 4), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ if (statMods.isNotEmpty) Text( statMods.join(', '), style: const TextStyle( fontSize: 15, color: RetroColors.textLight, ), ), if (passiveDesc.isNotEmpty) Text( passiveDesc, style: const TextStyle(fontSize: 15, color: RetroColors.expGreen), ), ], ), ); } }