private void _exportDatButton_Click(object sender, RoutedEventArgs e)
        {
            // Show save file dialog
            var saveFileDialog = new System.Windows.Forms.SaveFileDialog
            {
                Filter = "Genie database files (*.dat)|*.dat",
                Title  = "Export DAT file..."
            };

            if (saveFileDialog.ShowDialog() != System.Windows.Forms.DialogResult.OK)
            {
                return;
            }

            // Catch errors on export process
            try
            {
                // Reload internal genie file, apply changes and save
                GenieLibrary.GenieFile exportFile =
                    new GenieLibrary.GenieFile(GenieLibrary.GenieFile.DecompressData(new IORAMHelper.RAMBuffer(_currentFileSelectionWindow.BaseGenieFilePath)));
                BalancingFile.WriteChangesToGenieFile(exportFile);
                IORAMHelper.RAMBuffer exportFileBuffer = new IORAMHelper.RAMBuffer();
                exportFile.WriteData(exportFileBuffer);
                GenieLibrary.GenieFile.CompressData(exportFileBuffer).Save(saveFileDialog.FileName);
            }
            catch (IOException ex)
            {
                // Error
                MessageBox.Show($"Unable to export modified DAT file: {ex.Message}");
            }
        }
        /// <summary>
        /// Creates a new file selection window.
        /// </summary>
        /// <param name="balancingFile">The current balancing file.</param>
        /// <param name="genieFile">The base DAT file.</param>
        public TestScenarioWindow(BalancingFile balancingFile, GenieFile genieFile)
        {
            // Remember parameters
            BalancingFile = balancingFile;

            // Initialize controls
            InitializeComponent();
            DataContext = this;

            // Fill list boxes
            Researches1 = new ObservableCollection <ResearchEntry>(BalancingFile.ResearchEntries.Select(r => new ResearchEntry(r.Key, false, r.Value.DisplayName)));
            Researches2 = new ObservableCollection <ResearchEntry>(BalancingFile.ResearchEntries.Select(r => new ResearchEntry(r.Key, false, r.Value.DisplayName)));
            Units       = BalancingFile.UnitEntries.ToDictionary(u => u.Key, u => $"[{u.Key}] {u.Value.DisplayName}");
            Duels       = new ObservableCollection <Duel>();
            Civs        = genieFile.Civs.Select((c, id) => new { c.Name, id }).Where(x => x.id > 0).ToDictionary(x => (short)x.id, x => x.Name.TrimEnd('\0'));
        }
        private void _loadFileButton_Click(object sender, RoutedEventArgs e)
        {
            // Create and show dialog
            var openFileDialog = new System.Windows.Forms.OpenFileDialog
            {
                FileName = _balancingFilePath,
                Filter   = "Balancing data file (*.balancing)|*.balancing",
                Title    = "Load balancing data file..."
            };

            if (openFileDialog.ShowDialog() != System.Windows.Forms.DialogResult.OK)
            {
                return;
            }

            // Catch IO errors
            try
            {
                // Load file
                BalancingFile      = new BalancingFile(_genieFile, openFileDialog.FileName, _languageFiles.ToArray(), _mappingFile);
                _balancingFilePath = openFileDialog.FileName;
            }
            catch (IOException ex)
            {
                // Error
                MessageBox.Show($"Unable to load given file: {ex.Message}");
            }
            catch (KeyNotFoundException)
            {
                // Error
                MessageBox.Show($"The given file and the current DAT are incompatible.");
            }

            // Set filterable lists
            UnitEntryList = new GenericCollectionView <KeyValuePair <short, UnitEntry> >(CollectionViewSource.GetDefaultView(_balancingFile.UnitEntries));
            OnPropertyChanged(nameof(UnitEntryList));

            // Update window title
            CurrentWindowTitle = WindowTitlePrefix + " [" + _balancingFilePath + "]";
        }
        private void _saveFileButton_Click(object sender, RoutedEventArgs e)
        {
            // Path selected?
            if (_balancingFilePath == "")
            {
                // Show "Save as..." dialog instead
                _saveFileAsButton_Click(sender, e);
                return;
            }

            // Catch IO errors
            try
            {
                // Save file
                BalancingFile.Save(_balancingFilePath);
            }
            catch (IOException ex)
            {
                // Error
                MessageBox.Show($"Unable to save balancing data: {ex.Message}");
            }
        }
        private void _loadDatButton_Click(object sender, RoutedEventArgs e)
        {
            // Show window (create new first, as closed windows cannot be reopened)
            _currentFileSelectionWindow = new FileSelectionWindow();
            if (!(_currentFileSelectionWindow.ShowDialog() ?? false))
            {
                return;
            }

            // Check whether genie file exists
            if (!File.Exists(_currentFileSelectionWindow.BaseGenieFilePath))
            {
                // Error
                MessageBox.Show($"The given genie file path is invalid: '{_currentFileSelectionWindow.BaseGenieFilePath}'");
                return;
            }

            // Catch errors
            _languageFiles = new List <string>();
            try
            {
                // Find language files
                if (File.Exists(_currentFileSelectionWindow.LanguageX1P1DllFilePath))
                {
                    _languageFiles.Add(_currentFileSelectionWindow.LanguageX1P1DllFilePath);
                }
                if (File.Exists(_currentFileSelectionWindow.LanguageX1DllFilePath))
                {
                    _languageFiles.Add(_currentFileSelectionWindow.LanguageX1DllFilePath);
                }
                if (File.Exists(_currentFileSelectionWindow.LanguageDllFilePath))
                {
                    _languageFiles.Add(_currentFileSelectionWindow.LanguageDllFilePath);
                }

                // Load genie file
                _genieFile = new GenieLibrary.GenieFile(GenieLibrary.GenieFile.DecompressData(new IORAMHelper.RAMBuffer(_currentFileSelectionWindow.BaseGenieFilePath)));
            }
            catch (IOException ex)
            {
                // Error
                MessageBox.Show($"Unable to load given genie file: {ex.Message}");
                return;
            }

            // Check for mapping requirement
            _mappingFile = null;
            if (!string.IsNullOrWhiteSpace(_currentFileSelectionWindow.MappingFilePath) && File.Exists(_currentFileSelectionWindow.MappingFilePath))
            {
                // Read mapping
                _mappingFile = new MappingFile(new IORAMHelper.RAMBuffer(_currentFileSelectionWindow.MappingFilePath));
                if (!_mappingFile.CheckCompabilityToGenieFile(_genieFile))
                {
                    MessageBox.Show($"The given mapping file does not match the given DAT file.");
                }
            }
            else if (_genieFile.Researches.Exists(r => r.Name.StartsWith("#BDep")))
            {
                MessageBox.Show($"This file was probably created using an editor that dynamically reassigns unit and research IDs.\nIt is strongly recommended to reload using a valid mapping file.");
            }

            // Create balancing data object
            BalancingFile      = new BalancingFile(_genieFile, _languageFiles.ToArray(), _mappingFile);
            _balancingFilePath = "";

            // Set filterable lists
            UnitEntryList = new GenericCollectionView <KeyValuePair <short, UnitEntry> >(CollectionViewSource.GetDefaultView(_balancingFile.UnitEntries));
            OnPropertyChanged(nameof(UnitEntryList));

            // Update child windows
            if (_projectileWindow != null)
            {
                _projectileWindow.GenieFile = _genieFile;
            }

            // Reset window title
            CurrentWindowTitle = WindowTitlePrefix;

            // Enable UI controls
            EnableEditorPanel = true;
        }