Files
flutter-rimworld-modman/lib/main.dart
2025-03-18 00:31:32 +01:00

1302 lines
50 KiB
Dart

//import 'dart:io';
//
//import 'package:flutter/material.dart';
//import 'package:rimworld_modman/logger.dart';
//import 'package:rimworld_modman/mod.dart';
//import 'package:rimworld_modman/mod_list.dart';
//
//// Constants for file paths
//final String root =
// Platform.isWindows
// ? r'C:/Users/Administrator/Seafile/Games-RimWorld'
// : '~/Library/Application Support/RimWorld';
//final String modsRoot = Platform.isWindows ? '$root/294100' : '$root/Mods';
//final String configRoot =
// Platform.isWindows
// ? '$root/AppData/RimWorld by Ludeon Studios/Config'
// : '$root/Config';
//final String configPath = '$configRoot/ModsConfig.xml';
//final String logsPath = '$root/ModManager';
//
//late ModList modManager;
//
//void main() {
// WidgetsFlutterBinding.ensureInitialized();
//
// // Get a reference to the logger (now auto-initializes)
// final logger = Logger.instance;
// logger.info('RimWorld Mod Manager starting...');
//
// // Initialize the mod manager
// modManager = ModList(modsPath: modsRoot, configPath: configPath);
//
// // Start the app
// runApp(const RimWorldModManager());
//}
//
//class RimWorldModManager extends StatelessWidget {
// const RimWorldModManager({super.key});
//
// @override
// Widget build(BuildContext context) {
// return MaterialApp(
// title: 'RimWorld Mod Manager',
// theme: ThemeData.dark().copyWith(
// primaryColor: const Color(0xFF3D4A59),
// colorScheme: ColorScheme.fromSeed(
// seedColor: const Color(0xFF3D4A59),
// brightness: Brightness.dark,
// ),
// scaffoldBackgroundColor: const Color(0xFF1E262F),
// cardColor: const Color(0xFF2A3440),
// appBarTheme: const AppBarTheme(
// backgroundColor: Color(0xFF2A3440),
// foregroundColor: Colors.white,
// ),
// ),
// home: const ModManagerHomePage(),
// );
// }
//}
//
//class ModManagerHomePage extends StatefulWidget {
// const ModManagerHomePage({super.key});
//
// @override
// State<ModManagerHomePage> createState() => _ModManagerHomePageState();
//}
//
//class _ModManagerHomePageState extends State<ModManagerHomePage> {
// int _selectedIndex = 0;
//
// final List<Widget> _pages = [
// const ModManagerPage(),
// const TroubleshootingPage(),
// ];
//
// @override
// Widget build(BuildContext context) {
// return Scaffold(
// appBar: AppBar(title: const Text('RimWorld Mod Manager')),
// body: _pages[_selectedIndex],
// bottomNavigationBar: BottomNavigationBar(
// currentIndex: _selectedIndex,
// onTap: (index) {
// setState(() {
// _selectedIndex = index;
// });
// },
// items: const [
// BottomNavigationBarItem(icon: Icon(Icons.extension), label: 'Mods'),
// BottomNavigationBarItem(
// icon: Icon(Icons.build),
// label: 'Troubleshoot',
// ),
// ],
// ),
// );
// }
//}
//
//// Combined page for mod management with two-panel layout
//class ModManagerPage extends StatefulWidget {
// const ModManagerPage({super.key});
//
// @override
// State<ModManagerPage> createState() => _ModManagerPageState();
//}
//
//class _ModManagerPageState extends State<ModManagerPage> {
// // For all available mods (left panel)
// List<Mod> _availableMods = [];
//
// // For active mods (right panel)
// List<Mod> _activeMods = [];
//
// bool _isLoading = false;
// String _statusMessage = '';
// int _totalModsFound = 0;
// bool _skipFileCount = false;
// bool _hasCycles = false;
// List<String>? _cycleInfo;
// List<List<String>> _incompatibleMods = [];
// List<String>? _loadOrderErrors;
//
// final TextEditingController _searchController = TextEditingController();
// String _searchQuery = '';
//
// @override
// void initState() {
// super.initState();
// // Check if mods are already loaded
// if (modManager.mods.isNotEmpty) {
// _loadModsFromGlobalState();
// }
//
// _searchController.addListener(() {
// setState(() {
// _searchQuery = _searchController.text.toLowerCase();
// });
// });
// }
//
// @override
// void dispose() {
// _searchController.dispose();
// super.dispose();
// }
//
// void _loadModsFromGlobalState() {
// setState(() {
// // Get all mods for the left panel (sorted alphabetically)
// _availableMods = modManager.mods.values.toList();
// _availableMods.sort((a, b) => a.name.compareTo(b.name));
//
// // Get active mods for the right panel (in load order)
// _activeMods = modManager.mods.values.where((m) => m.enabled).toList();
// _isLoading = false;
// _statusMessage = 'Loaded ${_availableMods.length} mods';
// _totalModsFound = _availableMods.length;
// });
// }
//
// @override
// Widget build(BuildContext context) {
// return Scaffold(
// body:
// _isLoading && _availableMods.isEmpty
// ? _buildLoadingView()
// : _availableMods.isEmpty
// ? _buildEmptyState()
// : _buildSplitView(),
// );
// }
//
// Widget _buildLoadingView() {
// return Center(
// child: Column(
// mainAxisAlignment: MainAxisAlignment.center,
// children: [
// const CircularProgressIndicator(),
// const SizedBox(height: 16),
// Text(
// _statusMessage,
// style: Theme.of(context).textTheme.bodyMedium,
// textAlign: TextAlign.center,
// ),
// ],
// ),
// );
// }
//
// Widget _buildEmptyState() {
// return Center(
// child: Column(
// mainAxisAlignment: MainAxisAlignment.center,
// children: [
// const Icon(Icons.extension, size: 64),
// const SizedBox(height: 16),
// Text(
// 'Mod Manager',
// style: Theme.of(context).textTheme.headlineMedium,
// ),
// const SizedBox(height: 16),
// Text(
// 'Ready to scan for RimWorld mods.',
// style: Theme.of(context).textTheme.bodyLarge,
// ),
// const SizedBox(height: 12),
// Row(
// mainAxisSize: MainAxisSize.min,
// children: [
// Checkbox(
// value: _skipFileCount,
// onChanged: (value) {
// setState(() {
// _skipFileCount = value ?? true;
// });
// },
// ),
// const Text('Skip file counting (faster loading)'),
// ],
// ),
// const SizedBox(height: 24),
// ElevatedButton(
// onPressed: _startLoadingMods,
// child: const Text('Scan for Mods'),
// ),
// ],
// ),
// );
// }
//
// Widget _buildSplitView() {
// // Filter both available and active mods based on search query
// final filteredAvailableMods =
// _searchQuery.isEmpty
// ? _availableMods
// : _availableMods
// .where(
// (mod) =>
// mod.name.toLowerCase().contains(_searchQuery) ||
// mod.id.toLowerCase().contains(_searchQuery),
// )
// .toList();
//
// final filteredActiveMods =
// _searchQuery.isEmpty
// ? _activeMods
// : _activeMods
// .where(
// (mod) =>
// mod.name.toLowerCase().contains(_searchQuery) ||
// mod.id.toLowerCase().contains(_searchQuery),
// )
// .toList();
//
// return Column(
// children: [
// Padding(
// padding: const EdgeInsets.all(8.0),
// child: Row(
// children: [
// // Search field
// Expanded(
// child: TextField(
// controller: _searchController,
// decoration: InputDecoration(
// hintText: 'Search mods by name or ID...',
// prefixIcon: const Icon(Icons.search),
// border: OutlineInputBorder(
// borderRadius: BorderRadius.circular(8.0),
// ),
// suffixIcon:
// _searchQuery.isNotEmpty
// ? IconButton(
// icon: const Icon(Icons.clear),
// onPressed: () {
// _searchController.clear();
// },
// )
// : null,
// ),
// ),
// ),
// const SizedBox(width: 8),
// // Reload button
// IconButton(
// icon: const Icon(Icons.refresh),
// tooltip: 'Reload mods',
// onPressed: _startLoadingMods,
// ),
// const SizedBox(width: 8),
// // Load Dependencies button
// Tooltip(
// message:
// 'Automatically load missing dependencies for active mods',
// child: ElevatedButton.icon(
// icon: const Icon(Icons.download),
// label: const Text('Load Deps'),
// onPressed: _loadRequiredDependencies,
// ),
// ),
// const SizedBox(width: 8),
// // Auto-sort button
// ElevatedButton.icon(
// icon: const Icon(Icons.sort),
// label: const Text('Auto-Sort'),
// onPressed: _sortActiveMods,
// ),
// const SizedBox(width: 8),
// // Save button
// ElevatedButton.icon(
// icon: const Icon(Icons.save),
// label: const Text('Save'),
// onPressed: _saveModOrder,
// ),
// ],
// ),
// ),
//
// // Status message
// if (!_isLoading && _statusMessage.isNotEmpty)
// Padding(
// padding: const EdgeInsets.symmetric(horizontal: 8.0, vertical: 4.0),
// child: Text(
// _statusMessage,
// style: TextStyle(
// color:
// _hasCycles || _incompatibleMods.isNotEmpty
// ? Colors.orange
// : Colors.green,
// ),
// ),
// ),
//
// // Error display section
// if (_hasCycles ||
// _incompatibleMods.isNotEmpty ||
// (_loadOrderErrors?.isNotEmpty ?? false))
// Container(
// margin: const EdgeInsets.symmetric(horizontal: 8.0, vertical: 4.0),
// padding: const EdgeInsets.all(8.0),
// decoration: BoxDecoration(
// color: Colors.red.shade900.withOpacity(0.3),
// borderRadius: BorderRadius.circular(4.0),
// border: Border.all(color: Colors.red.shade800),
// ),
// child: Column(
// crossAxisAlignment: CrossAxisAlignment.start,
// children: [
// // Cycle warnings
// if (_hasCycles && _cycleInfo != null)
// Padding(
// padding: const EdgeInsets.only(bottom: 4.0),
// child: Row(
// children: [
// const Icon(Icons.loop, color: Colors.orange, size: 16),
// const SizedBox(width: 4),
// Expanded(
// child: Text(
// 'Dependency cycle detected: ${_cycleInfo!.join(" -> ")}',
// style: const TextStyle(color: Colors.orange),
// ),
// ),
// ],
// ),
// ),
//
// // Incompatible mod warnings
// if (_incompatibleMods.isNotEmpty)
// Padding(
// padding: const EdgeInsets.only(bottom: 4.0),
// child: Row(
// crossAxisAlignment: CrossAxisAlignment.start,
// children: [
// const Icon(
// Icons.warning,
// color: Colors.orange,
// size: 16,
// ),
// const SizedBox(width: 4),
// Expanded(
// child: Column(
// crossAxisAlignment: CrossAxisAlignment.start,
// children: [
// Text(
// '${_incompatibleMods.length} incompatible mod pairs:',
// style: const TextStyle(color: Colors.orange),
// ),
// if (_incompatibleMods.length <= 3)
// ...List.generate(_incompatibleMods.length, (
// index,
// ) {
// final pair = _incompatibleMods[index];
// final mod1 =
// modManager.mods[pair[0]]?.name ?? pair[0];
// final mod2 =
// modManager.mods[pair[1]]?.name ?? pair[1];
// return Padding(
// padding: const EdgeInsets.only(
// left: 12.0,
// top: 2.0,
// ),
// child: Text(
// '• $mod1 ↔ $mod2',
// style: TextStyle(
// color: Colors.orange.shade300,
// fontSize: 12,
// ),
// ),
// );
// }),
// ],
// ),
// ),
// ],
// ),
// ),
//
// // Other errors (missing dependencies, etc.)
// if (_loadOrderErrors?.isNotEmpty ?? false)
// Row(
// crossAxisAlignment: CrossAxisAlignment.start,
// children: [
// const Icon(
// Icons.error_outline,
// color: Colors.red,
// size: 16,
// ),
// const SizedBox(width: 4),
// Expanded(
// child: Column(
// crossAxisAlignment: CrossAxisAlignment.start,
// children: [
// const Text(
// 'Dependency errors:',
// style: TextStyle(color: Colors.red),
// ),
// ...List.generate(
// _loadOrderErrors!.length > 5
// ? 5
// : _loadOrderErrors!.length,
// (index) => Padding(
// padding: const EdgeInsets.only(
// left: 12.0,
// top: 2.0,
// ),
// child: Text(
// '• ${_loadOrderErrors![index]}',
// style: TextStyle(
// color: Colors.red.shade300,
// fontSize: 12,
// ),
// ),
// ),
// ),
// if (_loadOrderErrors!.length > 5)
// Padding(
// padding: const EdgeInsets.only(
// left: 12.0,
// top: 4.0,
// ),
// child: Text(
// '(${_loadOrderErrors!.length - 5} more errors...)',
// style: TextStyle(
// color: Colors.red.shade300,
// fontSize: 12,
// fontStyle: FontStyle.italic,
// ),
// ),
// ),
// ],
// ),
// ),
// ],
// ),
// ],
// ),
// ),
//
// // Main split view
// Expanded(
// child: Row(
// children: [
// // LEFT PANEL - All available mods (alphabetical)
// Expanded(
// child: Card(
// margin: const EdgeInsets.all(8.0),
// child: Column(
// crossAxisAlignment: CrossAxisAlignment.stretch,
// children: [
// Container(
// color: Theme.of(context).primaryColor,
// padding: const EdgeInsets.all(8.0),
// child: Text(
// 'Available Mods (${filteredAvailableMods.length}${_searchQuery.isNotEmpty ? '/${_availableMods.length}' : ''})',
// style: const TextStyle(fontWeight: FontWeight.bold),
// textAlign: TextAlign.center,
// ),
// ),
// if (_searchQuery.isNotEmpty)
// Padding(
// padding: const EdgeInsets.all(4.0),
// child: Text(
// 'Searching: "$_searchQuery"',
// style: TextStyle(
// fontSize: 12,
// fontStyle: FontStyle.italic,
// color: Colors.grey.shade400,
// ),
// textAlign: TextAlign.center,
// ),
// ),
// Expanded(
// child: ListView.builder(
// itemCount: filteredAvailableMods.length,
// itemBuilder: (context, index) {
// final mod = filteredAvailableMods[index];
// final isActive = mod.enabled;
//
// return GestureDetector(
// onDoubleTap: () => _toggleModActive(mod),
// child: ListTile(
// title: Text(
// mod.name,
// style: TextStyle(
// color:
// isActive ? Colors.green : Colors.white,
// ),
// ),
// subtitle: Text(
// 'ID: ${mod.id}\nSize: ${mod.size} files',
// style: Theme.of(context).textTheme.bodySmall,
// ),
// trailing: Row(
// mainAxisSize: MainAxisSize.min,
// children: [
// if (mod.isBaseGame)
// const Tooltip(
// message: 'Base Game',
// child: Icon(
// Icons.home,
// color: Colors.blue,
// size: 24,
// ),
// ),
// if (mod.isExpansion)
// const Tooltip(
// message: 'Expansion',
// child: Icon(
// Icons.star,
// color: Colors.yellow,
// size: 24,
// ),
// ),
// const SizedBox(width: 4),
// if (mod.dependencies.isNotEmpty)
// Tooltip(
// message:
// 'Dependencies:\n${mod.dependencies.join('\n')}',
// child: const Icon(
// Icons.link,
// color: Colors.orange,
// size: 24,
// ),
// ),
// if (mod.loadAfter.isNotEmpty)
// Tooltip(
// message:
// 'Loads after:\n${mod.loadAfter.join('\n')}',
// child: const Icon(
// Icons.arrow_downward,
// color: Colors.blue,
// size: 24,
// ),
// ),
// if (mod.loadBefore.isNotEmpty)
// Tooltip(
// message:
// 'Loads before:\n${mod.loadBefore.join('\n')}',
// child: const Icon(
// Icons.arrow_upward,
// color: Colors.green,
// size: 24,
// ),
// ),
// ],
// ),
// onTap: () {
// // Show mod details in future
// },
// ),
// );
// },
// ),
// ),
// ],
// ),
// ),
// ),
//
// // RIGHT PANEL - Active mods (load order)
// Expanded(
// child: Card(
// margin: const EdgeInsets.all(8.0),
// child: Column(
// crossAxisAlignment: CrossAxisAlignment.stretch,
// children: [
// Container(
// color: Theme.of(context).primaryColor,
// padding: const EdgeInsets.all(8.0),
// child: Text(
// 'Active Mods (${filteredActiveMods.length}${_searchQuery.isNotEmpty ? '/${_activeMods.length}' : ''})',
// style: const TextStyle(fontWeight: FontWeight.bold),
// textAlign: TextAlign.center,
// ),
// ),
// Padding(
// padding: const EdgeInsets.all(8.0),
// child: Text(
// _searchQuery.isNotEmpty
// ? 'Searching: "$_searchQuery"'
// : 'Larger mods are prioritized during auto-sorting.',
// style: TextStyle(
// fontSize: 12,
// color: Colors.grey.shade400,
// fontStyle: FontStyle.italic,
// ),
// textAlign: TextAlign.center,
// ),
// ),
// Expanded(
// child: ListView.builder(
// itemCount: filteredActiveMods.length,
// itemBuilder: (context, index) {
// final mod = filteredActiveMods[index];
// // Find the actual position in the complete active mods list (for correct load order)
// final actualLoadOrderPosition =
// _activeMods.indexWhere((m) => m.id == mod.id) +
// 1;
//
// return GestureDetector(
// onDoubleTap: () {
// // Don't allow deactivating base game or expansions
// if (!mod.isBaseGame && !mod.isExpansion) {
// _toggleModActive(mod);
// } else {
// ScaffoldMessenger.of(context).showSnackBar(
// const SnackBar(
// content: Text(
// 'Core game and expansions cannot be deactivated',
// ),
// backgroundColor: Colors.orange,
// ),
// );
// }
// },
// child: Card(
// margin: const EdgeInsets.symmetric(
// horizontal: 8.0,
// vertical: 4.0,
// ),
// child: ListTile(
// leading: SizedBox(
// width: 50,
// child: Column(
// mainAxisSize: MainAxisSize.min,
// mainAxisAlignment:
// MainAxisAlignment.center,
// children: [
// SizedBox(
// height: 24,
// child: Container(
// padding: const EdgeInsets.symmetric(
// horizontal: 4,
// ),
// decoration: BoxDecoration(
// color:
// _searchQuery.isNotEmpty
// ? Colors.blue.withOpacity(
// 0.2,
// )
// : null,
// borderRadius:
// BorderRadius.circular(4),
// ),
// child: Tooltip(
// message:
// 'Load position: $actualLoadOrderPosition of ${_activeMods.length}${_searchQuery.isNotEmpty ? " (preserved when filtering)" : ""}',
// child: Text(
// '$actualLoadOrderPosition',
// style: TextStyle(
// fontWeight: FontWeight.bold,
// fontSize: 12,
// color:
// _searchQuery.isNotEmpty
// ? Colors.blue.shade300
// : null,
// ),
// ),
// ),
// ),
// ),
// SizedBox(
// height: 24,
// child: Center(
// child:
// mod.size > 0
// ? Tooltip(
// message:
// 'This mod contains ${mod.size} files.',
// child: Text(
// '${mod.size}',
// style: const TextStyle(
// fontSize: 10,
// color: Colors.grey,
// ),
// ),
// )
// : const SizedBox(),
// ),
// ),
// ],
// ),
// ),
// title: Text(mod.name),
// subtitle: Text(
// mod.id,
// style: const TextStyle(fontSize: 12),
// ),
// trailing: Row(
// mainAxisSize: MainAxisSize.min,
// children: [
// if (mod.isBaseGame)
// const Tooltip(
// message: 'Base Game',
// child: Icon(
// Icons.home,
// color: Colors.blue,
// size: 24,
// ),
// ),
// if (mod.isExpansion)
// const Tooltip(
// message: 'Expansion',
// child: Icon(
// Icons.star,
// color: Colors.yellow,
// size: 24,
// ),
// ),
// if (mod.dependencies.isNotEmpty)
// Tooltip(
// message:
// 'Dependencies:\n${mod.dependencies.join('\n')}',
// child: const Icon(
// Icons.link,
// color: Colors.orange,
// size: 24,
// ),
// ),
// const SizedBox(width: 4),
// if (mod.loadAfter.isNotEmpty)
// Tooltip(
// message:
// 'Loads after other mods:\n${mod.loadAfter.join('\n')}',
// child: const Icon(
// Icons.arrow_downward,
// color: Colors.blue,
// size: 24,
// ),
// ),
// const SizedBox(width: 4),
// if (mod.loadBefore.isNotEmpty)
// Tooltip(
// message:
// 'Loads before other mods:\n${mod.loadBefore.join('\n')}',
// child: const Icon(
// Icons.arrow_upward,
// color: Colors.green,
// size: 24,
// ),
// ),
// ],
// ),
// onTap: () {
// // Show mod details in future
// },
// ),
// ),
// );
// },
// ),
// ),
// ],
// ),
// ),
// ),
// ],
// ),
// ),
// ],
// );
// }
//
// void _startLoadingMods() {
// setState(() {
// _availableMods.clear();
// _activeMods.clear();
// _isLoading = true;
// _statusMessage = 'Scanning for mods...';
// _hasCycles = false;
// _cycleInfo = null;
// _incompatibleMods = [];
// });
//
// // Create an async function to load mods
// Future<void> loadMods() async {
// try {
// // First load available mods
// await for (final mod in modManager.loadAvailable()) {
// // Update UI for each mod loaded
// if (mounted) {
// setState(() {
// _statusMessage = 'Loaded mod: ${mod.name}';
// _totalModsFound = modManager.mods.length;
// });
// }
// }
//
// // Then load active mods from config
// await for (final mod in modManager.loadActive()) {
// // Update UI as active mods are loaded
// if (mounted) {
// setState(() {
// _statusMessage = 'Loading active mod: ${mod.name}';
// });
// }
// }
//
// // Update the UI with all loaded mods
// if (mounted) {
// _loadModsFromGlobalState();
// setState(() {
// _statusMessage =
// 'Loaded ${_availableMods.length} mods, ${_activeMods.length} active';
// });
// }
// } catch (error) {
// if (mounted) {
// setState(() {
// _isLoading = false;
// _statusMessage = 'Error loading mods: $error';
// });
// }
// }
// }
//
// // Start the loading process
// loadMods();
// }
//
// void _toggleModActive(Mod mod) {
// // Cannot deactivate base game or expansions
// if ((mod.isBaseGame || mod.isExpansion) && mod.enabled) {
// ScaffoldMessenger.of(context).showSnackBar(
// const SnackBar(
// content: Text('Core game and expansions cannot be deactivated'),
// backgroundColor: Colors.orange,
// ),
// );
// return;
// }
//
// // Get the current state before toggling
// final bool wasEnabled = mod.enabled;
//
// // Toggle the mod in the global mod manager
// modManager.setEnabled(mod.id, !wasEnabled);
// Logger.instance.info(
// 'Toggled mod ${mod.name} (${mod.id}) from ${wasEnabled ? 'enabled' : 'disabled'} to ${!wasEnabled ? 'enabled' : 'disabled'}',
// );
//
// // Update the UI
// setState(() {
// // Update in the available mods list
// final index = _availableMods.indexWhere((m) => m.id == mod.id);
// if (index >= 0) {
// _availableMods[index] = modManager.mods[mod.id]!;
// }
//
// // Update the active mods list
// _activeMods = modManager.mods.values.where((m) => m.enabled).toList();
//
// _statusMessage =
// 'Mod "${mod.name}" ${!wasEnabled ? 'activated' : 'deactivated'}';
// });
// }
//
// void _sortActiveMods() async {
// if (_activeMods.isEmpty) {
// setState(() {
// _statusMessage = 'No active mods to sort';
// });
// return;
// }
//
// setState(() {
// _isLoading = true;
// _statusMessage = 'Sorting mods based on dependencies...';
// _hasCycles = false;
// _cycleInfo = null;
// _incompatibleMods = [];
// _loadOrderErrors = null;
// });
//
// // Use a Future.delayed to allow the UI to update
// await Future.delayed(Duration.zero);
//
// try {
// final logger = Logger.instance;
// logger.info('Starting auto-sort of ${_activeMods.length} active mods');
//
// // Generate a load order for active mods
// final loadOrder = modManager.generateLoadOrder();
//
// // Store all errors
// if (loadOrder.hasErrors) {
// setState(() {
// _loadOrderErrors = List<String>.from(loadOrder.errors);
// });
//
// logger.warning(
// 'Found ${loadOrder.errors.length} errors during sorting',
// );
// for (final error in loadOrder.errors) {
// logger.warning(' - $error');
// }
//
// setState(() {
// _hasCycles = loadOrder.errors.any(
// (e) => e.contains('Cyclic dependency'),
// );
// if (_hasCycles) {
// // Extract cycle info from error message
// final cycleError = loadOrder.errors.firstWhere(
// (e) => e.contains('Cyclic dependency'),
// orElse: () => '',
// );
// logger.warning('Detected dependency cycle: $cycleError');
//
// if (cycleError.isNotEmpty) {
// // Extract cycle path from error message
// final startIndex = cycleError.indexOf(':');
// if (startIndex != -1) {
// final pathStr = cycleError.substring(startIndex + 1).trim();
// _cycleInfo = pathStr.split(' -> ');
// logger.info(
// 'Extracted cycle path: ${_cycleInfo!.join(" -> ")}',
// );
// }
// }
// }
// });
// } else {
// _loadOrderErrors = null;
// }
//
// // Check for incompatibilities
// _incompatibleMods = modManager.checkIncompatibilities(
// modManager.activeMods.keys.toList(),
// );
//
// if (_incompatibleMods.isNotEmpty) {
// logger.warning(
// 'Found ${_incompatibleMods.length} incompatible mod pairs:',
// );
// for (final pair in _incompatibleMods) {
// final mod1 = modManager.mods[pair[0]]?.name ?? pair[0];
// final mod2 = modManager.mods[pair[1]]?.name ?? pair[1];
// logger.warning(' - $mod1 is incompatible with $mod2');
// }
// }
//
// // Get sorted mods from the load order
// final List<Mod> sortedMods = [];
// for (final modId in loadOrder.loadOrder) {
// if (modManager.mods.containsKey(modId)) {
// sortedMods.add(modManager.mods[modId]!);
// }
// }
//
// logger.info(
// 'Sorting complete. Arranged ${sortedMods.length} mods in load order',
// );
// if (sortedMods.isNotEmpty) {
// logger.info(
// 'First 5 mods in order: ${sortedMods.take(5).map((m) => m.name).join(', ')}',
// );
// if (sortedMods.length > 5) {
// logger.info('... (${sortedMods.length - 5} more) ...');
// logger.info(
// 'Last 3 mods in order: ${sortedMods.reversed.take(3).map((m) => m.name).toList().reversed.join(', ')}',
// );
// }
// }
//
// setState(() {
// _activeMods = sortedMods;
// _isLoading = false;
// _statusMessage = 'Sorting complete! ${sortedMods.length} mods sorted.';
// if (_hasCycles) {
// _statusMessage += ' Warning: Dependency cycles were found and fixed.';
// }
// if (_incompatibleMods.isNotEmpty) {
// _statusMessage +=
// ' Warning: ${_incompatibleMods.length} incompatible mod pairs found.';
// }
// });
// } catch (e) {
// Logger.instance.error('Error during auto-sort: $e');
// setState(() {
// _isLoading = false;
// _statusMessage = 'Error sorting mods: $e';
// });
// }
// }
//
// void _saveModOrder() async {
// if (_activeMods.isEmpty) {
// setState(() {
// _statusMessage = 'No active mods to save';
// });
// return;
// }
//
// setState(() {
// _isLoading = true;
// _statusMessage = 'Saving mod load order...';
// });
//
// try {
// final logger = Logger.instance;
// logger.info(
// 'Saving mod load order for ${_activeMods.length} active mods to $configPath',
// );
//
// // Save the mod list to the XML config file
// final file = File(configPath);
// final buffer = StringBuffer();
//
// buffer.writeln('<?xml version="1.0" encoding="utf-8"?>');
// buffer.writeln('<ModsConfigData>');
// buffer.writeln(' <version>1</version>');
//
// // Write active mods
// buffer.writeln(' <activeMods>');
// for (final mod in _activeMods) {
// buffer.writeln(' <li>${mod.id}</li>');
// logger.info(' - Adding mod to config: ${mod.name} (${mod.id})');
// }
// buffer.writeln(' </activeMods>');
//
// // Count expansions
// final expansions = _availableMods.where((m) => m.isExpansion).toList();
// logger.info('Found ${expansions.length} expansions to include in config');
//
// // Add known expansions
// buffer.writeln(' <knownExpansions>');
// for (final mod in expansions) {
// buffer.writeln(' <li>${mod.id}</li>');
// logger.info(' - Adding expansion to config: ${mod.name} (${mod.id})');
// }
// buffer.writeln(' </knownExpansions>');
//
// buffer.writeln('</ModsConfigData>');
//
// // Ensure directory exists
// final directory = Directory(configRoot);
// if (!directory.existsSync()) {
// logger.info('Creating config directory: $configRoot');
// directory.createSync(recursive: true);
// }
//
// // Write to file
// logger.info('Writing config file to $configPath');
// await file.writeAsString(buffer.toString());
// logger.info('Successfully saved mod configuration');
//
// setState(() {
// _isLoading = false;
// _statusMessage = 'Mod load order saved successfully!';
// });
//
// // Show success message
// ScaffoldMessenger.of(context).showSnackBar(
// SnackBar(
// content: Text(
// 'Mod order saved to config. ${_activeMods.length} mods enabled.',
// ),
// backgroundColor: Colors.green,
// ),
// );
// } catch (e) {
// final logger = Logger.instance;
// logger.error('Error saving mod load order: $e');
//
// setState(() {
// _isLoading = false;
// _statusMessage = 'Error saving mod load order: $e';
// });
//
// // Show error message
// ScaffoldMessenger.of(context).showSnackBar(
// SnackBar(
// content: Text('Error saving mod order: $e'),
// backgroundColor: Colors.red,
// ),
// );
// }
// }
//
// // Load all required dependencies for active mods
// void _loadRequiredDependencies() async {
// if (_activeMods.isEmpty) {
// setState(() {
// _statusMessage = 'No active mods to load dependencies for';
// });
// return;
// }
//
// setState(() {
// _isLoading = true;
// _statusMessage = 'Loading required dependencies...';
// _hasCycles = false;
// _cycleInfo = null;
// _incompatibleMods = [];
// _loadOrderErrors = null;
// });
//
// // Use a Future.delayed to allow the UI to update
// await Future.delayed(Duration.zero);
//
// try {
// final logger = Logger.instance;
// logger.info(
// 'Starting dependency resolution for ${_activeMods.length} active mods',
// );
//
// // Get current active mod count for comparison
// final initialActiveCount = modManager.activeMods.length;
//
// // Load required dependencies and get the load order
// final loadOrder = modManager.loadRequired();
//
// // Store any errors
// if (loadOrder.hasErrors) {
// setState(() {
// _loadOrderErrors = List<String>.from(loadOrder.errors);
// });
//
// logger.warning(
// 'Found ${loadOrder.errors.length} errors during dependency loading',
// );
// for (final error in loadOrder.errors) {
// logger.warning(' - $error');
// }
//
// // Check for cycles
// setState(() {
// _hasCycles = loadOrder.errors.any(
// (e) => e.contains('Cyclic dependency'),
// );
// if (_hasCycles) {
// // Extract cycle info from error message
// final cycleError = loadOrder.errors.firstWhere(
// (e) => e.contains('Cyclic dependency'),
// orElse: () => '',
// );
// logger.warning('Detected dependency cycle: $cycleError');
//
// if (cycleError.isNotEmpty) {
// // Extract cycle path from error message
// final startIndex = cycleError.indexOf(':');
// if (startIndex != -1) {
// final pathStr = cycleError.substring(startIndex + 1).trim();
// _cycleInfo = pathStr.split(' -> ');
// logger.info(
// 'Extracted cycle path: ${_cycleInfo!.join(" -> ")}',
// );
// }
// }
// }
// });
// } else {
// _loadOrderErrors = null;
// }
//
// // Check for incompatibilities
// _incompatibleMods = modManager.checkIncompatibilities(
// modManager.activeMods.keys.toList(),
// );
//
// if (_incompatibleMods.isNotEmpty) {
// logger.warning(
// 'Found ${_incompatibleMods.length} incompatible mod pairs:',
// );
// for (final pair in _incompatibleMods) {
// final mod1 = modManager.mods[pair[0]]?.name ?? pair[0];
// final mod2 = modManager.mods[pair[1]]?.name ?? pair[1];
// logger.warning(' - $mod1 is incompatible with $mod2');
// }
// }
//
// // Get sorted mods from the load order
// final List<Mod> sortedMods = [];
// for (final modId in loadOrder.loadOrder) {
// if (modManager.mods.containsKey(modId)) {
// sortedMods.add(modManager.mods[modId]!);
// }
// }
//
// // Calculate how many dependencies were added
// final newModsCount = modManager.activeMods.length - initialActiveCount;
//
// logger.info(
// 'Dependency loading complete. Enabled $newModsCount new dependencies.',
// );
// if (newModsCount > 0) {
// logger.info('Newly enabled dependencies:');
// final activeModIds = modManager.activeMods.keys.toList();
// for (int i = 0; i < newModsCount; i++) {
// final modId = activeModIds[initialActiveCount + i];
// logger.info(' - ${modManager.mods[modId]?.name ?? modId} ($modId)');
// }
// }
//
// setState(() {
// _activeMods = sortedMods;
// _isLoading = false;
// if (newModsCount > 0) {
// _statusMessage = 'Added $newModsCount required dependencies!';
// } else {
// _statusMessage = 'All dependencies are already loaded.';
// }
//
// if (_hasCycles) {
// _statusMessage += ' Warning: Dependency cycles were found and fixed.';
// }
// if (_incompatibleMods.isNotEmpty) {
// _statusMessage +=
// ' Warning: ${_incompatibleMods.length} incompatible mod pairs found.';
// }
// });
// } catch (e) {
// Logger.instance.error('Error during dependency loading: $e');
// setState(() {
// _isLoading = false;
// _statusMessage = 'Error loading dependencies: $e';
// });
// }
// }
//}
//
//// Page for troubleshooting problematic mods
//class TroubleshootingPage extends StatelessWidget {
// const TroubleshootingPage({super.key});
//
// @override
// Widget build(BuildContext context) {
// return Center(
// child: Column(
// mainAxisAlignment: MainAxisAlignment.center,
// children: [
// const Icon(Icons.build, size: 64),
// const SizedBox(height: 16),
// Text(
// 'Troubleshooting',
// style: Theme.of(context).textTheme.headlineMedium,
// ),
// const SizedBox(height: 16),
// Padding(
// padding: const EdgeInsets.symmetric(horizontal: 32.0),
// child: Text(
// 'Find problematic mods with smart batch testing.',
// style: Theme.of(context).textTheme.bodyLarge,
// textAlign: TextAlign.center,
// ),
// ),
// const SizedBox(height: 24),
// ElevatedButton(
// onPressed: () {
// // TODO: Implement troubleshooting wizard
// },
// child: const Text('Start Troubleshooting'),
// ),
// ],
// ),
// );
// }
//}
//