//import 'package:flutter/material.dart'; //import 'package:rimworld_modman/logger.dart'; //import 'package:rimworld_modman/mod.dart'; // //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(path: modsRoot); // // // 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 = []; // // final TextEditingController _searchController = TextEditingController(); // String _searchQuery = ''; // // @override // void initState() { // super.initState(); // // Check if mods are already loaded in the global modManager // if (modManager.modsLoaded) { // _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 = modManager.loadingStatus; // _totalModsFound = modManager.totalModsFound; // }); // } // // @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), // // 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, // ), // ), // ), // // // Cycle warnings // if (_hasCycles && _cycleInfo != null) // Padding( // padding: const EdgeInsets.symmetric(horizontal: 8.0), // child: Text( // 'Dependency cycle detected: ${_cycleInfo!.join(" -> ")}', // style: const TextStyle(color: Colors.orange), // ), // ), // // // Incompatible mod warnings // if (_incompatibleMods.isNotEmpty) // Padding( // padding: const EdgeInsets.symmetric(horizontal: 8.0), // child: Row( // children: [ // const Icon(Icons.warning, color: Colors.orange, size: 16), // const SizedBox(width: 4), // Text( // '${_incompatibleMods.length} incompatible mod pairs found', // style: const TextStyle(color: Colors.orange), // ), // ], // ), // ), // // // 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 = []; // }); // // // Load mods // modManager // .loadWithConfig(skipFileCount: _skipFileCount) // .then((_) { // _loadModsFromGlobalState(); // }) // .catchError((error) { // setState(() { // _isLoading = false; // _statusMessage = 'Error loading mods: $error'; // }); // }); // } // // 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; // } // // // Update the mod's enabled status in the global mod manager // final updatedMod = Mod( // name: mod.name, // id: mod.id, // path: mod.path, // versions: mod.versions, // description: mod.description, // dependencies: mod.dependencies, // loadAfter: mod.loadAfter, // loadBefore: mod.loadBefore, // incompatibilities: mod.incompatibilities, // enabled: !mod.enabled, // size: mod.size, // isBaseGame: mod.isBaseGame, // isExpansion: mod.isExpansion, // ); // // // Update in the global mod manager // modManager.mods[mod.id] = updatedMod; // // // Update the UI // setState(() { // // Update in the available mods list // final index = _availableMods.indexWhere((m) => m.id == mod.id); // if (index >= 0) { // _availableMods[index] = updatedMod; // } // // // Update the active mods list // if (updatedMod.enabled) { // // Add to active mods if not already there // if (!_activeMods.any((m) => m.id == updatedMod.id)) { // _activeMods.add(updatedMod); // } // } else { // // Remove from active mods // _activeMods.removeWhere((m) => m.id == updatedMod.id); // } // // _statusMessage = // 'Mod "${mod.name}" ${updatedMod.enabled ? '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 = []; // }); // // // Use a Future.delayed to allow the UI to update // await Future.delayed(Duration.zero); // // try { // // Check for cycles first // final hardGraph = modManager.buildDependencyGraph(); // final cycle = modManager.detectCycle(hardGraph); // // if (cycle != null) { // setState(() { // _hasCycles = true; // _cycleInfo = cycle; // }); // } // // // Get incompatibilities // _incompatibleMods = modManager.findIncompatibilities(); // // // Get the sorted mods // final sortedMods = modManager.getModsInLoadOrder(); // // 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) { // 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 { // // Create a ConfigFile instance // final configFile = ConfigFile(path: configPath); // // // Load the current config // await configFile.load(); // // // Replace the mods with our active mods list // configFile.mods.clear(); // for (final mod in _activeMods) { // configFile.mods.add(mod); // } // // // Save the updated config // configFile.save(); // // setState(() { // _isLoading = false; // _statusMessage = 'Mod load order saved successfully!'; // }); // // // Show success message // ScaffoldMessenger.of(context).showSnackBar( // const SnackBar( // content: Text('Mod order saved to config'), // backgroundColor: Colors.green, // ), // ); // } catch (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, // ), // ); // } // } //} // //// 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'), // ), // ], // ), // ); // } //} //