import 'package:flutter/material.dart'; import 'package:asciineverdie/l10n/app_localizations.dart'; import 'package:asciineverdie/src/core/model/game_state.dart'; import 'package:asciineverdie/src/core/util/pq_logic.dart' as pq_logic; import 'package:asciineverdie/src/core/util/roman.dart' show intToRoman; import 'package:asciineverdie/src/features/game/widgets/desktop_panel_widgets.dart'; import 'package:asciineverdie/src/shared/retro_colors.dart'; /// 데스크톱 우측 패널: Plot/Quest /// /// Plot Development, Quests 목록 및 프로그레스 바 표시 class DesktopQuestPanel extends StatelessWidget { const DesktopQuestPanel({super.key, required this.state}); final GameState state; @override Widget build(BuildContext context) { final l10n = L10n.of(context); return Card( margin: const EdgeInsets.all(4), color: RetroColors.panelBg, shape: RoundedRectangleBorder( side: const BorderSide( color: RetroColors.panelBorderOuter, width: 2, ), borderRadius: BorderRadius.circular(0), ), child: Column( crossAxisAlignment: CrossAxisAlignment.stretch, children: [ DesktopPanelHeader(title: l10n.plotDevelopment), Expanded(child: _PlotList(state: state)), DesktopSegmentProgressBar( position: state.progress.plot.position, max: state.progress.plot.max, color: Colors.purple, tooltip: state.progress.plot.max > 0 ? '${pq_logic.roughTime(state.progress.plot.max - state.progress.plot.position)} remaining' : null, ), DesktopPanelHeader(title: l10n.quests), Expanded(child: _QuestList(state: state)), DesktopSegmentProgressBar( position: state.progress.quest.position, max: state.progress.quest.max, color: Colors.green, tooltip: state.progress.quest.max > 0 ? l10n.percentComplete( 100 * state.progress.quest.position ~/ state.progress.quest.max, ) : null, ), ], ), ); } } /// Plot 목록 위젯 class _PlotList extends StatelessWidget { const _PlotList({required this.state}); final GameState state; @override Widget build(BuildContext context) { final l10n = L10n.of(context); final plotCount = state.progress.plotStageCount; if (plotCount == 0) { return Center( child: Text( l10n.prologue.toUpperCase(), style: const TextStyle( fontFamily: 'PressStart2P', fontSize: 14, color: RetroColors.textDisabled, ), ), ); } return ListView.builder( itemCount: plotCount, padding: const EdgeInsets.symmetric(horizontal: 8), itemBuilder: (context, index) { final isCompleted = index < plotCount - 1; final isCurrent = index == plotCount - 1; return Padding( padding: const EdgeInsets.symmetric(vertical: 1), child: Row( children: [ Icon( isCompleted ? Icons.check_box : (isCurrent ? Icons.arrow_right : Icons.check_box_outline_blank), size: 12, color: isCompleted ? RetroColors.expGreen : (isCurrent ? RetroColors.gold : RetroColors.textDisabled), ), const SizedBox(width: 4), Expanded( child: Text( index == 0 ? l10n.prologue : l10n.actNumber(intToRoman(index)), style: TextStyle( fontFamily: 'PressStart2P', fontSize: 13, color: isCompleted ? RetroColors.textDisabled : (isCurrent ? RetroColors.gold : RetroColors.textLight), decoration: isCompleted ? TextDecoration.lineThrough : TextDecoration.none, ), ), ), ], ), ); }, ); } } /// Quest 목록 위젯 class _QuestList extends StatelessWidget { const _QuestList({required this.state}); final GameState state; @override Widget build(BuildContext context) { final l10n = L10n.of(context); final questHistory = state.progress.questHistory; if (questHistory.isEmpty) { return Center( child: Text( l10n.noActiveQuests.toUpperCase(), style: const TextStyle( fontFamily: 'PressStart2P', fontSize: 14, color: RetroColors.textDisabled, ), ), ); } return ListView.builder( itemCount: questHistory.length, padding: const EdgeInsets.symmetric(horizontal: 8), itemBuilder: (context, index) { final quest = questHistory[index]; final isCurrentQuest = index == questHistory.length - 1 && !quest.isComplete; return Padding( padding: const EdgeInsets.symmetric(vertical: 1), child: Row( children: [ Icon( isCurrentQuest ? Icons.arrow_right : (quest.isComplete ? Icons.check_box : Icons.check_box_outline_blank), size: 12, color: isCurrentQuest ? RetroColors.gold : (quest.isComplete ? RetroColors.expGreen : RetroColors.textDisabled), ), const SizedBox(width: 4), Expanded( child: Text( quest.caption, style: TextStyle( fontFamily: 'PressStart2P', fontSize: 13, color: isCurrentQuest ? RetroColors.gold : (quest.isComplete ? RetroColors.textDisabled : RetroColors.textLight), decoration: quest.isComplete ? TextDecoration.lineThrough : TextDecoration.none, ), overflow: TextOverflow.ellipsis, ), ), ], ), ); }, ); } }