//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 createState() => _ModManagerHomePageState(); //} // //class _ModManagerHomePageState extends State { // int _selectedIndex = 0; // // final List _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 createState() => _ModManagerPageState(); //} // //class _ModManagerPageState extends State { // // For all available mods (left panel) // List _availableMods = []; // // // For active mods (right panel) // List _activeMods = []; // // bool _isLoading = false; // String _statusMessage = ''; // int _totalModsFound = 0; // bool _skipFileCount = false; // bool _hasCycles = false; // List? _cycleInfo; // List> _incompatibleMods = []; // List? _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 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.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 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(''); // buffer.writeln(''); // buffer.writeln(' 1'); // // // Write active mods // buffer.writeln(' '); // for (final mod in _activeMods) { // buffer.writeln('
  • ${mod.id}
  • '); // logger.info(' - Adding mod to config: ${mod.name} (${mod.id})'); // } // buffer.writeln('
    '); // // // 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(' '); // for (final mod in expansions) { // buffer.writeln('
  • ${mod.id}
  • '); // logger.info(' - Adding expansion to config: ${mod.name} (${mod.id})'); // } // buffer.writeln('
    '); // // buffer.writeln('
    '); // // // 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.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 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'), // ), // ], // ), // ); // } //} //