Files
BCSH1-TournamentApp/TournamentOrganizer/ViewModels/GamesViewModel.cs
T

276 lines
7.6 KiB
C#
Raw Normal View History

2026-05-06 10:19:19 +02:00
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Threading.Tasks;
using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
using Microsoft.EntityFrameworkCore;
using TournamentOrganizer.Models;
namespace TournamentOrganizer.ViewModels;
public partial class GamesViewModel : ViewModelBase
{
private readonly TournamentContext _context;
[ObservableProperty]
private ObservableCollection<GameDisplay> _games = [];
[ObservableProperty]
private GameDisplay? _selectedGame;
[ObservableProperty]
private string _gameName = string.Empty;
[ObservableProperty]
private string _gameDescription = string.Empty;
[ObservableProperty]
private RuleSetOption? _selectedS1RuleSet;
[ObservableProperty]
private int? _s1Groups;
[ObservableProperty]
private int? _s1GroupAdvances;
[ObservableProperty]
private RuleSetOption? _selectedS2RuleSet;
[ObservableProperty]
private string _filterGameName = string.Empty;
[ObservableProperty]
private bool _isEditing;
[ObservableProperty]
private string _statusMessage = string.Empty;
public ObservableCollection<RuleSetOption> S1RuleSetOptions { get; } = [];
public ObservableCollection<RuleSetOption> S2RuleSetOptions { get; } = [new RuleSetOption(null, "(None)")];
public bool ShowStage1GroupSettings => SelectedS2RuleSet?.Value != null;
public GamesViewModel()
{
_context = new TournamentContext();
foreach (var rs in Enum.GetValues<RuleSet>())
{
S1RuleSetOptions.Add(new RuleSetOption(rs, rs.ToDisplayName()));
S2RuleSetOptions.Add(new RuleSetOption(rs, rs.ToDisplayName()));
}
SelectedS1RuleSet = S1RuleSetOptions.First();
SelectedS2RuleSet = S2RuleSetOptions.First();
}
partial void OnSelectedS2RuleSetChanged(RuleSetOption? value)
{
OnPropertyChanged(nameof(ShowStage1GroupSettings));
if (value?.Value == null)
{
S1Groups = null;
S1GroupAdvances = null;
}
}
partial void OnFilterGameNameChanged(string value) => ApplyFilters();
private async void ApplyFilters()
{
await LoadGames();
}
public async Task LoadGames()
{
var allGames = await _context.Games
.Include(g => g.Tournaments)
.ThenInclude(t => t.Event)
.ToListAsync();
var filtered = allGames.AsEnumerable();
if (!string.IsNullOrWhiteSpace(FilterGameName))
{
var filter = FilterGameName.ToLower();
filtered = filtered.Where(g => g.Name.ToLower().Contains(filter));
}
Games.Clear();
foreach (var game in filtered)
{
Games.Add(new GameDisplay(game));
}
SelectedGame = null;
IsEditing = false;
}
[RelayCommand]
private async Task RefreshGames()
{
await LoadGames();
}
[RelayCommand]
private void CreateNewGame()
{
GameName = "New Game";
GameDescription = string.Empty;
SelectedS1RuleSet = S1RuleSetOptions.FirstOrDefault(o => o.Value == RuleSet.SingleElimination);
S1Groups = null;
S1GroupAdvances = null;
SelectedS2RuleSet = S2RuleSetOptions.First();
IsEditing = true;
SelectedGame = null;
StatusMessage = "Creating new game";
}
[RelayCommand]
private async Task SaveGame()
{
if (string.IsNullOrWhiteSpace(GameName))
{
StatusMessage = "Game name is required";
return;
}
Game? game;
if (SelectedGame != null && SelectedGame.Id > 0)
{
game = await _context.Games.FirstOrDefaultAsync(g => g.Id == SelectedGame.Id);
if (game == null)
{
StatusMessage = "Game not found";
return;
}
game.Name = GameName;
game.Description = GameDescription;
game.S1RuleSet = SelectedS1RuleSet!.Value!.Value;
game.S1Groups = ShowStage1GroupSettings ? S1Groups : null;
game.S1GroupAdvances = ShowStage1GroupSettings ? S1GroupAdvances : null;
game.S2RuleSet = SelectedS2RuleSet?.Value;
}
else
{
game = new Game
{
Name = GameName,
Description = GameDescription,
S1RuleSet = SelectedS1RuleSet!.Value!.Value,
S1Groups = ShowStage1GroupSettings ? S1Groups : null,
S1GroupAdvances = ShowStage1GroupSettings ? S1GroupAdvances : null,
S2RuleSet = SelectedS2RuleSet?.Value,
Tournaments = []
};
_context.Games.Add(game);
}
await _context.SaveChangesAsync();
StatusMessage = $"Game '{GameName}' saved successfully";
await LoadGames();
}
[RelayCommand]
private async Task DeleteGame()
{
if (SelectedGame == null || SelectedGame.Id == 0)
{
StatusMessage = "Select a game to delete";
return;
}
var game = await _context.Games.FirstOrDefaultAsync(g => g.Id == SelectedGame.Id);
if (game == null)
{
StatusMessage = "Game not found";
return;
}
_context.Games.Remove(game);
await _context.SaveChangesAsync();
StatusMessage = $"Game '{game.Name}' deleted";
await LoadGames();
}
partial void OnSelectedGameChanged(GameDisplay? value)
{
if (value == null)
{
IsEditing = false;
return;
}
GameName = value.Name;
GameDescription = value.Description;
SelectedS1RuleSet = S1RuleSetOptions.FirstOrDefault(o => o.Value == value.S1RuleSet) ?? S1RuleSetOptions.First();
S1Groups = value.S1Groups;
S1GroupAdvances = value.S1GroupAdvances;
SelectedS2RuleSet = S2RuleSetOptions.FirstOrDefault(o => o.Value == value.S2RuleSet) ?? S2RuleSetOptions.First();
IsEditing = true;
StatusMessage = $"Editing game '{value.Name}'";
}
}
public class GameDisplay
{
public int Id { get; set; }
public string Name { get; set; } = string.Empty;
public string Description { get; set; } = string.Empty;
public RuleSet S1RuleSet { get; set; }
public string S1RuleSetName => S1RuleSet.ToDisplayName();
public int? S1Groups { get; set; }
public int? S1GroupAdvances { get; set; }
public RuleSet? S2RuleSet { get; set; }
public string? S2RuleSetName => S2RuleSet?.ToDisplayName();
public List<string> AssociatedEvents { get; set; } = [];
public GameDisplay() { }
public GameDisplay(Game game)
{
Id = game.Id;
Name = game.Name;
Description = game.Description;
S1RuleSet = game.S1RuleSet;
S1Groups = game.S1Groups;
S1GroupAdvances = game.S1GroupAdvances;
S2RuleSet = game.S2RuleSet;
var events = new HashSet<string>();
if (game.Tournaments != null)
{
foreach (var t in game.Tournaments)
{
if (t.Event != null)
{
events.Add(t.Event.Name);
}
}
}
AssociatedEvents = events.ToList();
}
}
public class RuleSetOption
{
public RuleSet? Value { get; set; }
public string Label { get; set; } = string.Empty;
public RuleSetOption() { }
public RuleSetOption(RuleSet? value, string label)
{
Value = value;
Label = label;
}
public override string ToString() => Label;
}