Alvaro2112/Money_run

View on GitHub
app/src/main/java/sdp/moneyrun/menu/NewGameImplementation.java

Summary

Maintainability
A
1 hr
Test Coverage
A
100%
package sdp.moneyrun.menu;

import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.location.Location;
import android.location.LocationManager;
import android.media.MediaPlayer;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.PopupWindow;
import android.widget.TextView;

import androidx.activity.result.ActivityResultLauncher;
import androidx.annotation.NonNull;

import com.google.firebase.database.DatabaseReference;

import java.util.ArrayList;
import java.util.List;

import sdp.moneyrun.R;
import sdp.moneyrun.database.game.GameDatabaseProxy;
import sdp.moneyrun.database.riddle.Riddle;
import sdp.moneyrun.game.Game;
import sdp.moneyrun.location.AndroidLocationService;
import sdp.moneyrun.location.LocationRepresentation;
import sdp.moneyrun.map.Coin;
import sdp.moneyrun.player.Player;
import sdp.moneyrun.ui.game.GameLobbyActivity;
import sdp.moneyrun.ui.map.MapActivity;
import sdp.moneyrun.user.User;

@SuppressWarnings("FieldCanBeLocal")
public class NewGameImplementation extends MenuImplementation {
    private final String LOCATION_MODE = LocationManager.GPS_PROVIDER;
    TextView nameGameView;
    TextView maxPlayerNumberView;
    TextView numCoinsView;
    TextView gameRadiusView;
    TextView gameDurationView;

    public NewGameImplementation(Activity activity,
                                 DatabaseReference databaseReference,
                                 User user,
                                 ActivityResultLauncher<String[]> requestPermissionsLauncher,
                                 AndroidLocationService locationService) {
        super(activity, databaseReference, user, requestPermissionsLauncher, locationService);
    }


    /**
     * Event that occurs when the user wants to add a new game.
     *
     * @param view the current view
     */
    public void onClickShowNewGamePopupWindow(View view) {
        // inflate the layout of the popup window
        MediaPlayer.create(activity.getApplicationContext(), R.raw.button_press).start();
        LayoutInflater inflater = (LayoutInflater)
                activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        @SuppressLint("InflateParams") View popupView = inflater.inflate(R.layout.new_game_popup, null);

        // create the popup window
        int width = LinearLayout.LayoutParams.WRAP_CONTENT;
        int height = LinearLayout.LayoutParams.WRAP_CONTENT;
        final PopupWindow popupWindow = new PopupWindow(popupView, width, height, true);

        // show the popup window at wanted location
        popupWindow.showAtLocation(view, Gravity.CENTER, 0, 0);

        LinearLayout newGameLayout = popupView.findViewById(R.id.newGameLayout);
        Button newGameButton = newGameLayout.findViewById(R.id.newGameSubmit);

        newGameButton.setOnClickListener(v -> onSubmitPostNewGame(newGameLayout, popupWindow));
    }

    /**
     * Create a new game.
     *
     * @param newGameLayout the game layout
     */
    public void onSubmitPostNewGame(@NonNull LinearLayout newGameLayout, @NonNull PopupWindow popupWindow) {
        nameGameView = newGameLayout.findViewById(R.id.nameGameField);
        maxPlayerNumberView = newGameLayout.findViewById(R.id.maxPlayerCountField);
        numCoinsView = newGameLayout.findViewById(R.id.newGameNumCoins);
        gameRadiusView = newGameLayout.findViewById(R.id.newGameRadius);
        gameDurationView = newGameLayout.findViewById(R.id.newGameDuration);
        String gameName = nameGameView.getText().toString().trim();
        String maxPlayerNumberStr = maxPlayerNumberView.getText().toString().trim();
        String numCoinsStr = numCoinsView.getText().toString().trim();
        String gameRadiusStr = gameRadiusView.getText().toString().trim();
        String gameDurationStr = gameDurationView.getText().toString().trim();

        if (!checkNewGameStringParameters(gameName, maxPlayerNumberStr, numCoinsStr, gameRadiusStr, gameDurationStr)) {
            return;
        }
        int maxPlayerNumber = Integer.parseInt(maxPlayerNumberStr);
        int numCoinsNumber = Integer.parseInt(numCoinsStr);
        double gameRadiusNumber = Double.parseDouble(gameRadiusStr);
        double gameDurationNumber = Double.parseDouble(gameDurationStr);

        if (!checkNewGameParametersValues(maxPlayerNumber, numCoinsNumber, gameRadiusNumber, gameDurationNumber)) {
            return;
        }

        popupWindow.dismiss();

        postNewGame(gameName, maxPlayerNumber, numCoinsNumber, gameRadiusNumber, gameDurationNumber, locationService.getCurrentLocation());
    }

