KoogleV4/GameHandler/GameStateHandler.cs

210 lines
7.0 KiB
C#

using GameModel;
using GameModel.Contract;
using GameModel.Contracts;
using Microsoft.VisualBasic.FileIO;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace GameHandler
{
class GameStateHandlerItem<T>
{
internal Guid GameStateId;
internal bool Saved;
internal T Data;
public GameStateHandlerItem(Guid gameStateId, T data)
{
GameStateId = gameStateId;
Data = data;
}
}
public class GameStateHandler
{
private Guid _gameStateId;
private List<GameStateHandlerItem<GameState>> gameStates = new List<GameStateHandlerItem<GameState>>();
private List<GameStateHandlerItem<ExpenseModel>> expenseModels = new List<GameStateHandlerItem<ExpenseModel>>();
private List<GameStateHandlerItem<PlayerExpense>> memberExpenses = new List<GameStateHandlerItem<PlayerExpense>>();
private List<GameStateHandlerItem<GameState>> redoableGameStates = new List<GameStateHandlerItem<GameState>>();
private List<GameStateHandlerItem<ExpenseModel>> redoableExpenseModels = new List<GameStateHandlerItem<ExpenseModel>>();
private List<GameStateHandlerItem<PlayerExpense>> redoableMeberExpenses = new List<GameStateHandlerItem<PlayerExpense>>();
private IGameRepository _gameRepository;
private IExpenseRepository _expenseRepository;
public GameStateHandler(IGameRepository gameRepository, IExpenseRepository expenseRepository)
{
_gameRepository = gameRepository;
_expenseRepository = expenseRepository;
}
public ExpenseModel ExpenseModel
{
get
{
var res = expenseModels.LastOrDefault();
if (res != null)
{
return res.Data;
}
return null;
}
}
public GameState GameState
{
get
{
var res = gameStates.LastOrDefault();
if (res != null)
{
return res.Data;
}
return null;
}
}
internal async Task Add(ExpenseModel expenseModel)
{
if (ExpenseModel != null)
{
if (!expenseModel.Equals(ExpenseModel))
{
expenseModels.Add(new GameStateHandlerItem<ExpenseModel>(_gameStateId, expenseModel));
}
}
else
{
expenseModels.Add(new GameStateHandlerItem<ExpenseModel>(_gameStateId, expenseModel));
}
}
public async Task Save()
{
await DeleteRedoableStates(); // first delete undone items - otherwise ID is not unique in DB
var gameState = gameStates.FirstOrDefault(_ => _.GameStateId == _gameStateId);
await Save(gameState);
var expenseModelItem = expenseModels.FirstOrDefault(_ => _.GameStateId == _gameStateId);
if (expenseModelItem != null)
{
var expenseModel = expenseModelItem.Data;
foreach (var memberExpense in expenseModel.MemberExpenses.Where(_ => _.GamestateId == _gameStateId))
{
var item = new GameStateHandlerItem<PlayerExpense>(memberExpense.GamestateId, memberExpense);
memberExpenses.Add(item);
await Save(item);
}
}
}
private async Task DeleteRedoableStates()
{
if (redoableGameStates.Count > 0)
{
await _gameRepository.Delete(redoableGameStates.Select(_ => _.Data));
redoableGameStates.Clear();
}
if (redoableMeberExpenses.Count > 0)
{
// wird über fremdschlüssel gelöscht
//await _expenseRepository.Delete(redoableMeberExpenses.Select(_ => _.Data));
redoableMeberExpenses.Clear();
}
redoableExpenseModels.Clear();
}
internal async Task Add(GameState newState)
{
if (!newState.Equals(GameState))
{
_gameStateId = newState.Id;
var item = new GameStateHandlerItem<GameState>(_gameStateId, newState with { Counter = gameStates.Count + 1 });
gameStates.Add(item);
}
}
private async Task Save(GameStateHandlerItem<PlayerExpense> item)
{
await _expenseRepository.Save(item.Data);
}
private async Task Save(GameStateHandlerItem<GameState> item)
{
await _gameRepository.Save(item.Data);
}
public GameState Redo()
{
if (gameStates.Count == 0)
{
return null;
}
if (redoableGameStates.Count > 0)
{
var redoId = redoableGameStates.Last().GameStateId;
gameStates.AddRange(redoableGameStates.Where(_ => _.GameStateId == redoId));
expenseModels.AddRange(redoableExpenseModels.Where(_ => _.GameStateId == redoId));
memberExpenses.AddRange(redoableMeberExpenses.Where(_ => _.GameStateId == redoId));
redoableGameStates.RemoveAll(_ => _.GameStateId == redoId);
redoableExpenseModels.RemoveAll(_ => _.GameStateId == redoId);
redoableMeberExpenses.RemoveAll(_ => _.GameStateId == redoId);
}
_gameStateId = gameStates.Last().GameStateId;
return GameState;
}
public GameState Undo()
{
if (gameStates.Count <= 1)
{
return null;
}
redoableGameStates.AddRange(gameStates.Where(_ => _.GameStateId == _gameStateId));
redoableExpenseModels.AddRange(expenseModels.Where(_ => _.GameStateId == _gameStateId));
redoableMeberExpenses.AddRange(memberExpenses.Where(_ => _.GameStateId == _gameStateId));
gameStates.RemoveAll(_ => _.GameStateId == _gameStateId);
expenseModels.RemoveAll(_ => _.GameStateId == _gameStateId);
memberExpenses.RemoveAll(_ => _.GameStateId == _gameStateId);
_gameStateId = gameStates.Last().GameStateId;
return GameState;
}
internal async Task<Game> CreateNewGame(string gameName)
{
return await _gameRepository.Create(gameName);
}
internal async Task<GameState> LoadState(Guid gameId)
{
var existingGameStates = await _gameRepository.LoadStates(gameId);
gameStates.AddRange(existingGameStates.Select(_ => new GameStateHandlerItem<GameState>(_.Id,_)));
_gameStateId = gameStates.Last().GameStateId;
return existingGameStates.Last();
}
internal async Task<Game?> LoadGame(Guid gameId)
{
return await _gameRepository.LoadGame(gameId);
}
}
}