using System.Collections.Generic;
using System.ComponentModel;
using System.IO;
using System.Threading.Tasks;
using MPF.Frontend.ComboBoxItems;
using MPF.Frontend.Tools;
using SabreTools.RedumpLib.Data;
namespace MPF.Frontend.ViewModels
{
///
/// Constructor
///
public class CheckDumpViewModel : INotifyPropertyChanged
{
#region Fields
///
/// Access to the current options
///
public Options Options
{
get => _options;
}
private readonly Options _options;
///
/// Indicates if SelectionChanged events can be executed
///
public bool CanExecuteSelectionChanged { get; private set; } = false;
///
public event PropertyChangedEventHandler? PropertyChanged;
#endregion
#region Properties
///
/// Currently selected system value
///
public RedumpSystem? CurrentSystem
{
get => _currentSystem;
set
{
_currentSystem = value;
TriggerPropertyChanged(nameof(CurrentSystem));
}
}
private RedumpSystem? _currentSystem;
///
/// Indicates the status of the system type combo box
///
public bool SystemTypeComboBoxEnabled
{
get => _systemTypeComboBoxEnabled;
set
{
_systemTypeComboBoxEnabled = value;
TriggerPropertyChanged(nameof(SystemTypeComboBoxEnabled));
}
}
private bool _systemTypeComboBoxEnabled;
///
/// Currently selected media type value
///
public MediaType? CurrentMediaType
{
get => _currentMediaType;
set
{
_currentMediaType = value;
TriggerPropertyChanged(nameof(CurrentMediaType));
}
}
private MediaType? _currentMediaType;
///
/// Indicates the status of the media type combo box
///
public bool MediaTypeComboBoxEnabled
{
get => _mediaTypeComboBoxEnabled;
set
{
_mediaTypeComboBoxEnabled = value;
TriggerPropertyChanged(nameof(MediaTypeComboBoxEnabled));
}
}
private bool _mediaTypeComboBoxEnabled;
///
/// Currently provided input path
///
public string? InputPath
{
get => _inputPath;
set
{
_inputPath = value;
TriggerPropertyChanged(nameof(InputPath));
}
}
private string? _inputPath;
///
/// Indicates the status of the input path text box
///
public bool InputPathTextBoxEnabled
{
get => _inputPathTextBoxEnabled;
set
{
_inputPathTextBoxEnabled = value;
TriggerPropertyChanged(nameof(InputPathTextBoxEnabled));
}
}
private bool _inputPathTextBoxEnabled;
///
/// Indicates the status of the input path browse button
///
public bool InputPathBrowseButtonEnabled
{
get => _inputPathBrowseButtonEnabled;
set
{
_inputPathBrowseButtonEnabled = value;
TriggerPropertyChanged(nameof(InputPathBrowseButtonEnabled));
}
}
private bool _inputPathBrowseButtonEnabled;
///
/// Currently selected dumping program
///
public InternalProgram CurrentProgram
{
get => _currentProgram;
set
{
_currentProgram = value;
TriggerPropertyChanged(nameof(CurrentProgram));
}
}
private InternalProgram _currentProgram;
///
/// Indicates the status of the dumping program combo box
///
public bool DumpingProgramComboBoxEnabled
{
get => _dumpingProgramComboBoxEnabled;
set
{
_dumpingProgramComboBoxEnabled = value;
TriggerPropertyChanged(nameof(DumpingProgramComboBoxEnabled));
}
}
private bool _dumpingProgramComboBoxEnabled;
///
/// Indicates the status of the check dump button
///
public bool CheckDumpButtonEnabled
{
get => _checkDumpButtonEnabled;
set
{
_checkDumpButtonEnabled = value;
TriggerPropertyChanged(nameof(CheckDumpButtonEnabled));
}
}
private bool _checkDumpButtonEnabled;
///
/// Indicates the status of the cancel button
///
public bool CancelButtonEnabled
{
get => _cancelButtonEnabled;
set
{
_cancelButtonEnabled = value;
TriggerPropertyChanged(nameof(CancelButtonEnabled));
}
}
private bool _cancelButtonEnabled;
#endregion
#region List Properties
///
/// Current list of supported media types
///
public List>? MediaTypes
{
get => _mediaTypes;
set
{
_mediaTypes = value;
TriggerPropertyChanged(nameof(MediaTypes));
}
}
private List>? _mediaTypes;
///
/// Current list of supported system profiles
///
public List Systems
{
get => _systems;
set
{
_systems = value;
TriggerPropertyChanged(nameof(Systems));
}
}
private List _systems;
///
/// List of available internal programs
///
public List> InternalPrograms
{
get => _internalPrograms;
set
{
_internalPrograms = value;
TriggerPropertyChanged(nameof(InternalPrograms));
}
}
private List> _internalPrograms;
#endregion
///
/// Constructor for pure view model
///
public CheckDumpViewModel()
{
_options = OptionsLoader.LoadFromConfig();
_internalPrograms = [];
_inputPath = string.Empty;
_systems = [];
SystemTypeComboBoxEnabled = true;
InputPathTextBoxEnabled = true;
InputPathBrowseButtonEnabled = true;
MediaTypeComboBoxEnabled = true;
DumpingProgramComboBoxEnabled = true;
CheckDumpButtonEnabled = false;
CancelButtonEnabled = true;
MediaTypes = [];
Systems = RedumpSystemComboBoxItem.GenerateElements();
InternalPrograms = [];
PopulateMediaType();
PopulateInternalPrograms();
EnableEventHandlers();
}
#region Property Updates
///
/// Trigger a property changed event
///
private void TriggerPropertyChanged(string propertyName)
{
// Disable event handlers temporarily
bool cachedCanExecuteSelectionChanged = CanExecuteSelectionChanged;
DisableEventHandlers();
// If the property change event is initialized
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
// Reenable event handlers, if necessary
if (cachedCanExecuteSelectionChanged) EnableEventHandlers();
}
#endregion
#region UI Commands
///
/// Change the currently selected system
///
public void ChangeSystem()
{
PopulateMediaType();
CheckDumpButtonEnabled = ShouldEnableCheckDumpButton();
}
///
/// Change the currently selected media type
///
public void ChangeMediaType()
{
CheckDumpButtonEnabled = ShouldEnableCheckDumpButton();
}
///
/// Change the currently selected dumping program
///
public void ChangeDumpingProgram()
{
CheckDumpButtonEnabled = ShouldEnableCheckDumpButton();
}
///
/// Change the currently selected input path
///
public void ChangeInputPath()
{
CheckDumpButtonEnabled = ShouldEnableCheckDumpButton();
}
#endregion
#region UI Control
///
/// Enables all UI elements that should be enabled
///
private void EnableUIElements()
{
SystemTypeComboBoxEnabled = true;
InputPathTextBoxEnabled = true;
InputPathBrowseButtonEnabled = true;
DumpingProgramComboBoxEnabled = true;
PopulateMediaType();
CheckDumpButtonEnabled = ShouldEnableCheckDumpButton();
CancelButtonEnabled = true;
}
///
/// Disables all UI elements
///
private void DisableUIElements()
{
SystemTypeComboBoxEnabled = false;
InputPathTextBoxEnabled = false;
InputPathBrowseButtonEnabled = false;
MediaTypeComboBoxEnabled = false;
DumpingProgramComboBoxEnabled = false;
CheckDumpButtonEnabled = false;
CancelButtonEnabled = false;
}
#endregion
#region Population
///
/// Populate media type according to system type
///
private void PopulateMediaType()
{
// Disable other UI updates
bool cachedCanExecuteSelectionChanged = CanExecuteSelectionChanged;
DisableEventHandlers();
if (CurrentSystem != null)
{
var mediaTypeValues = CurrentSystem.MediaTypes();
int index = mediaTypeValues.FindIndex(m => m == CurrentMediaType);
MediaTypes = mediaTypeValues.ConvertAll(m => new Element(m ?? MediaType.NONE));
MediaTypeComboBoxEnabled = MediaTypes.Count > 1;
CurrentMediaType = (index > -1 ? MediaTypes[index] : MediaTypes[0]);
}
else
{
MediaTypeComboBoxEnabled = false;
MediaTypes = null;
CurrentMediaType = null;
}
// Reenable event handlers, if necessary
if (cachedCanExecuteSelectionChanged) EnableEventHandlers();
}
///
/// Populate media type according to system type
///
private void PopulateInternalPrograms()
{
// Disable other UI updates
bool cachedCanExecuteSelectionChanged = CanExecuteSelectionChanged;
DisableEventHandlers();
// Get the current internal program
InternalProgram internalProgram = Options.InternalProgram;
// Create a static list of supported Check programs, not everything
var internalPrograms = new List { InternalProgram.Redumper, InternalProgram.Aaru, InternalProgram.DiscImageCreator, InternalProgram.CleanRip, InternalProgram.PS3CFW, InternalProgram.UmdImageCreator, InternalProgram.XboxBackupCreator };
InternalPrograms = internalPrograms.ConvertAll(ip => new Element(ip));
// Select the current default dumping program
int currentIndex = InternalPrograms.FindIndex(m => m == internalProgram);
CurrentProgram = (currentIndex > -1 ? InternalPrograms[currentIndex].Value : InternalPrograms[0].Value);
// Reenable event handlers, if necessary
if (cachedCanExecuteSelectionChanged) EnableEventHandlers();
}
#endregion
#region UI Functionality
private bool ShouldEnableCheckDumpButton()
{
return CurrentSystem != null && CurrentMediaType != null && !string.IsNullOrEmpty(InputPath);
}
///
/// Enable all textbox and combobox event handlers
///
private void EnableEventHandlers()
{
CanExecuteSelectionChanged = true;
}
///
/// Disable all textbox and combobox event handlers
///
private void DisableEventHandlers()
{
CanExecuteSelectionChanged = false;
}
#endregion
#region MPF.Check
///
/// Performs MPF.Check functionality
///
/// An error message if failed, otherwise string.Empty/null
public async Task CheckDump(ProcessUserInfoDelegate processUserInfo)
{
if (string.IsNullOrEmpty(InputPath))
return "Invalid Input path";
if (!File.Exists(InputPath!.Trim('"')))
return "Input Path is not a valid file";
// Disable UI while Check is running
DisableUIElements();
bool cachedCanExecuteSelectionChanged = CanExecuteSelectionChanged;
DisableEventHandlers();
// Populate an environment
var env = new DumpEnvironment(Options,
Path.GetFullPath(InputPath.Trim('"')),
null,
CurrentSystem,
CurrentMediaType,
CurrentProgram,
parameters: null);
// Finally, attempt to do the output dance
var result = await env.VerifyAndSaveDumpOutput(processUserInfo: processUserInfo);
// Reenable UI and event handlers, if necessary
EnableUIElements();
if (cachedCanExecuteSelectionChanged)
EnableEventHandlers();
return result.Message;
}
#endregion
}
}