278 lines
9.5 KiB
Plaintext
278 lines
9.5 KiB
Plaintext
@using Fluxor
|
|
@using Koogle.Application.DTOs
|
|
@using Koogle.Application.Games
|
|
@using Koogle.Application.Games.Shit
|
|
@using Koogle.Application.Games.Training
|
|
@using Koogle.Application.Interfaces
|
|
@using Koogle.Domain.Enums
|
|
@using Koogle.Domain.Interfaces
|
|
@using Koogle.Web.Store.DayState
|
|
@using Koogle.Web.Store.GameState
|
|
@using MudBlazor
|
|
|
|
@inject IState<DayState> DayState
|
|
@inject IDispatcher Dispatcher
|
|
@inject GameDefinitionRegistry GameRegistry
|
|
|
|
<MudDialog>
|
|
<DialogContent>
|
|
<MudStack Spacing="4" Style="min-width: 400px; max-width: 600px;">
|
|
@* Step 1: Game Type Selection *@
|
|
<MudExpansionPanels MultiExpansion="false" Elevation="0">
|
|
<MudExpansionPanel Text="1. Spieltyp" IsExpanded="@(_currentStep == 1)">
|
|
<GameTypeSelector @bind-SelectedGameType="_selectedGameType"
|
|
OnGameDefinitionChanged="OnGameDefinitionChanged" />
|
|
</MudExpansionPanel>
|
|
|
|
@* Step 2: Participant Selection *@
|
|
<MudExpansionPanel Text="2. Teilnehmer"
|
|
IsExpanded="@(_currentStep == 3)"
|
|
Disabled="@(_selectedDefinition == null)">
|
|
<ParticipantSelector AvailableParticipants="@_availableParticipants"
|
|
@bind-SelectedParticipantIds="_selectedParticipantIds"
|
|
MinimumParticipants="1" />
|
|
</MudExpansionPanel>
|
|
|
|
@* Step 3: Game-specific Setup *@
|
|
<MudExpansionPanel Text="3. Spieleinstellungen"
|
|
IsExpanded="@(_currentStep == 2)"
|
|
Disabled="@(_selectedDefinition == null)">
|
|
@if (_selectedDefinition != null)
|
|
{
|
|
<DynamicComponent Type="@_selectedDefinition.SetupComponentType"
|
|
@ref="dynamicComponentRef"
|
|
Parameters="@GetSetupParameters()" />
|
|
}
|
|
else
|
|
{
|
|
<MudText Color="Color.Secondary">
|
|
Wähle zuerst einen Spieltyp aus.
|
|
</MudText>
|
|
}
|
|
</MudExpansionPanel>
|
|
|
|
@* Step 4: Common Options *@
|
|
@* <MudExpansionPanel Text="4. Grundeinstellungen"
|
|
IsExpanded="@(_currentStep == 4)"
|
|
Disabled="@(_selectedParticipantIds.Count == 0)">
|
|
<CommonSetupOptions @bind-ThrowMode="_throwMode"
|
|
@bind-ThrowsPerRound="_throwsPerRound"
|
|
@bind-ParticipantsMode="_participantsMode" />
|
|
</MudExpansionPanel> *@
|
|
</MudExpansionPanels>
|
|
|
|
@* Validation errors *@
|
|
@if (!string.IsNullOrEmpty(_validationError))
|
|
{
|
|
<MudAlert Severity="Severity.Error" Dense="true">
|
|
@_validationError
|
|
</MudAlert>
|
|
}
|
|
|
|
@* Game info summary *@
|
|
@if (CanStartGame())
|
|
{
|
|
<MudPaper Class="pa-3" Elevation="0" Style="background-color: var(--mud-palette-background-grey);">
|
|
<MudStack Spacing="1">
|
|
<MudText Typo="Typo.body2">
|
|
<strong>Spieltyp:</strong> @_selectedDefinition?.DisplayName
|
|
</MudText>
|
|
<MudText Typo="Typo.body2">
|
|
<strong>Teilnehmer:</strong> @_selectedParticipantIds.Count Spieler
|
|
</MudText>
|
|
<MudText Typo="Typo.body2">
|
|
<strong>Modus:</strong> @GetThrowModeLabel()
|
|
</MudText>
|
|
</MudStack>
|
|
</MudPaper>
|
|
}
|
|
</MudStack>
|
|
</DialogContent>
|
|
<DialogActions>
|
|
<MudButton OnClick="Cancel" Variant="Variant.Text">Abbrechen</MudButton>
|
|
<MudButton OnClick="StartGame"
|
|
Color="Color.Primary"
|
|
Variant="Variant.Filled"
|
|
Disabled="@(!CanStartGame() || _isStarting)"
|
|
StartIcon="@Icons.Material.Filled.PlayArrow">
|
|
@if (_isStarting)
|
|
{
|
|
<MudProgressCircular Size="Size.Small" Indeterminate="true" Class="mr-2" />
|
|
<span>Starte...</span>
|
|
}
|
|
else
|
|
{
|
|
<span>Spiel starten</span>
|
|
}
|
|
</MudButton>
|
|
</DialogActions>
|
|
</MudDialog>
|
|
|
|
@code {
|
|
private DynamicComponent? dynamicComponentRef;
|
|
|
|
/// <summary>
|
|
/// ID of the day to start the game for.
|
|
/// </summary>
|
|
[Parameter]
|
|
public Guid DayId { get; set; }
|
|
|
|
/// <summary>
|
|
/// Cascade parameter for the dialog instance.
|
|
/// </summary>
|
|
[CascadingParameter]
|
|
private IMudDialogInstance? MudDialog { get; set; }
|
|
|
|
// State
|
|
private int _currentStep = 1;
|
|
private string? _selectedGameType;
|
|
private IGameDefinition? _selectedDefinition;
|
|
private IReadOnlyList<DayParticipantDto> _availableParticipants = [];
|
|
private IReadOnlyList<Guid> _selectedParticipantIds = [];
|
|
// private object? _gameSpecificSetupOptions;
|
|
// private ThrowMode _throwMode = ThrowMode.Reposition;
|
|
// private int _throwsPerRound = 3;
|
|
// private ParticipantsMode _participantsMode = ParticipantsMode.GameLogic;
|
|
private string? _validationError;
|
|
private bool _isStarting;
|
|
|
|
protected override void OnInitialized()
|
|
{
|
|
// Get available participants from the selected day
|
|
var selectedDay = DayState.Value.SelectedDay;
|
|
if (selectedDay != null)
|
|
{
|
|
_availableParticipants = selectedDay.Participants;
|
|
// Pre-select all participants
|
|
_selectedParticipantIds = selectedDay.Participants.Select(p => p.PersonId).ToList();
|
|
}
|
|
}
|
|
|
|
private void OnGameDefinitionChanged(IGameDefinition? definition)
|
|
{
|
|
_selectedDefinition = definition;
|
|
// _gameSpecificSetupOptions = null;
|
|
_validationError = null;
|
|
|
|
if (definition != null)
|
|
{
|
|
_currentStep = 2;
|
|
}
|
|
}
|
|
|
|
private Dictionary<string, object> GetSetupParameters()
|
|
{
|
|
return new Dictionary<string, object>
|
|
{
|
|
["OnOptionsChanged"] = EventCallback.Factory.Create<object>(this, OnSetupOptionsChanged),
|
|
// ["InitialOptions"] = _gameSpecificSetupOptions!
|
|
};
|
|
}
|
|
|
|
private void OnSetupOptionsChanged(object options)
|
|
{
|
|
// _gameSpecificSetupOptions = options;
|
|
_validationError = null;
|
|
}
|
|
|
|
private bool CanStartGame()
|
|
{
|
|
if (_selectedDefinition == null)
|
|
return false;
|
|
|
|
if (_selectedParticipantIds.Count == 0)
|
|
return false;
|
|
|
|
return true;
|
|
}
|
|
|
|
private Task StartGame()
|
|
{
|
|
if (!CanStartGame() || _selectedDefinition == null)
|
|
return Task.CompletedTask;
|
|
|
|
_isStarting = true;
|
|
_validationError = null;
|
|
|
|
try
|
|
{
|
|
// Create typed setup model based on game type
|
|
IGameSetupModel? setup = CreateSetupModel(_selectedDefinition.Name);
|
|
|
|
// Validate setup options
|
|
var logicService = GameRegistry.GetLogicService(_selectedDefinition.Name);
|
|
var validationResult = logicService.ValidateSetup(setup);
|
|
|
|
if (!validationResult.IsValid)
|
|
{
|
|
_validationError = string.Join(", ", validationResult.Errors);
|
|
_isStarting = false;
|
|
return Task.CompletedTask;
|
|
}
|
|
|
|
// Create initial game model and setup
|
|
var playerIds = _selectedParticipantIds.ToArray();
|
|
|
|
|
|
var initialModel = logicService.CreateInitialModel(playerIds, setup);
|
|
|
|
// Dispatch start game action
|
|
var action = new StartGameAction(
|
|
DayId: DayId,
|
|
GameTypeName: _selectedDefinition.Name,
|
|
PlayerIds: playerIds,
|
|
ThrowMode: setup.ThrowMode,
|
|
ThrowsPerRound: setup.ThrowsPerRound,
|
|
ParticipantsMode: setup.ParticipantsMode,
|
|
InitialGameModel: initialModel,
|
|
Setup: setup);
|
|
|
|
Dispatcher.Dispatch(action);
|
|
|
|
// Close dialog
|
|
MudDialog?.Close(DialogResult.Ok(true));
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
_validationError = $"Fehler beim Starten: {ex.Message}";
|
|
}
|
|
finally
|
|
{
|
|
_isStarting = false;
|
|
}
|
|
|
|
return Task.CompletedTask;
|
|
}
|
|
|
|
private void Cancel()
|
|
{
|
|
MudDialog?.Cancel();
|
|
}
|
|
|
|
private string GetThrowModeLabel()
|
|
{
|
|
IGameSetupModel? setup = CreateSetupModel(_selectedDefinition.Name);
|
|
switch (setup.ThrowMode)
|
|
{
|
|
case ThrowMode.Reposition:
|
|
return "In die Vollen";
|
|
case ThrowMode.Decrease:
|
|
return "Abräumen";
|
|
}
|
|
|
|
return "";
|
|
}
|
|
|
|
private IGameSetupModel? CreateSetupModel(string gameTypeName)
|
|
{
|
|
var setupModel = (dynamicComponentRef.Instance as IGameSetupControl).GameSetupModel;
|
|
// setupModel.DayId = DayState.Value.Id;
|
|
// setupModel.KnownGameType = SetupState.Value.Game.GetType().Name;
|
|
// setupModel.Participants = PlayerIds;
|
|
return setupModel;
|
|
}
|
|
|
|
|
|
|
|
}
|