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

Class Class, % Method, % Branch, % Line, %
LoginFXMLController 0% (0/1) 0% (0/14) 0% (0/14) 0% (0/63)


 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.Network.IClient;
 import it.polimi.ingsw.gc14.Network.NetworkConfig;
 import it.polimi.ingsw.gc14.Network.InterfaceResolver;
 import it.polimi.ingsw.gc14.Network.RMI.Client.RMIClient;
 import it.polimi.ingsw.gc14.Network.TCP.Client.TCPClient;
 import javafx.animation.*;
 import javafx.application.Platform;
 import javafx.css.PseudoClass;
 import javafx.fxml.FXML;
 import javafx.geometry.Rectangle2D;
 import javafx.scene.control.*;
 import javafx.scene.image.Image;
 import javafx.scene.image.ImageView;
 import javafx.scene.layout.*;
 import javafx.scene.paint.Color;
 import javafx.stage.Screen;
 import javafx.util.Duration;
 
 import java.util.Objects;
 
 /**
  * FXML controller for the login scene.
  *
  * <p>Handles username/IP/player-count input, protocol selection (TCP/RMI),
  * and initiates the connection to the server.
  */
 public class LoginFXMLController {
     /** Background image displayed behind the login form. */
     @FXML private ImageView backgroundImage;
     /** Text field for the player's username. */
     @FXML private TextField campoNome;
     /** Text field for the desired number of players. */
     @FXML private TextField campoNumPlayers;
     /** Text field for the server IP address. */
     @FXML private TextField campoIP;
     /** Button that submits the login form. */
     @FXML private Button btnAccedi;
     /** Label used to show error or success messages. */
     @FXML private Label labelErrore;
     /** VBox containing the login form controls. */
     @FXML private VBox formPanel;
     /** Toggle container for switching between RMI and TCP. */
     @FXML private StackPane protocolToggle;
     /** Sliding thumb inside the protocol toggle. */
     @FXML private Region toggleThumb;
     /** Label for the RMI side of the protocol toggle. */
     @FXML private Label labelRMI;
     /** Label for the TCP side of the protocol toggle. */
     @FXML private Label labelTCP;
     /** {@code true} when RMI is selected; {@code false} for TCP. */
     private boolean isRMI = true;
     /** Client controller used to initiate the connection. */
     private ClientController controller;
     /** CSS pseudo-class applied to the active protocol label. */
     private final PseudoClass activeProtocolPseudo = PseudoClass.getPseudoClass("active-protocol");
 
     /**
      * Injects the client controller into this FXML controller.
      *
      * @param controller the client controller to use.
      */
     public void setController(ClientController controller) {
         this.controller = controller;
     }
 
     /** Initializes the scene: loads background, sets up animations, and binds input listeners. */
     @FXML
     public void initialize() {
         // Background setup
         Image img = new Image(Objects.requireNonNull(getClass().getResourceAsStream("/GUIImages/BackgroundLogin.png")));
         backgroundImage.setImage(img);
         Rectangle2D screenBounds = Screen.getPrimary().getBounds();
         backgroundImage.setFitWidth(screenBounds.getWidth());
         backgroundImage.setFitHeight(screenBounds.getHeight());
 
         // Protocol toggle configuration
         protocolToggle.setOnMouseClicked(e -> switchProtocol());
         protocolToggle.setStyle(protocolToggle.getStyle() + " -fx-cursor: hand;");
 
         labelRMI.pseudoClassStateChanged(activeProtocolPseudo, true);
         labelTCP.pseudoClassStateChanged(activeProtocolPseudo, false);
 
         // Login Action
         btnAccedi.setOnAction(e -> onAccediClick());
     }
 
     /** Toggles the selected protocol between RMI and TCP, animating the toggle thumb and updating label styles. */
     private void switchProtocol() {
         isRMI = !isRMI;
 
         TranslateTransition tt = new TranslateTransition(Duration.millis(200), toggleThumb);
         tt.setToX(isRMI ? 0 : 110);
         tt.play();
 
         labelRMI.pseudoClassStateChanged(activeProtocolPseudo, isRMI);
         labelTCP.pseudoClassStateChanged(activeProtocolPseudo, !isRMI);
     }
 
     /** Validates form input and starts a background thread to connect to the server. */
     @FXML
     private void onAccediClick() {
         String name = campoNome.getText().trim();
         String ip   = campoIP.getText().trim();
 
         if (name.isEmpty()) {
             showError("Please select a name.");
             return;
         }
 
         int numPlayers;
         try {
             numPlayers = Integer.parseInt(campoNumPlayers.getText().trim());
         } catch (NumberFormatException e) {
             showError("Invalid number of players.");
             return;
         }
 
         updateLoginButton(false);
         controller.setMyUsername(name);
 
         new Thread(() -> {
             try {
                 String localInterface = InterfaceResolver.resolveLocalInterface(ip);
                 System.setProperty("java.rmi.server.hostname", localInterface);
                 connect(name, ip, numPlayers, localInterface);
             } catch (Exception ex) {
                 Platform.runLater(() -> {
                     showError("Network error: " + ex.getMessage());
                     updateLoginButton(true);
                 });
             }
         }).start();
     }
 
     /**
      * Enables or disables the login button and updates its visual style.
      *
      * @param enabled {@code true} to enable the button, {@code false} to disable it.
      */
     public void updateLoginButton(boolean enabled) {
         btnAccedi.setDisable(!enabled);
         btnAccedi.setStyle(
                 "-fx-font-family: 'Cinzel'; -fx-font-size: 12; -fx-font-weight: bold;" +
                 "-fx-letter-spacing: 4; -fx-text-fill: #0c0601;" +
                 "-fx-background-color: linear-gradient(to right, #f4c05a, #c8791a, #f4c05a);" +
                 "-fx-padding: 13 48 13 48; -fx-background-radius: 2;" +
                 "-fx-opacity: " + (enabled ? "1.0" : "0.3") + ";" +
                 "-fx-cursor: " + (enabled ? "hand" : "default") + ";"
         );
     }
 
 
 
 
     /** Connects to the server using the selected protocol and transitions to the waiting state on success. */
     private void connect(String nome, String ip, int numPlayers, String localInterface) {
         IClient client;
         if (isRMI) {
             client = new RMIClient(controller, ip, NetworkConfig.RMI_PORT, localInterface);
             ErrorType serverResponse = client.connect(nome, numPlayers);
             if (serverResponse == null) {
                 controller.setClient(client);
                 Platform.runLater(() -> showSuccess("Connected! Waiting for other players…"));
             } else {
                 Platform.runLater(() -> {
                     showError(serverResponse);
                     updateLoginButton(true);
                 });
             }
         } else {
             client = new TCPClient(controller, ip, NetworkConfig.TCP_PORT, NetworkConfig.HEARTBEAT_PORT);
             ErrorType serverResponse = client.connect(nome, numPlayers);
             if (serverResponse == null) {
                 controller.setClient(client);
                 Platform.runLater(() -> showSuccess("Connected! Waiting for other players…"));
             } else {
                 Platform.runLater(() -> {
                     showError(serverResponse);
                     updateLoginButton(true);
                 });
             }
         }
     }
     /**
      * Displays an error from an {@link ErrorType} constant in the login form label.
      *
      * @param errorType the error to display.
      */
     public void showError(ErrorType errorType) {
         labelErrore.setTextFill(Color.web("#e05050"));
         labelErrore.setText(errorType.toString());
     }
 
     /**
      * Displays an arbitrary error message in the login form label.
      *
      * @param msg the error message to display.
      */
     public void showError(String msg) {
         labelErrore.setTextFill(Color.web("#e05050"));
         labelErrore.setText(msg);
     }
 
     /** Displays a success message in green in the login form label. */
     private void showSuccess(String msg) {
         labelErrore.setTextFill(Color.web("#6fcf8a"));
         labelErrore.setText(msg);
     }
 }