Alvaro2112/Money_run

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

Summary

Maintainability
A
0 mins
Test Coverage
A
95%
package sdp.moneyrun.menu.friendlist;

import android.annotation.SuppressLint;
import android.app.Activity;
import android.location.Location;
import android.location.LocationManager;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.TextView;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;

import com.google.android.gms.tasks.Task;
import com.google.firebase.database.DataSnapshot;
import com.google.firebase.database.FirebaseDatabase;

import java.util.HashMap;
import java.util.List;

import sdp.moneyrun.Helpers;
import sdp.moneyrun.R;
import sdp.moneyrun.database.game.GameDatabaseProxy;
import sdp.moneyrun.game.Game;
import sdp.moneyrun.game.GameRepresentation;
import sdp.moneyrun.location.AndroidLocationService;
import sdp.moneyrun.location.LocationRepresentation;
import sdp.moneyrun.menu.ListAdapterWithUser;
import sdp.moneyrun.menu.MenuImplementation;
import sdp.moneyrun.user.User;

@SuppressWarnings({"FieldCanBeLocal", "CanBeFinal"})
public class FriendListListAdapter extends ListAdapterWithUser {

    public static final String TAG_BUTTON_PREFIX = "button";
    private final AndroidLocationService locationService;
    private final String LOCATION_MODE = LocationManager.GPS_PROVIDER;
    @NonNull
    HashMap<Integer, Game> gamesByPosition = new HashMap<>();

    public FriendListListAdapter(Activity context, List<User> userList, User user, AndroidLocationService locationService) {
        super(context, userList, user);

        this.locationService = locationService;
    }

    @SuppressLint("ViewHolder")
    public View getView(int position, View view, ViewGroup parent) {
        view = LayoutInflater.from(getContext()).inflate(R.layout.friend_list_item_layout, parent, false);
        User userRequested = getItem(position);
        // Define game in hash map
        gamesByPosition.put(position, null);

        TextView userNameView = view.findViewById(R.id.friend_list_name);
        TextView playedView = view.findViewById(R.id.friend_list_n_played_result);
        TextView maxScoreView = view.findViewById(R.id.friend_list_logo_max_score_result);

        userNameView.setText(String.valueOf(userRequested.getName()));
        playedView.setText(String.valueOf(userRequested.getNumberOfPlayedGames()));
        maxScoreView.setText(String.valueOf(userRequested.getMaxScoreInGame()));

        //Define button
        Button button = view.findViewById(R.id.friend_list_join_game);
        Helpers.setInvalidButtonType(button);
        updateJoinButton(userRequested, button, position);

        //Define a tag to recognize the user.
        view.setTag(userRequested.getUserId());
        button.setTag(TAG_BUTTON_PREFIX + userRequested.getUserId());

        return view;
    }

    /**
     * Define the join game button as valid or invalid depending on predicates
     *
     * @param userRequested the friend that may have a game
     * @param button        the join button
     */
    private void updateJoinButton(@NonNull User userRequested,
                                  @NonNull Button button,
                                  int position) {
        Task<DataSnapshot> gameTask = getTaskFriendGame(userRequested, position);
        gameTask.addOnCompleteListener(task -> {
            Game friendGame = gamesByPosition.get(position);

            if (task.isSuccessful() && friendGameIsJoinable(friendGame)) {
                Helpers.setValidButtonType(button);
                button.setOnClickListener(v -> addFriendButtonImplementation(friendGame));
            }
        });
    }

    /**
     * @return true if the user can join the friend's game
     */
    private boolean friendGameIsJoinable(@Nullable Game friendGame) {
        if (friendGame == null) {
            return false;
        }

        Location gameLocation = friendGame.getStartLocation();
        if (gameLocation == null) {
            return false;
        }

        LocationRepresentation gameLocationRepr = new LocationRepresentation(gameLocation);
        LocationRepresentation userLocation = locationService.getCurrentLocation();
        if (userLocation == null) {
            return false;
        }

        double distance = gameLocationRepr.distanceTo(userLocation);
        return distance <= MenuImplementation.MAX_DISTANCE_TO_JOIN_GAME;
    }

    /**
     * Get the friend's game from database.
     *
     * @param requestedUser the user's friend
     * @return the task retrieving the friends task from database
     */
    @NonNull
    private Task<DataSnapshot> getTaskFriendGame(@NonNull User requestedUser, int position) {
        GameDatabaseProxy db = new GameDatabaseProxy();
        Task<DataSnapshot> gameTask = db.getGameDataSnapshot(requestedUser.getUserId());

        gameTask.addOnCompleteListener(task -> {
            try {
                gamesByPosition.put(position, db.getGameFromTaskSnapshot(task));
            } catch (IllegalArgumentException e) {
                gamesByPosition.put(position, null);
            }
        });

        return gameTask;
    }

    /**
     * Add button interaction to join game lobby
     */
    private void addFriendButtonImplementation(@Nullable Game friendGame) {
        if (friendGame == null) {
            return;
        }
        if (getCurrentUser() == null) {
            return;
        }

        LocationRepresentation gameLocationRep = new LocationRepresentation(friendGame.getStartLocation());

        GameRepresentation gameRepresentation = new GameRepresentation(friendGame.getId(),
                friendGame.getName(),
                friendGame.getPlayerCount(),
                friendGame.getMaxPlayerCount(),
                gameLocationRep);
        Helpers.joinLobbyFromJoinButton(gameRepresentation,
                FirebaseDatabase.getInstance().getReference(),
                (Activity) getContext(),
                getCurrentUser(),
                LOCATION_MODE);
    }
}