import 'package:flutter/material.dart'; import 'package:askiineverdie/l10n/app_localizations.dart'; import 'package:askiineverdie/src/core/animation/ascii_animation_data.dart'; import 'package:askiineverdie/src/core/animation/ascii_animation_type.dart'; import 'package:askiineverdie/src/core/model/game_state.dart'; import 'package:askiineverdie/src/features/game/widgets/ascii_animation_card.dart'; /// 상단 패널: ASCII 애니메이션 + Task Progress 바 class TaskProgressPanel extends StatelessWidget { const TaskProgressPanel({ super.key, required this.progress, required this.speedMultiplier, required this.onSpeedCycle, required this.colorTheme, required this.onThemeCycle, this.specialAnimation, this.weaponName, this.shieldName, this.characterLevel, this.monsterLevel, }); final ProgressState progress; final int speedMultiplier; final VoidCallback onSpeedCycle; final AsciiColorTheme colorTheme; final VoidCallback onThemeCycle; /// 특수 애니메이션 (레벨업, 퀘스트 완료 등) final AsciiAnimationType? specialAnimation; /// 장비 정보 (애니메이션 스타일 결정용) final String? weaponName; final String? shieldName; final int? characterLevel; final int? monsterLevel; @override Widget build(BuildContext context) { return Container( padding: const EdgeInsets.all(8), decoration: BoxDecoration( color: Theme.of(context).colorScheme.surfaceContainerHighest, border: Border( bottom: BorderSide(color: Theme.of(context).dividerColor), ), ), child: Column( mainAxisSize: MainAxisSize.min, children: [ // ASCII 애니메이션 카드 SizedBox( height: 120, child: AsciiAnimationCard( taskType: progress.currentTask.type, monsterBaseName: progress.currentTask.monsterBaseName, colorTheme: colorTheme, specialAnimation: specialAnimation, weaponName: weaponName, shieldName: shieldName, characterLevel: characterLevel, monsterLevel: monsterLevel, ), ), const SizedBox(height: 8), // 상태 메시지 + 버튼들 Row( children: [ _buildThemeButton(context), const SizedBox(width: 8), Expanded( child: Text( progress.currentTask.caption.isNotEmpty ? progress.currentTask.caption : L10n.of(context).welcomeMessage, style: Theme.of(context).textTheme.bodyMedium, textAlign: TextAlign.center, ), ), const SizedBox(width: 8), _buildSpeedButton(context), ], ), const SizedBox(height: 4), // Task Progress 바 _buildProgressBar(context), ], ), ); } Widget _buildThemeButton(BuildContext context) { final themeLabel = switch (colorTheme) { AsciiColorTheme.green => 'G', AsciiColorTheme.amber => 'A', AsciiColorTheme.white => 'W', AsciiColorTheme.system => 'S', }; final themeColor = switch (colorTheme) { AsciiColorTheme.green => const Color(0xFF00FF00), AsciiColorTheme.amber => const Color(0xFFFFB000), AsciiColorTheme.white => Colors.white, AsciiColorTheme.system => Theme.of(context).colorScheme.primary, }; return SizedBox( height: 28, child: OutlinedButton( onPressed: onThemeCycle, style: OutlinedButton.styleFrom( padding: const EdgeInsets.symmetric(horizontal: 8), visualDensity: VisualDensity.compact, side: BorderSide(color: themeColor.withValues(alpha: 0.5)), ), child: Text( themeLabel, style: TextStyle( fontWeight: FontWeight.bold, color: themeColor, ), ), ), ); } Widget _buildSpeedButton(BuildContext context) { return SizedBox( height: 28, child: OutlinedButton( onPressed: onSpeedCycle, style: OutlinedButton.styleFrom( padding: const EdgeInsets.symmetric(horizontal: 8), visualDensity: VisualDensity.compact, ), child: Text( '${speedMultiplier}x', style: TextStyle( fontWeight: speedMultiplier > 1 ? FontWeight.bold : FontWeight.normal, color: speedMultiplier > 1 ? Theme.of(context).colorScheme.primary : null, ), ), ), ); } Widget _buildProgressBar(BuildContext context) { final progressValue = progress.task.max > 0 ? (progress.task.position / progress.task.max).clamp(0.0, 1.0) : 0.0; return Padding( padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 4), child: LinearProgressIndicator( value: progressValue, backgroundColor: Theme.of(context).colorScheme.primary.withValues(alpha: 0.2), valueColor: AlwaysStoppedAnimation( Theme.of(context).colorScheme.primary, ), minHeight: 12, ), ); } }