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; } } public Guid NextGameStateId { get { if (_gameStateId == Guid.Empty) { _gameStateId = Guid.NewGuid(); } return _gameStateId; } } public Guid StartNewState() { _gameStateId = Guid.NewGuid(); return _gameStateId; } internal void Add(IEnumerable playerExpenses) { foreach (var playerExpense in playerExpenses) { Add(playerExpense); } } internal void Add(PlayerExpense playerExpense) { var model = playerExpense with { GamestateId = _gameStateId }; memberExpenses.Add(new GameStateHandlerItem(_gameStateId, model)); } internal void Add(GameState newState) { if (newState.Id != Guid.Empty && newState.Id != NextGameStateId) { throw new InvalidDataException("GameState is not new"); } var model = newState with { Id = _gameStateId, Counter = gameStates.Count + 1 }; var item = new GameStateHandlerItem(_gameStateId, model); gameStates.Add(item); } 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); foreach (var memberExpense in memberExpenses.Where(_ => _.GameStateId == _gameStateId)) { await Save(memberExpense); } //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(); } 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.Clear(); gameStates.AddRange(existingGameStates.Select(_ => new GameStateHandlerItem(_.Id,_))); _gameStateId = gameStates.Last().GameStateId; memberExpenses.Clear(); //_expenseRepository.GetMemberExpenses(); return existingGameStates.Last(); } internal async Task LoadGame(Guid gameId) { return await _gameRepository.LoadGame(gameId); } } }