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 { 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> gameStates = new List>(); private List> expenseModels = new List>(); private List> memberExpenses = new List>(); private List> redoableGameStates = new List>(); private List> redoableExpenseModels = new List>(); private List> redoableMeberExpenses = new List>(); 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(_gameStateId, expenseModel)); } } else { expenseModels.Add(new GameStateHandlerItem(_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(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(_gameStateId, newState with { Counter = gameStates.Count + 1 }); gameStates.Add(item); } } private async Task Save(GameStateHandlerItem item) { await _expenseRepository.Save(item.Data); } private async Task Save(GameStateHandlerItem 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 CreateNewGame(string gameName) { return await _gameRepository.Create(gameName); } internal async Task LoadState(Guid gameId) { var existingGameStates = await _gameRepository.LoadStates(gameId); gameStates.AddRange(existingGameStates.Select(_ => new GameStateHandlerItem(_.Id,_))); _gameStateId = gameStates.Last().GameStateId; return existingGameStates.Last(); } internal async Task LoadGame(Guid gameId) { return await _gameRepository.LoadGame(gameId); } } }