Files
GreadyPoang/GreadyPoang.ViewModelLayer/ViewModelClasses/RoundRunningViewModel.cs

364 lines
12 KiB
C#

using Common.Library;
using CommunityToolkit.Maui;
using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
using GreadyPoang.DataLayer;
using GreadyPoang.EntityLayer;
using GreadyPoang.Services;
using System.Collections.ObjectModel;
using System.Diagnostics;
using System.Windows.Input;
namespace GreadyPoang.ViewModelLayer;
public partial class RoundRunningViewModel : ObservableObject
{
public event EventHandler RebuildRequested;
public ICommand OnLoadedCommand { get; }
public RoundRunningViewModel() : base()
{
}
public RoundRunningViewModel(
IRepository<GameRound> roundsRepo,
IRepository<GamePoint> pointsRepo,
IMethodSharingService<Participant> sharingService,
ICombinedRepository combined,
IObjectMessageService objectMessage,
IPopupService popupService,
IPopupEventHub popupEvent
) : base()
{
_roundsRepo = roundsRepo;
_pointsRepo = pointsRepo;
_sharingService = sharingService;
_combined = combined;
_objectMessage = objectMessage;
_popupService = popupService;
_popupEvent = popupEvent;
RoundElements = new ObservableCollection<RoundBuilderElement>();
BuilderObject = new();
_popupEvent.InfoPopupCloseRequested += infoPopupViewModel_ClosePopupRequested;
//PopupVisad = false;
OnLoadedCommand = new AsyncRelayCommand(OnLoadedAsync, () => true);
}
private readonly IRepository<GameRound>? _roundsRepo;
private readonly IRepository<GamePoint> _pointsRepo;
private readonly IMethodSharingService<Participant> _sharingService;
private readonly ICombinedRepository _combined;
private readonly IObjectMessageService _objectMessage;
private readonly IPopupService _popupService;
private readonly IPopupEventHub _popupEvent;
[ObservableProperty]
private ObservableCollection<RoundBuilderElement> roundElements;
[ObservableProperty]
private Collection<PlayerColumn> playerColumns;
[ObservableProperty]
private RoundBuilderElement builderObject;
public ObservableCollection<ScoreColumn> ScoreColumns { get; } = new ObservableCollection<ScoreColumn>();
private string _activePopupId;
//public bool PopupVisad { get; set; }
private async Task OnLoadedAsync()
{
await Get();
}
public async Task Get()
{
if (_objectMessage.CurrentGroup != null)
{
//CurrentGroup är satt från RoundStarting ViewModel
Debug.WriteLine($"Chosen round: {_objectMessage.CurrentGroup.GameRoundId}");
if (RoundElements.Count > 0)
{
RoundElements.Clear();
}
foreach (var item in _objectMessage.CurrentGroup.Elements)
{
RoundElements.Add(item);
}
// Räkna ut vem som är nästa spelare
var nxt = nextPlayerElement();
// Aktuell spelare sätts som BuilderObject
BuilderObject.ParticipantName = _objectMessage.CurrentGroup.Elements[nxt].ParticipantName;
BuilderObject.GameRoundId = _objectMessage.CurrentGroup.GameRoundId;
BuilderObject.ParticipantId = _objectMessage.CurrentGroup.Elements[nxt].ParticipantId;
BuilderObject.Status = _objectMessage.CurrentGroup.Status;
// Alla poängposter från samtliga spelare i rundan samlas ihop och fördelas per deltagare
var localElements = _combined.roundBuilderElementsTotalById(_objectMessage.CurrentGroup.GameRoundId);
FillupResultTable(localElements);
foreach (var col in PlayerColumns)
{
RoundElements.FirstOrDefault(e => e.ParticipantId == col.PlayerId).GameRegPoints = col.PlayerPoints;
}
//TriggerRebuild();
BuildScore(playerColumns);
}
}
[RelayCommand]
private void StoreAndHandlePointsAsync()
{
var game = _roundsRepo.Get(BuilderObject.GameRoundId).GetAwaiter().GetResult();
var regNr = RoundElements.Count > 0 ? RoundElements.Max(e => e.GameRoundRegNr) + 1 : 1;
if (game.GameStatus == GamePointStatus.New)
{
game.GameStatus = GamePointStatus.InProgress;
regNr = regNr == 0 ? 1 : regNr;
_roundsRepo.Save(game);
}
BuilderObject.Status = game.GameStatus;
var points = BuilderObject.GameRegPoints;
var newPoint = new GamePoint
{
ParticipantId = BuilderObject.ParticipantId,
GameRoundId = BuilderObject.GameRoundId,
GameDate = DateTime.Now,
GameRoundRegNr = regNr,
GameRegPoints = points
};
var pointId = _pointsRepo?.Save(newPoint).GetAwaiter().GetResult();
// Uppdatera listan med element
var tmpElements = _combined.roundBuilderElementsDbById(BuilderObject.GameRoundId);
RoundElements.Clear();
foreach (var item in tmpElements)
{
item.Status = GamePointStatus.InProgress;
RoundElements.Add(item);
}
// Uppdatera spelaren som skall spela nästa
var nxt = nextPlayerElement();
BuilderObject.GameRegPoints = 0;
BuilderObject.ParticipantName = RoundElements[nxt].ParticipantName;
BuilderObject.ParticipantId = RoundElements[nxt].ParticipantId;
BuilderObject.GameRoundId = RoundElements[0].GameRoundId;
var localElements = _combined.roundBuilderElementsTotalById(BuilderObject.GameRoundId);
FillupResultTable(localElements);
foreach (var col in PlayerColumns)
{
RoundElements.FirstOrDefault(e => e.ParticipantId == col.PlayerId).GameRegPoints = col.PlayerPoints;
}
// TriggerRebuild();
BuildScore(playerColumns);
Shell.Current.GoToAsync("..").GetAwaiter().GetResult();
}
private int nextPlayerElement()
{
for (int i = 0; i < RoundElements.Count; i++)
{
if (RoundElements[i].GameRoundRegNr == -1 ||
(i > 0 && (RoundElements[i - 1].GameRoundRegNr > RoundElements[i].GameRoundRegNr)) ||
(i == 0 && RoundElements[i].GameRoundRegNr < RoundElements[RoundElements.Count - 1].GameRoundRegNr))
return i;
}
return -1;
}
private void Show_a_Popup(string ppName, string ppTitle, string ppMessage)
{
//if (!PopupVisad)
//{
var queryAttributes = new Dictionary<string, object>
{
[nameof(InfoPopupViewModel.Title)] = ppTitle,
[nameof(InfoPopupViewModel.Message)] = ppMessage,
[nameof(InfoPopupViewModel.Name)] = ppName,
};
_popupService.ShowPopup<InfoPopupViewModel>(
Shell.Current,
options: PopupOptions.Empty,
shellParameters: queryAttributes);
_activePopupId = LatestPopup.valueGuid;
//}
}
private async void infoPopupViewModel_ClosePopupRequested(object? sender, PopupCloseEventArgs e)
{
if (e.PopupId != _activePopupId)
{
return;
}
//PopupVisad = true;
await _popupService.ClosePopupAsync(Shell.Current);
}
private void FillupResultTable(IEnumerable<RoundBuilderElement> elements)
{
if (PlayerColumns != null)
{
PlayerColumns.Clear();
}
else
{
PlayerColumns = new Collection<PlayerColumn>();
}
// if (elements.Any(g => g.GameRegPoints > 0))
if (BuilderObject.Status == GamePointStatus.InProgress)
{
PlayerColumn player = new PlayerColumn();
var regMax = elements.Max(e => e.GameRoundRegNr);
var existingWinning = elements.FirstOrDefault(e => e.Status == GamePointStatus.Winning);
foreach (var element in elements)
{
player = PlayerColumns.FirstOrDefault(p => p.PlayerId == element.ParticipantId)!;
if (player == null)
{
player = new PlayerColumn
{
PlayerName = element.ParticipantName,
PlayerId = element.ParticipantId,
PlayerPoints = 0
};
}
if (element.GameRegPoints > 0)
{
player.Values.Add(element.GameRegPoints.ToString());
var playerPointsOld = player.PlayerPoints;
player.PlayerPoints += element.GameRegPoints;
if (player.PlayerPoints > 10000)
{
HandlePlayerReachedWinningThreshold(player, regMax, element, playerPointsOld, existingWinning);
}
}
if (!PlayerColumns.Contains(player))
{
PlayerColumns.Add(player);
}
}
}
else
{
Random slumper = new Random();
foreach (var element in elements)
{
var player = new PlayerColumn
{
PlayerName = element.ParticipantName,
PlayerId = element.ParticipantId,
PlayerPoints = 0
};
for (int i = 0; i < slumper.Next(6); i++)
{
player.Values.Add(slumper.Next(1, 10).ToString());
}
PlayerColumns.Add(player);
}
}
}
private void HandlePlayerReachedWinningThreshold(
PlayerColumn player,
int regMax,
RoundBuilderElement element,
int playerPointsOld,
RoundBuilderElement existingWinning
)
{
var nextPlayer = RoundElements[AfterNext()].ParticipantName;
Debug.WriteLine($"Spelare {nextPlayer} samma som {player.PlayerName} ???.");
// Om det redan finns en vinnare, sätt dennes status tillbaka till InProgress, kanske
var winner = RoundElements.FirstOrDefault(e => e.ParticipantId == player.PlayerId);
var oldStatus = winner.Status;
winner.Status = GamePointStatus.Winning;
if (playerPointsOld < 10000 && oldStatus != winner.Status && regMax == element.GameRoundRegNr)
{
//PopupVisad = false;
Show_a_Popup(
player.PlayerName,
"Se upp för denne spelare !",
$"Du har nått en poängnivå över 10000 ({player.PlayerPoints})\r" +
$"Alla övriga får nu en chans att överträffa\r" +
$"om någon kommer till samma poäng som\r" +
$"{player.PlayerName}\r" +
$"får hen försvara sig med nytt kast\r" +
$"Om kastet inte blir godkänt (ger poäng)\r" +
$"Vinner den upphinnande spelaren"
);
}
}
private int AfterNext()
{
var comingUp = nextPlayerElement();
if (RoundElements.Count - 1 == comingUp)
{
return 0;
}
return comingUp;
}
public void BuildScore(IEnumerable<PlayerColumn> columns)
{
ScoreColumns.Clear();
foreach (var column in columns)
{
var scoreColumn = new ScoreColumn
{
PlayerName = column.PlayerName
};
scoreColumn.Cells.Add(new ScoreCell
{
Text = column.PlayerName,
IsHeader = true
});
foreach (var value in System.Linq.Enumerable.Reverse(column.Values))
{
scoreColumn.Cells.Add(new ScoreCell
{
Text = value,
IsHeader = false
});
}
ScoreColumns.Add(scoreColumn);
}
}
}