JD2022-TU1/main/tools/modules/JD.Guinness.WPF.Module/ViewModel/APlatformChallengeViewModel.cs

226 lines
8.1 KiB
C#

using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.ComponentModel;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Forms;
using JD.Guinness.WPF.Module.Model;
using Plume.WPF.Mvvm;
using MessageBox = System.Windows.MessageBox;
using OpenFileDialog = Microsoft.Win32.OpenFileDialog;
using SaveFileDialog = Microsoft.Win32.SaveFileDialog;
namespace JD.Guinness.WPF.Module.ViewModel
{
public abstract class APlatformChallengeViewModel<T> : BindableBase
where T : APlatformChallenge
{
#region Properties
public DelegateCommand AddPlatformChallengeCommand { get; }
public DelegateCommand<IList> DuplicatePlatformChallengeCommand { get; }
public DelegateCommand<IList> RemovePlatformChallengeCommand { get; }
public AsyncDelegateCommand GenerateCommand { get; }
public GameViewModel Game { get; }
public DispatcherObservableCollection<T> PlatformChallenges { get; }
#endregion
#region Initialisation
protected APlatformChallengeViewModel(GameViewModel gameViewModel)
{
Game = gameViewModel ?? throw new ArgumentNullException(nameof(gameViewModel));
PlatformChallenges = new DispatcherObservableCollection<T>();
AddPlatformChallengeCommand = new DelegateCommand(OnAddPlatformChallenge, () => Game.IsAvailable);
DuplicatePlatformChallengeCommand = new DelegateCommand<IList>(OnDuplicatePlatformChallenge, c => Game.IsAvailable && c.Count > 0);
RemovePlatformChallengeCommand = new DelegateCommand<IList>(OnRemovePlatformChallenge, c => Game.IsAvailable && c.Count > 0);
GenerateCommand = new AsyncDelegateCommand(OnGenerate, () => Game.IsAvailable);
Game.GeneratePlatfromsAsked += types => types.Any(t => t == typeof(T)) ? OnGenerate() : Task.FromResult(false);
Game.Challenges.CollectionChanged += OnChallengesChanged;
OnChallengesChanged(null, new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add, Game.Challenges));
}
#endregion
#region Callbacks
private void OnChallengesChanged(object sender, NotifyCollectionChangedEventArgs e)
{
foreach (Challenge challenge in e.OldItems ?? Array.Empty<Challenge>())
{
challenge.PlatformChallengesChanged -= OnPlatformChallengesChanged;
}
RemovePlatformChallenges((e.OldItems ?? Array.Empty<Challenge>()).OfType<Challenge>().Select(c => c.GetPlatformChallenge<T>()).Where(c => c != null));
foreach (Challenge challenge in e.NewItems ?? Array.Empty<Challenge>())
{
challenge.PlatformChallengesChanged += OnPlatformChallengesChanged;
}
AddPlatformChallenges((e.NewItems ?? Array.Empty<Challenge>()).OfType<Challenge>().Select(c => c.GetPlatformChallenge<T>()).Where(c => c != null));
OnPlatformChallengeChanged(null, null);
}
private void OnPlatformChallengesChanged(object sender, NotifyCollectionChangedEventArgs e)
{
RemovePlatformChallenges((e.OldItems ?? Array.Empty<T>()).OfType<T>());
AddPlatformChallenges((e.NewItems ?? Array.Empty<T>()).OfType<T>());
OnPlatformChallengeChanged(null, null);
}
private void OnAddPlatformChallenge()
{
Challenge challenge = new Challenge();
challenge.GetOrAddPlatformChallenge<T>();
Game.Challenges.Add(challenge);
}
private void OnRemovePlatformChallenge(IList platformChallenges)
{
if (MessageBox.Show("Are you sure you want to remove this platform data?", "Remove platform data", MessageBoxButton.YesNo, MessageBoxImage.Question) == MessageBoxResult.Yes)
{
foreach (T platformChallenge in platformChallenges.OfType<T>().ToList())
{
platformChallenge.Remove();
platformChallenge.Challenge.NotifyPlatformChallenges();
}
}
}
private void OnDuplicatePlatformChallenge(IList platformChallenges)
{
foreach (T platformChallenge in platformChallenges.OfType<T>())
{
Challenge challenge = new Challenge()
{
Name = platformChallenge.Challenge.Name,
Objective = platformChallenge.Challenge.Objective
};
challenge.CustomData.Add(platformChallenge.CustomData.Values);
Game.Challenges.Add(DuplicatePlatFormChallengeInto(platformChallenge, challenge).Challenge);
}
}
protected virtual void OnPlatformChallengeChanged(object target, PropertyChangedEventArgs args)
{ }
protected abstract Task OnGenerate();
#endregion
#region Methods
private void AddPlatformChallenges(IEnumerable<T> platformChallenges)
{
foreach (T platformChallenge in platformChallenges)
{
PlatformChallenges.Add(platformChallenge);
platformChallenge.PropertyChanged += OnPlatformChallengeChanged;
}
}
private void RemovePlatformChallenges(IEnumerable<T> platformChallenges)
{
foreach (T platformChallenge in platformChallenges)
{
PlatformChallenges.Remove(platformChallenge);
platformChallenge.PropertyChanged -= OnPlatformChallengeChanged;
}
}
protected void SaveFile(string title, string filter, Action<string> setter)
{
SaveFileDialog dialog = new SaveFileDialog
{
Title = title,
Filter = filter,
InitialDirectory = Game.Settings.WorkspacePath,
OverwritePrompt = false
};
if (dialog.ShowDialog() is true)
{
setter(dialog.FileName);
}
}
protected void SelectFile(string title, string path, string filter, Action<string> setter)
{
OpenFileDialog dialog = new OpenFileDialog
{
Title = title,
Filter = filter,
InitialDirectory = path,
Multiselect = false
};
if (dialog.ShowDialog() is true)
{
setter(dialog.FileName);
}
}
protected void SelectFolder(string title, string path, Action<string> setter)
{
FolderBrowserDialog dialog = new FolderBrowserDialog
{
Description = title,
SelectedPath = path,
ShowNewFolderButton = true
};
if (dialog.ShowDialog() == DialogResult.OK)
{
setter(dialog.SelectedPath);
}
}
protected void SetImageFromId(string path, Action<T, string> setter)
{
FolderBrowserDialog dialog = new FolderBrowserDialog
{
Description = "Select the folder contaning the images",
SelectedPath = path,
ShowNewFolderButton = false
};
if (dialog.ShowDialog() == DialogResult.OK)
{
Dictionary<int, string> files = new Dictionary<int, string>();
foreach (string file in Directory.GetFiles(dialog.SelectedPath, "*.png"))
{
if (int.TryParse(Path.GetFileNameWithoutExtension(file), out int id))
{
files[id] = file;
}
}
foreach (T platformChallenge in PlatformChallenges)
{
if (files.TryGetValue(platformChallenge.Id, out string file))
{
setter(platformChallenge, file);
}
}
}
}
protected abstract T DuplicatePlatFormChallengeInto(T platformChallenge, Challenge challenge);
#endregion
}
}