Coverage Summary for Class: GUI (it.polimi.ingsw.gc14.View.GUI)

Class Class, % Method, % Branch, % Line, %
GUI 0% (0/1) 0% (0/16) 0% (0/22) 0% (0/110)


 package it.polimi.ingsw.gc14.View.GUI;
 
 import it.polimi.ingsw.gc14.Controller.ClientController;
 import it.polimi.ingsw.gc14.ErrorType;
 import it.polimi.ingsw.gc14.Model.MiniModel;
 import it.polimi.ingsw.gc14.View.IView;
 import javafx.animation.FadeTransition;
 import javafx.application.Application;
 import javafx.application.Platform;
 import javafx.fxml.FXMLLoader;
 import javafx.geometry.Rectangle2D;
 import javafx.scene.Parent;
 import javafx.scene.Scene;
 import javafx.scene.input.KeyCode;
 import javafx.scene.input.KeyEvent;
 import javafx.scene.input.KeyCombination;
 import javafx.scene.layout.StackPane;
 
 import javafx.scene.paint.Color;
 import javafx.scene.shape.Rectangle;
 import javafx.stage.Screen;
 import javafx.stage.Stage;
 import javafx.util.Duration;
 
 import static it.polimi.ingsw.gc14.Model.GamePackage.GameStages.ENDED;
 import static it.polimi.ingsw.gc14.Model.GamePackage.GameStages.TOTEM_CHOICE;
 
 /**
  * JavaFX-based GUI implementation of {@link it.polimi.ingsw.gc14.View.IView IView}.
  *
  * <p>Manages the primary stage and switches between the login, totem choice,
  * main game, and leaderboard scenes based on the current game state.
  */
 public class GUI extends Application implements IView {
     /** The primary JavaFX stage. */
     private Stage primaryStage;
     /** Latest mini model received from the server. */
     private volatile MiniModel miniModel;
     /** FXML loader for the login scene. */
     private FXMLLoader loaderLogin;
     /** The login scene. */
     private Scene loginScene;
     /** Controller for the login FXML scene. */
     private LoginFXMLController controllerLogin;
     /** FXML loader for the totem selection scene. */
     private FXMLLoader loaderTotem;
     /** The totem selection scene. */
     private Scene totemScene;
     /** Controller for the totem FXML scene. */
     private TotemFXMLController controllerTotem;
     /** FXML loader for the main game scene. */
     private FXMLLoader loaderMain;
     /** The main game scene. */
     private Scene mainScene;
     /** Controller for the main FXML scene. */
     private MainFXMLController controllerMain;
     /** FXML loader for the leaderboard scene. */
     private FXMLLoader loaderLeaderboard;
     /** The end-of-game leaderboard scene. */
     private Scene leaderboardScene;
     /** Controller for the leaderboard FXML scene. */
     private LeaderboardFXMLController controllerLeaderboard;
     /** Client controller injected before JavaFX startup. */
     private ClientController controller;
     /** When {@code true}, the app re-enters fullscreen automatically after ESC is pressed. */
     private boolean autoReenterFullscreen = true;
     /** Guards against overlapping fade transitions. */
     private boolean isFading = false;
 
 
     /**
      * JavaFX entry point: loads all FXML scenes, wires up controllers,
      * configures fullscreen behavior, and shows the login scene.
      *
      * @param stage the primary stage provided by the JavaFX runtime.
      * @throws Exception if any FXML resource cannot be loaded.
      */
     @Override
     public void start(Stage stage) throws Exception {
         this.primaryStage = stage;
         loaderLogin = new FXMLLoader(getClass().getResource("/GUIScene/login.fxml"));
         loginScene = new Scene(loaderLogin.load());
         controllerLogin = loaderLogin.getController();
         controllerLogin.setController(controller);
 
 
         loaderTotem = new FXMLLoader(getClass().getResource("/GUIScene/totem.fxml"));
         totemScene = new Scene(loaderTotem.load());
         controllerTotem = loaderTotem.getController();
         controllerTotem.setController(controller);
 
 
         loaderMain = new FXMLLoader(getClass().getResource("/GUIScene/main.fxml"));
         mainScene = new Scene(loaderMain.load());
         controllerMain = loaderMain.getController();
         controllerMain.setController(controller);
 
         loaderLeaderboard = new FXMLLoader(getClass().getResource("/GUIScene/standing.fxml"));
         leaderboardScene = new Scene(loaderLeaderboard.load());
         controllerLeaderboard = loaderLeaderboard.getController();
         controllerLeaderboard.setController(controller, () -> {
             controllerLogin.updateLoginButton(true);
             controllerLogin.showError("");
             fadeToScene(loginScene);
         });
 
 
 
 
 
         wrapScene(loginScene);
         wrapScene(totemScene);
         wrapScene(mainScene);
         wrapScene(leaderboardScene);
 
         FireParticleSystem fireParticles = new FireParticleSystem(mainScene);
         ((StackPane) mainScene.getRoot()).getChildren().add(fireParticles.getPane());
         fireParticles.start();
 
         primaryStage.setScene(loginScene);
         Rectangle2D tmp = Screen.getPrimary().getVisualBounds();
         primaryStage.setWidth(tmp.getWidth());
         primaryStage.setHeight(tmp.getHeight());
         primaryStage.setX(tmp.getMinX());
         primaryStage.setY(tmp.getMinY());
         primaryStage.setResizable(false);
         primaryStage.setFullScreenExitHint("");
         primaryStage.setFullScreenExitKeyCombination(KeyCombination.NO_MATCH);
 
         primaryStage.fullScreenProperty().addListener((obs, was, isNow) -> {
             if (!isNow && autoReenterFullscreen) {
                 Platform.runLater(() -> primaryStage.setFullScreen(true));
             }
         });
 
         primaryStage.addEventFilter(KeyEvent.KEY_PRESSED, e -> {
             if (e.getCode() == KeyCode.ESCAPE) {
                 autoReenterFullscreen = false;
                 primaryStage.setFullScreen(false);
                 e.consume();
             } else if (e.getCode() == KeyCode.F11) {
                 autoReenterFullscreen = true;
                 primaryStage.setFullScreen(true);
                 e.consume();
             }
         });
 
         primaryStage.setTitle("Mesos");
         primaryStage.setOnCloseRequest(e -> {
             Platform.exit();
             System.exit(0);
         });
         primaryStage.show();
         Platform.runLater(() -> primaryStage.setFullScreen(true));
 
     }
 
 
     /**
      * Updates the local mini model reference used by the GUI.
      *
      * @param miniModel the latest mini model received from the server.
      */
     @Override
     public void setModel(MiniModel miniModel) {
         this.miniModel = miniModel;
     }
 
     /**
      * Injects the client controller into this GUI.
      *
      * @param controller the client controller to use.
      */
     public void setController(ClientController controller) {
         this.controller=controller;
     }
 
     /**
      * Re-renders the GUI on the JavaFX application thread, switching to the
      * appropriate scene based on the current game stage.
      */
     public void render() {
         Platform.runLater(() -> {
             if (miniModel == null) return;
             if (controller.getMiniModel().currentState.getGameStage() == TOTEM_CHOICE) {
                 controllerTotem.render();
                 fadeToScene(totemScene);
             } else if (controller.getMiniModel().currentState.getGameStage() == ENDED) {
                 controllerLeaderboard.render();
                 fadeToScene(leaderboardScene);
             } else {
                 controllerMain.render();
                 fadeToScene(mainScene);
             }
         });
     }
     /**
      * Wraps the current root of {@code scene} in a {@link StackPane} so that
      * fade overlay rectangles can be layered over it during scene transitions.
      *
      * @param scene the scene whose root to wrap.
      */
     private void wrapScene(Scene scene) {
         Parent root = scene.getRoot();
         scene.setRoot(new StackPane(root));
     }
     /**
      * Performs a black-overlay crossfade from the current scene to {@code newScene}.
      * No-op if already fading or if {@code newScene} is already displayed.
      *
      * @param newScene the scene to transition to.
      */
     private void fadeToScene(Scene newScene) {
         Scene currentScene = primaryStage.getScene();
         if (currentScene == newScene || isFading) return;
         isFading = true;
 
         StackPane currentRoot = (StackPane) currentScene.getRoot();
         Rectangle overlay = new Rectangle();
         overlay.setFill(Color.BLACK);
         overlay.setOpacity(0);
         overlay.widthProperty().bind(currentRoot.widthProperty());
         overlay.heightProperty().bind(currentRoot.heightProperty());
         currentRoot.getChildren().add(overlay);
 
         FadeTransition fadeOut = new FadeTransition(Duration.millis(500), overlay);
         fadeOut.setFromValue(0);
         fadeOut.setToValue(1);
         fadeOut.setOnFinished(e -> {
             currentRoot.getChildren().remove(overlay);
 
             StackPane newRoot = (StackPane) newScene.getRoot();
             Rectangle newOverlay = new Rectangle();
             newOverlay.setFill(Color.BLACK);
             newOverlay.setOpacity(1);
             newOverlay.widthProperty().bind(newRoot.widthProperty());
             newOverlay.heightProperty().bind(newRoot.heightProperty());
             newRoot.getChildren().add(newOverlay);
 
             primaryStage.setScene(newScene);
 
             FadeTransition fadeIn = new FadeTransition(Duration.millis(500), newOverlay);
             fadeIn.setFromValue(1);
             fadeIn.setToValue(0);
             fadeIn.setOnFinished(ev -> {
                 newRoot.getChildren().remove(newOverlay);
                 isFading = false;
             });
             fadeIn.play();
         });
         fadeOut.play();
     }
 
     /**
      * Displays an error on the JavaFX application thread.
      *
      * <p>If the server crashed, returns to the login scene and re-enables the login button.
      * Otherwise, delegates to the active scene's error display.
      *
      * @param error   the error type.
      * @param message a human-readable description of the error.
      */
     @Override
     public void showError(ErrorType error,String message) {
         Platform.runLater(() -> {
             if (error == ErrorType.SERVER_CRASHED) {
                 controllerLogin.updateLoginButton(true);
                 controllerLogin.showError(error);
                 fadeToScene(loginScene);
             } else {
                 if (miniModel == null) return;
                 controllerMain.setError(true);
                 controllerMain.render();
             }
         });
     }
 
 }