using System; using YachtDice.Categories; using YachtDice.Economy; using YachtDice.Game; using YachtDice.Inventory; using YachtDice.Player; using YachtDice.Run; using YachtDice.Shop; namespace YachtDice.UI.Presentation { public sealed class GameFlowPresenter : IDisposable { private readonly GameLoopController _gameLoopController; private readonly DiceManager _diceManager; private readonly CurrencyBank _currencyBank; private readonly ShopController _shopController; private readonly InventoryController _inventoryController; private readonly CategoryCatalog _categoryCatalog; private readonly PlayerModel _playerModel; private readonly IGameSaveService _saveService; private readonly IScoreSummaryService _scoreSummaryService; private readonly DicePanelPresenter _dicePanelPresenter; private readonly ScoreCardPresenter _scoreCardPresenter; private readonly GameInfoPresenter _gameInfoPresenter; public GameFlowPresenter( GameLoopController gameLoopController, DiceManager diceManager, CurrencyBank currencyBank, ShopController shopController, InventoryController inventoryController, CategoryCatalog categoryCatalog, PlayerModel playerModel, IGameSaveService saveService, IScoreSummaryService scoreSummaryService, DicePanelPresenter dicePanelPresenter, ScoreCardPresenter scoreCardPresenter, GameInfoPresenter gameInfoPresenter) { _gameLoopController = gameLoopController; _diceManager = diceManager; _currencyBank = currencyBank; _shopController = shopController; _inventoryController = inventoryController; _categoryCatalog = categoryCatalog; _playerModel = playerModel; _saveService = saveService; _scoreSummaryService = scoreSummaryService; _dicePanelPresenter = dicePanelPresenter; _scoreCardPresenter = scoreCardPresenter; _gameInfoPresenter = gameInfoPresenter; } public void Initialize() { _gameLoopController.OnTurnStarted += HandleTurnStarted; _gameLoopController.OnRollComplete += HandleRollComplete; _gameLoopController.OnScored += HandleScored; _gameLoopController.OnGameOver += HandleGameOver; _gameLoopController.OnBetStarted += HandleBetStarted; _gameLoopController.OnShopOpened += HandleShopOpened; _gameLoopController.OnShopClosed += HandleShopClosed; _gameLoopController.OnStoredRollsChanged += HandleStoredRollsChanged; _gameLoopController.OnQuotaChanged += HandleQuotaChanged; _gameLoopController.OnCycleCompleted += HandleCycleCompleted; _gameLoopController.OnPhaseChanged += HandlePhaseChanged; _gameLoopController.OnShopAvailabilityChanged += HandleShopAvailabilityChanged; _dicePanelPresenter.RollClicked += HandleRollClicked; _dicePanelPresenter.DiceToggled += HandleDiceToggled; _scoreCardPresenter.CategorySelected += HandleCategorySelected; _gameInfoPresenter.NewGameClicked += HandleNewGameClicked; _gameInfoPresenter.ShopClicked += HandleShopClicked; _gameInfoPresenter.InventoryClicked += HandleInventoryClicked; _shopController.OnCloseRequested += HandleShopCloseRequested; _currencyBank.OnBalanceChanged += HandleCurrencyChanged; _playerModel.OnChanged += HandlePlayerChangedForSave; _saveService.Load(); _gameInfoPresenter.SetCurrencyText(_currencyBank.Balance); _gameInfoPresenter.SetShopButtonInteractable(_gameLoopController.CanOpenShopManually()); _gameLoopController.StartNewGame(); } public void Dispose() { _gameLoopController.OnTurnStarted -= HandleTurnStarted; _gameLoopController.OnRollComplete -= HandleRollComplete; _gameLoopController.OnScored -= HandleScored; _gameLoopController.OnGameOver -= HandleGameOver; _gameLoopController.OnBetStarted -= HandleBetStarted; _gameLoopController.OnShopOpened -= HandleShopOpened; _gameLoopController.OnShopClosed -= HandleShopClosed; _gameLoopController.OnStoredRollsChanged -= HandleStoredRollsChanged; _gameLoopController.OnQuotaChanged -= HandleQuotaChanged; _gameLoopController.OnCycleCompleted -= HandleCycleCompleted; _gameLoopController.OnPhaseChanged -= HandlePhaseChanged; _gameLoopController.OnShopAvailabilityChanged -= HandleShopAvailabilityChanged; _dicePanelPresenter.RollClicked -= HandleRollClicked; _dicePanelPresenter.DiceToggled -= HandleDiceToggled; _scoreCardPresenter.CategorySelected -= HandleCategorySelected; _gameInfoPresenter.NewGameClicked -= HandleNewGameClicked; _gameInfoPresenter.ShopClicked -= HandleShopClicked; _gameInfoPresenter.InventoryClicked -= HandleInventoryClicked; _shopController.OnCloseRequested -= HandleShopCloseRequested; _currencyBank.OnBalanceChanged -= HandleCurrencyChanged; if (_playerModel != null) _playerModel.OnChanged -= HandlePlayerChangedForSave; } private void HandleTurnStarted(int turn) { UpdateRunInfoText(); _dicePanelPresenter.ResetForNewTurn(); _dicePanelPresenter.SetRollingEnabled(true); _scoreCardPresenter.ClearAllPreviews(); _gameInfoPresenter.SetShopButtonInteractable(_gameLoopController.CanOpenShopManually()); } private void HandleRollComplete(int rollNumber) { _dicePanelPresenter.HandleRollComplete(rollNumber); _scoreCardPresenter.UpdatePreviewScores(); _gameInfoPresenter.SetShopButtonInteractable(_gameLoopController.CanOpenShopManually()); } private void HandleScored(CategoryDefinition category, int finalScore) { _scoreCardPresenter.SetCategoryScored(category, finalScore); _scoreCardPresenter.UpdateTotalDisplay(_scoreSummaryService.Calculate()); UpdateRunInfoText(); _saveService.Save(); } private void HandleGameOver(int totalScore) { _dicePanelPresenter.HandleGameOver(); _scoreCardPresenter.SetAllInteractable(false); _gameInfoPresenter.ShowGameOver(_scoreSummaryService.Calculate().DisplayTotal); _shopController.Close(); _gameInfoPresenter.SetShopButtonInteractable(false); _saveService.Save(); } private void HandleRollClicked() { if (!_gameLoopController.Roll()) return; _dicePanelPresenter.PrepareForRoll(); _scoreCardPresenter.SetAllInteractable(false); } private void HandleDiceToggled(int index) { _gameLoopController.ToggleDiceLock(index); _dicePanelPresenter.SetDiceLocked(index, _diceManager.IsLocked(index)); } private void HandleCategorySelected(CategoryDefinition category) { _gameLoopController.ScoreInCategory(category); } private void HandleNewGameClicked() { _gameInfoPresenter.HideGameOver(); _shopController.Close(); _gameInfoPresenter.SetShopButtonInteractable(false); _scoreCardPresenter.ResetAll(); _dicePanelPresenter.ResetForNewGame(); _gameLoopController.StartNewGame(); } private void HandleShopClicked() { if (!_gameLoopController.CanOpenShopManually()) return; if (_shopController.IsOpen) _shopController.Close(); else _shopController.Open(); } private void HandleInventoryClicked() { _inventoryController.ToggleVisibility(); } private void HandleCurrencyChanged(int newBalance) { _gameInfoPresenter.SetCurrencyText(newBalance); UpdateRunInfoText(); } private void HandlePlayerChangedForSave() { _saveService.Save(); } private void HandleBetStarted(int betIndex) { UpdateRunInfoText(); } private void HandleShopOpened() { _gameInfoPresenter.SetShopButtonInteractable(_gameLoopController.CanOpenShopManually()); UpdateRunInfoText(); } private void HandleShopClosed() { _shopController.Close(); _gameInfoPresenter.SetShopButtonInteractable(_gameLoopController.CanOpenShopManually()); UpdateRunInfoText(); } private void HandleStoredRollsChanged(int value) { UpdateRunInfoText(); } private void HandleQuotaChanged(int value) { UpdateRunInfoText(); } private void HandleCycleCompleted(int bonus, int storedRolls) { _scoreCardPresenter.ResetAll(); _scoreCardPresenter.UpdateTotalDisplay(_scoreSummaryService.Calculate()); UpdateRunInfoText(); } private void HandlePhaseChanged(RunPhase phase) { _gameInfoPresenter.SetShopButtonInteractable(_gameLoopController.CanOpenShopManually()); UpdateRunInfoText(); } private void UpdateRunInfoText() { var phase = _gameLoopController.CurrentPhase.ToString(); _gameInfoPresenter.SetRunHud( phase, _gameLoopController.CurrentBet, _gameLoopController.CurrentStage, 3, _gameLoopController.CurrentStageTarget, _gameLoopController.CurrentBaseQuota, _gameLoopController.StoredRolls); } private void HandleShopCloseRequested() { _shopController.Close(); _gameLoopController.CompleteShop(); } private void HandleShopAvailabilityChanged(bool isAvailable) { if (!isAvailable && _shopController.IsOpen) _shopController.Close(); _gameInfoPresenter.SetShopButtonInteractable(isAvailable); UpdateRunInfoText(); } } }