package it.polimi.ingsw.gc14.Network.RMI.Client;
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;

import it.polimi.ingsw.gc14.Controller.ClientController;
import it.polimi.ingsw.gc14.Network.NetworkEvent;
import it.polimi.ingsw.gc14.Network.RMI.Common.IClientCallback;
import it.polimi.ingsw.gc14.Network.RMI.Common.IGameServer;
import it.polimi.ingsw.gc14.Network.RMI.Server.RMIServer;

/**
 * Client RMI. Uses the methods exposed by the server RMI.
 */
public class RMIClient {

    /** The host address of the RMI server */
    private final String host;

    /** The port of the RMI server */
    private final int port;

    /** The remote stub used to call methods on the server */
    private IGameServer stub;


    /**
     * Class constructor.
     * @param host the host address of the RMI server
     * @param port the port of the RMI server
     */
    public RMIClient(String host, int port) {
        this.host = host;
        this.port = port;
    }


    /**
     * Connects to the RMI server and attempts to join the game.
     * Looks up the RMI registry to retrieve the {@link IGameServer} stub.
     * Then, creates a {@link ClientCallbackImpl} and calls {@link RMIServer#joinGame(String, int, IClientCallback)}.
     * @param username the player's username
     * @param preferredInt the desired number of players
     * @param clientController the client controller used to create the callback
     * @return true if the player successfully joined the game, false otherwise
     */
    public boolean connect(String username,int preferredInt, ClientController clientController) {
        try {
            Registry registry = LocateRegistry.getRegistry(host, port);
            this.stub = (IGameServer) registry.lookup("RMIGameServer");
            ClientCallbackImpl callback = new ClientCallbackImpl(clientController);

            return stub.joinGame(username, preferredInt, callback);
        }
        catch (Exception e) {
            e.printStackTrace();
            return false;
        }

    }

    /**
     * Sends a {@link NetworkEvent} to the server.
     * @param event the event to send
     * @throws RemoteException if any RMI error occurs
     */
    public void doEvent(NetworkEvent event) throws RemoteException {
        stub.doEvent(event);
    }

}