import 'package:flutter/material.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'animated_draw_wheel.dart'; import 'alternative_draw_animations.dart'; import 'particle_draw_animation.dart'; enum DrawAnimationType { spinningWheel, cardFlip, slotMachine, numberRoulette, particleSystem, } class DrawAnimationSelector extends StatefulWidget { final List> members; final Function(String winnerId) onDrawComplete; final String? serverSeed; final String? clientSeed; final int? nonce; final Duration animationDuration; const DrawAnimationSelector({ super.key, required this.members, required this.onDrawComplete, this.serverSeed, this.clientSeed, this.nonce, this.animationDuration = const Duration(seconds: 4), }); @override State createState() => _DrawAnimationSelectorState(); } class _DrawAnimationSelectorState extends State { DrawAnimationType _selectedAnimation = DrawAnimationType.cardFlip; bool _isDrawStarted = false; @override void initState() { super.initState(); // Auto-select best animation based on member count _selectBestAnimation(); } void _selectBestAnimation() { final memberCount = widget.members.length; if (memberCount <= 8) { _selectedAnimation = DrawAnimationType.spinningWheel; } else if (memberCount <= 20) { _selectedAnimation = DrawAnimationType.cardFlip; } else if (memberCount <= 50) { _selectedAnimation = DrawAnimationType.slotMachine; } else { _selectedAnimation = DrawAnimationType.particleSystem; } } void _startDraw() { setState(() { _isDrawStarted = true; }); } void _resetDraw() { setState(() { _isDrawStarted = false; }); } Widget _buildAnimationSelector() { return Container( padding: EdgeInsets.all(20.w), decoration: BoxDecoration( color: Colors.white, borderRadius: BorderRadius.circular(16.r), boxShadow: [ BoxShadow( color: Colors.black.withOpacity(0.1), blurRadius: 10.r, offset: Offset(0, 5.h), ), ], ), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( 'Choose Draw Animation', style: TextStyle( fontSize: 20.sp, fontWeight: FontWeight.bold, color: Colors.grey.shade800, ), ), SizedBox(height: 16.h), Text( 'Members: ${widget.members.length}', style: TextStyle( fontSize: 14.sp, color: Colors.grey.shade600, ), ), SizedBox(height: 20.h), // Animation Options ...DrawAnimationType.values.map((type) => _buildAnimationOption(type)), SizedBox(height: 24.h), // Start Button SizedBox( width: double.infinity, child: ElevatedButton( onPressed: _startDraw, style: ElevatedButton.styleFrom( backgroundColor: Colors.purple.shade600, foregroundColor: Colors.white, padding: EdgeInsets.symmetric(vertical: 16.h), shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(12.r), ), ), child: Row( mainAxisAlignment: MainAxisAlignment.center, children: [ Icon(Icons.play_arrow, size: 20.w), SizedBox(width: 8.w), Text( 'Start ${_getAnimationName(_selectedAnimation)}', style: TextStyle(fontSize: 16.sp), ), ], ), ), ), ], ), ); } Widget _buildAnimationOption(DrawAnimationType type) { final isSelected = _selectedAnimation == type; final isRecommended = _isRecommendedAnimation(type); return Container( margin: EdgeInsets.only(bottom: 12.h), child: InkWell( onTap: () { setState(() { _selectedAnimation = type; }); }, borderRadius: BorderRadius.circular(12.r), child: Container( padding: EdgeInsets.all(16.w), decoration: BoxDecoration( color: isSelected ? Colors.purple.shade50 : Colors.grey.shade50, borderRadius: BorderRadius.circular(12.r), border: Border.all( color: isSelected ? Colors.purple.shade300 : Colors.grey.shade300, width: 2.w, ), ), child: Row( children: [ Container( width: 24.w, height: 24.w, decoration: BoxDecoration( color: isSelected ? Colors.purple.shade600 : Colors.grey.shade400, shape: BoxShape.circle, ), child: isSelected ? Icon(Icons.check, color: Colors.white, size: 16.w) : null, ), SizedBox(width: 16.w), Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Row( children: [ Text( _getAnimationName(type), style: TextStyle( fontSize: 16.sp, fontWeight: FontWeight.w600, color: isSelected ? Colors.purple.shade800 : Colors.grey.shade800, ), ), if (isRecommended) ...[ SizedBox(width: 8.w), Container( padding: EdgeInsets.symmetric(horizontal: 8.w, vertical: 2.h), decoration: BoxDecoration( color: Colors.green.shade100, borderRadius: BorderRadius.circular(12.r), ), child: Text( 'Recommended', style: TextStyle( fontSize: 10.sp, color: Colors.green.shade700, fontWeight: FontWeight.w500, ), ), ), ], ], ), SizedBox(height: 4.h), Text( _getAnimationDescription(type), style: TextStyle( fontSize: 12.sp, color: Colors.grey.shade600, ), ), ], ), ), Icon( _getAnimationIcon(type), color: isSelected ? Colors.purple.shade600 : Colors.grey.shade400, size: 24.w, ), ], ), ), ), ); } bool _isRecommendedAnimation(DrawAnimationType type) { final memberCount = widget.members.length; switch (type) { case DrawAnimationType.spinningWheel: return memberCount <= 8; case DrawAnimationType.cardFlip: return memberCount > 8 && memberCount <= 20; case DrawAnimationType.slotMachine: return memberCount > 20 && memberCount <= 50; case DrawAnimationType.numberRoulette: return memberCount > 20 && memberCount <= 100; case DrawAnimationType.particleSystem: return memberCount > 50; } } String _getAnimationName(DrawAnimationType type) { switch (type) { case DrawAnimationType.spinningWheel: return 'Spinning Wheel'; case DrawAnimationType.cardFlip: return 'Card Flip'; case DrawAnimationType.slotMachine: return 'Slot Machine'; case DrawAnimationType.numberRoulette: return 'Number Roulette'; case DrawAnimationType.particleSystem: return 'Particle System'; } } String _getAnimationDescription(DrawAnimationType type) { switch (type) { case DrawAnimationType.spinningWheel: return 'Classic spinning wheel - Best for small groups (≤8 members)'; case DrawAnimationType.cardFlip: return 'Cards flipping rapidly - Great for medium groups (9-20 members)'; case DrawAnimationType.slotMachine: return 'Slot machine style - Perfect for large groups (21-50 members)'; case DrawAnimationType.numberRoulette: return 'Number roulette wheel - Good for very large groups (21-100 members)'; case DrawAnimationType.particleSystem: return 'Particle effects - Best for massive groups (50+ members)'; } } IconData _getAnimationIcon(DrawAnimationType type) { switch (type) { case DrawAnimationType.spinningWheel: return Icons.casino; case DrawAnimationType.cardFlip: return Icons.style; case DrawAnimationType.slotMachine: return Icons.games; case DrawAnimationType.numberRoulette: return Icons.timeline; case DrawAnimationType.particleSystem: return Icons.auto_awesome; } } Widget _buildSelectedAnimation() { switch (_selectedAnimation) { case DrawAnimationType.spinningWheel: return AnimatedDrawWheel( members: widget.members, onDrawComplete: widget.onDrawComplete, serverSeed: widget.serverSeed, clientSeed: widget.clientSeed, nonce: widget.nonce, ); case DrawAnimationType.cardFlip: return CardFlipDrawAnimation( members: widget.members, onDrawComplete: widget.onDrawComplete, serverSeed: widget.serverSeed, clientSeed: widget.clientSeed, nonce: widget.nonce, animationDuration: widget.animationDuration, ); case DrawAnimationType.slotMachine: return SlotMachineDrawAnimation( members: widget.members, onDrawComplete: widget.onDrawComplete, serverSeed: widget.serverSeed, clientSeed: widget.clientSeed, nonce: widget.nonce, animationDuration: widget.animationDuration, ); case DrawAnimationType.numberRoulette: return NumberRouletteDrawAnimation( members: widget.members, onDrawComplete: widget.onDrawComplete, serverSeed: widget.serverSeed, clientSeed: widget.clientSeed, nonce: widget.nonce, animationDuration: widget.animationDuration, ); case DrawAnimationType.particleSystem: return ParticleDrawAnimation( members: widget.members, onDrawComplete: widget.onDrawComplete, serverSeed: widget.serverSeed, clientSeed: widget.clientSeed, nonce: widget.nonce, animationDuration: widget.animationDuration, ); } } @override Widget build(BuildContext context) { return Container( width: 400.w, child: Column( children: [ if (!_isDrawStarted) _buildAnimationSelector(), if (_isDrawStarted) ...[ _buildSelectedAnimation(), SizedBox(height: 20.h), SizedBox( width: double.infinity, child: OutlinedButton( onPressed: _resetDraw, style: OutlinedButton.styleFrom( padding: EdgeInsets.symmetric(vertical: 12.h), shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(8.r), ), ), child: Text( 'Choose Different Animation', style: TextStyle(fontSize: 14.sp), ), ), ), ], ], ), ); } }