    /**
     * Checks if the strings inputted in the UI are good or not
     *
     * @param gameName           name of the game
     * @param maxPlayerNumberStr string inputted in the UI for the  player count
     * @param numCoinsStr        string inputted in the UI for the number of coin
     * @param gameRadiusStr      string inputted in the UI for the radius of th game
     * @param gameDurationStr    string inputted in the UI for the game duration
     * @return true if there is no problem with the strings else return false
     */
    private boolean checkNewGameStringParameters(@NonNull String gameName, @NonNull String maxPlayerNumberStr, @NonNull String numCoinsStr, @NonNull String gameRadiusStr, @NonNull String gameDurationStr) {
        boolean isEmpty = false;
        if (gameName.isEmpty()) {
            nameGameView.setError("This field is required");
            isEmpty = true;
        }

        if (maxPlayerNumberStr.isEmpty()) {
            maxPlayerNumberView.setError("This field is required");
            isEmpty = true;
        }

        if (numCoinsStr.isEmpty()) {
            numCoinsView.setError("This field is required");
            isEmpty = true;
        }
        if (gameRadiusStr.isEmpty()) {
            gameRadiusView.setError("This field is required");
            isEmpty = true;
        }
        if (gameDurationStr.isEmpty()) {
            gameDurationView.setError("This field is required");
            isEmpty = true;
        }
        return !isEmpty;
    }

    /**
     * @param maxPlayerNumber parsed int of the UI string parameter
     * @param numCoins        parsed int of the UI string parameter
     * @param gameRadius      parsed double of the UI string parameter
     * @param gameDuration    parsed double of the UI string parameter
     * @return true if there is no problem with the numbers else return false
     */
    private boolean checkNewGameParametersValues(int maxPlayerNumber, int numCoins, double gameRadius, double gameDuration) {
        boolean outOfBounds = false;
        if (maxPlayerNumber < 1) {
            maxPlayerNumberView.setError("There should be at least one player in a game");
            outOfBounds = true;
        }

        if (numCoins < 1) {
            numCoinsView.setError("There should be at least one coin in a game");
            outOfBounds = true;
        }

        if (gameRadius <= MapActivity.THRESHOLD_DISTANCE) {
            gameRadiusView.setError("The radius of the game should be bigger than 7 meters");
            outOfBounds = true;
        }
        if (gameDuration <= 0) {
            gameDurationView.setError("The game should last for more than 0 minute");
            outOfBounds = true;
        }
        return !outOfBounds;

    }

    public void postNewGame(String name, int maxPlayerCount, int numCoins, double gameRadius, double gameDuration, @NonNull LocationRepresentation location) {
        List<Riddle> riddles = new ArrayList<>();
        List<Coin> coins = new ArrayList<>();
        Player player = new Player(user.getUserId(), user.getName(), 0);
        Location loc = new Location("");
        loc.setLatitude(location.getLatitude());
        loc.setLongitude(location.getLongitude());
        Game game = new Game(name, player, maxPlayerCount, riddles, coins, loc, true, numCoins, gameRadius, gameDuration);
        game.setId(user.getUserId());
        GameDatabaseProxy gdb = new GameDatabaseProxy();
        gdb.putGame(game);
        launchLobbyActivity(game.getId(), player);
    }


    private void launchLobbyActivity(String gameId, Player player) {
        Intent lobbyIntent = new Intent(activity.getApplicationContext(), GameLobbyActivity.class);
        lobbyIntent.putExtra(activity.getString(R.string.join_game_lobby_intent_extra_id), gameId);
        lobbyIntent.putExtra(activity.getString(R.string.join_game_lobby_intent_extra_user), player);
        lobbyIntent.putExtra(activity.getString(R.string.join_game_lobby_intent_extra_type_user), user);
        lobbyIntent.putExtra("locationMode", LOCATION_MODE);

        activity.startActivity(lobbyIntent);
        activity.finish();
    }
}