using Minesweeper.Commands; using Minesweeper.Core; using Minesweeper.Presentation.Factories; using Minesweeper.Presentation.ReadModels; using Minesweeper.Presentation.Views; namespace Minesweeper.Presentation.Presenters { public sealed class GamePresenter : IPresenter { private readonly IGameCommandDispatcher commandDispatcher; private readonly ICellViewFactory cellViewFactory; private readonly IGamePauseService pauseService; private readonly IGameReadModel readModel; private readonly IGameStateService gameStateService; private readonly TopPanelPresenter topPanelPresenter; private readonly IBoardView boardView; private readonly IPauseView pauseView; private readonly IResultView resultView; private bool boardBuilt; public GamePresenter(IGameCommandDispatcher commandDispatcher, ICellViewFactory cellViewFactory, IGamePauseService pauseService, IGameReadModel readModel, IGameStateService gameStateService, TopPanelPresenter topPanelPresenter, IBoardView boardView, IPauseView pauseView, IResultView resultView) { this.commandDispatcher = commandDispatcher; this.cellViewFactory = cellViewFactory; this.pauseService = pauseService; this.readModel = readModel; this.gameStateService = gameStateService; this.topPanelPresenter = topPanelPresenter; this.boardView = boardView; this.pauseView = pauseView; this.resultView = resultView; } public void Initialize() { boardView.CellPressStarted += OnCellPressStarted; boardView.CellPressEnded += OnCellPressEnded; boardView.PauseRequested += OnPauseRequested; boardView.CellOpenRequested += OnCellOpenRequested; boardView.CellFlagRequested += OnCellFlagRequested; pauseView.RestartRequested += OnRestartRequested; pauseView.ResumeRequested += OnResumeRequested; pauseView.GoToMenuRequested += OnGoToMenuRequested; resultView.RestartRequested += OnRestartRequested; resultView.GoToMenuRequested += OnGoToMenuRequested; gameStateService.StateChanged += OnStateChanged; pauseService.PauseChanged += OnPauseChanged; OnStateChanged(gameStateService.Current); OnPauseChanged(pauseService.IsPaused); } public void Dispose() { boardView.CellPressStarted -= OnCellPressStarted; boardView.CellPressEnded -= OnCellPressEnded; boardView.PauseRequested -= OnPauseRequested; boardView.CellOpenRequested -= OnCellOpenRequested; boardView.CellFlagRequested -= OnCellFlagRequested; pauseView.RestartRequested -= OnRestartRequested; pauseView.ResumeRequested -= OnResumeRequested; pauseView.GoToMenuRequested -= OnGoToMenuRequested; resultView.RestartRequested -= OnRestartRequested; resultView.GoToMenuRequested -= OnGoToMenuRequested; gameStateService.StateChanged -= OnStateChanged; pauseService.PauseChanged -= OnPauseChanged; } private void OnCellOpenRequested(int x, int y) { topPanelPresenter.SetCellPressActive(false); commandDispatcher.Dispatch(new OpenCellCommand(x, y)); RefreshBoard(); topPanelPresenter.RefreshCounters(); UpdateBoardInput(); } private void OnCellFlagRequested(int x, int y) { commandDispatcher.Dispatch(new ToggleFlagCommand(x, y)); RefreshBoard(); topPanelPresenter.RefreshCounters(); UpdateBoardInput(); } private void OnCellPressStarted() { topPanelPresenter.SetCellPressActive(true); } private void OnCellPressEnded() { topPanelPresenter.SetCellPressActive(false); } private void OnStateChanged(GameState state) { if (state == GameState.FieldSelection) { boardBuilt = false; boardView.Hide(); pauseView.Hide(); resultView.Hide(); return; } boardView.Show(); if (state == GameState.Won || state == GameState.Lost) { pauseView.Hide(); resultView.Show(state); } else { resultView.Hide(); } if (!boardBuilt || state == GameState.Preparing) { RebuildBoard(); } else { RefreshBoard(); } UpdateBoardInput(); } private void OnPauseChanged(bool isPaused) { if (isPaused && gameStateService.Current == GameState.Playing) { pauseView.Show(); } else { pauseView.Hide(); } UpdateBoardInput(); } private void RebuildBoard() { var cells = readModel.GetCells(); boardView.Rebuild(cells, readModel.Width, readModel.Height, cellViewFactory, IsFinalState()); boardBuilt = true; topPanelPresenter.RefreshCounters(); UpdateBoardInput(); } private void RefreshBoard() { boardView.Refresh(readModel.GetCells(), IsFinalState()); } private bool IsFinalState() { var state = gameStateService.Current; return state == GameState.Lost || state == GameState.Won; } private void UpdateBoardInput() { var state = gameStateService.Current; boardView.SetInputEnabled(!pauseService.IsPaused && (state == GameState.Preparing || state == GameState.Playing)); } private void OnRestartRequested() { commandDispatcher.Dispatch(new RestartCommand()); RebuildBoard(); topPanelPresenter.RefreshCounters(); } private void OnGoToMenuRequested() { commandDispatcher.Dispatch(new GoToMenuCommand()); } private void OnResumeRequested() { commandDispatcher.Dispatch(new ResumeCommand()); } private void OnPauseRequested() { commandDispatcher.Dispatch(new PauseCommand()); } } }