/*
* Copyright (c) 2017
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
package jsettlers.main.android.mainmenu.ui.fragments.setup;
import java.util.List;
import org.androidannotations.annotations.AfterViews;
import org.androidannotations.annotations.Background;
import org.androidannotations.annotations.Click;
import org.androidannotations.annotations.EFragment;
import org.androidannotations.annotations.FragmentArg;
import org.androidannotations.annotations.ItemSelect;
import org.androidannotations.annotations.UiThread;
import org.androidannotations.annotations.ViewById;
import jsettlers.main.android.R;
import jsettlers.main.android.core.ui.FragmentUtil;
import jsettlers.main.android.core.ui.PreviewImageConverter;
import jsettlers.main.android.mainmenu.presenters.setup.MapSetupPresenter;
import jsettlers.main.android.mainmenu.presenters.setup.Peacetime;
import jsettlers.main.android.mainmenu.presenters.setup.PlayerCount;
import jsettlers.main.android.mainmenu.presenters.setup.StartResources;
import jsettlers.main.android.mainmenu.presenters.setup.playeritem.Civilisation;
import jsettlers.main.android.mainmenu.presenters.setup.playeritem.PlayerSlotPresenter;
import jsettlers.main.android.mainmenu.presenters.setup.playeritem.PlayerType;
import jsettlers.main.android.mainmenu.presenters.setup.playeritem.StartPosition;
import jsettlers.main.android.mainmenu.presenters.setup.playeritem.Team;
import jsettlers.main.android.mainmenu.views.MapSetupView;
import jsettlers.main.android.mainmenu.views.PlayerSlotView;
import android.graphics.Bitmap;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.SwitchCompat;
import android.support.v7.widget.Toolbar;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.ImageView;
import android.widget.Spinner;
import android.widget.TextView;
/**
* Created by tompr on 21/01/2017.
*/
@EFragment(R.layout.fragment_new_single_player_setup)
public abstract class MapSetupFragment<Presenter extends MapSetupPresenter> extends Fragment implements MapSetupView {
@ViewById(R.id.recycler_view)
RecyclerView recyclerView;
@ViewById(R.id.image_view_map_preview)
ImageView mapPreviewImageView;
@ViewById(R.id.toolbar)
Toolbar toolbar;
@ViewById(R.id.spinner_number_of_players)
protected Spinner numberOfPlayersSpinner;
@ViewById(R.id.spinner_start_resources)
protected Spinner startResourcesSpinner;
@ViewById(R.id.spinner_peacetime)
protected Spinner peacetimeSpinner;
@FragmentArg("mapid")
protected String mapId;
protected Presenter presenter;
PlayersAdapter adapter;
ArrayAdapter<PlayerCount> playerCountsAdapter;
ArrayAdapter<StartResources> startResourcesAdapter;
boolean isSaving = false;
protected abstract Presenter createPresenter();
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
presenter = createPresenter();
}
@AfterViews
void setupView() {
recyclerView.setHasFixedSize(true);
FragmentUtil.setActionBar(this, toolbar);
// Disable these for now, as these features are not implemented yet.
startResourcesSpinner.setEnabled(false);
peacetimeSpinner.setEnabled(false);
presenter.initView();
}
@Override
public void onResume() {
super.onResume();
presenter.updateViewTitle();
}
@Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
isSaving = true;
}
@Override
public void onDestroyView() {
super.onDestroyView();
presenter.dispose();
}
@Override
public void onDetach() {
super.onDetach();
if (isRemoving() && !isSaving) {
presenter.viewFinished();
}
}
@Click(R.id.button_start_game)
protected void onStartGameClicked() {
presenter.startGame();
}
@ItemSelect(R.id.spinner_number_of_players)
void playerSelected(boolean selected, int position) {
presenter.playerCountSelected(playerCountsAdapter.getItem(position));
}
@ItemSelect(R.id.spinner_start_resources)
void startResourcesSelected(boolean selected, int position) {
presenter.startResourcesSelected(startResourcesAdapter.getItem(position));
}
/**
* MapSetupView implementation
*/
@Override
public void setNumberOfPlayersOptions(PlayerCount[] numberOfPlayersOptions) {
playerCountsAdapter = getSpinnerAdapter(numberOfPlayersOptions);
numberOfPlayersSpinner.setAdapter(playerCountsAdapter);
}
@Override
public void setPlayerCount(PlayerCount playerCount) {
numberOfPlayersSpinner.setSelection(playerCountsAdapter.getPosition(playerCount));
}
@Override
public void setStartResourcesOptions(StartResources[] startResources) {
startResourcesAdapter = getSpinnerAdapter(startResources);
startResourcesSpinner.setAdapter(startResourcesAdapter);
}
@Override
public void setStartResources(StartResources startResources) {
startResourcesSpinner.setSelection(startResourcesAdapter.getPosition(startResources));
}
@Override
public void setPeaceTimeOptions(Peacetime[] peaceTimeOptions) {
peacetimeSpinner.setAdapter(getSpinnerAdapter(peaceTimeOptions));
}
@Override
public void setMapName(String mapName) {
getActivity().setTitle(mapName);
}
@Override
@Background
public void setMapImage(short[] image) {
setMapImage(PreviewImageConverter.convert(image));
}
@UiThread
public void setMapImage(Bitmap bitmap) {
if (mapPreviewImageView != null) {
mapPreviewImageView.setImageBitmap(bitmap);
}
}
private <T> ArrayAdapter<T> getSpinnerAdapter(T[] items) {
ArrayAdapter<T> adapter = new ArrayAdapter<>(getActivity(), android.R.layout.simple_spinner_item, items);
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
return adapter;
}
@Override
@UiThread
public void setItems(List<PlayerSlotPresenter> items, int playerCount) {
if (adapter == null) {
adapter = new PlayersAdapter(items);
}
if (recyclerView.getAdapter() == null) {
recyclerView.setAdapter(adapter);
}
adapter.setItems(items, playerCount);
}
protected int getListItemLayoutId() {
return R.layout.item_playerslot;
}
class PlayersAdapter extends RecyclerView.Adapter<PlayerHolder> {
private final LayoutInflater layoutInflater;
private List<PlayerSlotPresenter> players;
private int playerCount;
PlayersAdapter(List<PlayerSlotPresenter> players) {
this.layoutInflater = LayoutInflater.from(getActivity());
this.players = players;
}
@Override
public int getItemCount() {
return playerCount;
}
@Override
public PlayerHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = layoutInflater.inflate(getListItemLayoutId(), parent, false);
return new PlayerHolder(view);
}
@Override
public void onBindViewHolder(PlayerHolder holder, int position) {
holder.bind(players.get(position));
}
void setItems(List<PlayerSlotPresenter> items, int playerCount) {
// TODO use diffutil
this.players = items;
this.playerCount = playerCount;
notifyDataSetChanged();
}
}
class PlayerHolder extends RecyclerView.ViewHolder implements PlayerSlotView {
private PlayerSlotPresenter presenter;
private final TextView playerNameTextView;
private final SwitchCompat readySwitch;
private final Spinner civilisationSpinner;
private final Spinner playerTypeSpinner;
private final Spinner startPositionSpinner;
private final Spinner teamSpinner;
private ArrayAdapter<Civilisation> civilisationsAdapter;
private ArrayAdapter<PlayerType> playerTypesAdapter;
private ArrayAdapter<StartPosition> startPositionsAdapter;
private ArrayAdapter<Team> teamsAdapter;
PlayerHolder(View itemView) {
super(itemView);
this.playerNameTextView = (TextView) itemView.findViewById(R.id.text_view_player_name);
this.readySwitch = (SwitchCompat) itemView.findViewById(R.id.switch_ready);
this.civilisationSpinner = (Spinner) itemView.findViewById(R.id.spinner_civilisation);
this.playerTypeSpinner = (Spinner) itemView.findViewById(R.id.spinner_type);
this.startPositionSpinner = (Spinner) itemView.findViewById(R.id.spinner_slot);
this.teamSpinner = (Spinner) itemView.findViewById(R.id.spinner_team);
readySwitch.setOnCheckedChangeListener((compoundButton, checked) -> {
presenter.readyChanged(checked);
});
civilisationSpinner.setOnItemSelectedListener(new SpinnerListener() {
@Override
public void onItemSelected(AdapterView<?> adapterView, View view, int position, long id) {
Civilisation civilisation = civilisationsAdapter.getItem(position);
presenter.setCivilisation(civilisation);
}
});
playerTypeSpinner.setOnItemSelectedListener(new SpinnerListener() {
@Override
public void onItemSelected(AdapterView<?> adapterView, View view, int position, long id) {
PlayerType playerType = playerTypesAdapter.getItem(position);
presenter.setPlayerType(playerType);
}
});
startPositionSpinner.setOnItemSelectedListener(new SpinnerListener() {
@Override
public void onItemSelected(AdapterView<?> adapterView, View view, int position, long id) {
StartPosition slot = startPositionsAdapter.getItem(position);
presenter.startPositionSelected(slot);
}
});
teamSpinner.setOnItemSelectedListener(new SpinnerListener() {
@Override
public void onItemSelected(AdapterView<?> adapterView, View view, int position, long id) {
Team team = teamsAdapter.getItem(position);
presenter.teamSelected(team);
}
});
}
@Override
public void setName(String name) {
playerNameTextView.setText(name);
}
@Override
public void setReady(boolean ready) {
readySwitch.setChecked(ready);
}
@Override
public void setPossibleCivilisations(Civilisation[] possibleCivilisations) {
civilisationsAdapter = getSpinnerAdapter(possibleCivilisations);
civilisationSpinner.setAdapter(civilisationsAdapter);
}
@Override
public void setCivilisation(Civilisation civilisation) {
civilisationSpinner.setSelection(civilisationsAdapter.getPosition(civilisation));
}
@Override
public void setPossiblePlayerTypes(PlayerType[] ePlayerTypes) {
playerTypesAdapter = getSpinnerAdapter(ePlayerTypes);
playerTypeSpinner.setAdapter(playerTypesAdapter);
}
@Override
public void setPlayerType(PlayerType playerType) {
playerTypeSpinner.setSelection(playerTypesAdapter.getPosition(playerType));
}
@Override
public void setPossibleStartPositions(StartPosition[] possibleSlots) {
startPositionsAdapter = getSpinnerAdapter(possibleSlots);
startPositionSpinner.setAdapter(startPositionsAdapter);
}
@Override
public void setStartPosition(StartPosition slot) {
startPositionSpinner.setSelection(startPositionsAdapter.getPosition(slot));
}
@Override
public void setPossibleTeams(Team[] possibleTeams) {
teamsAdapter = getSpinnerAdapter(possibleTeams);
teamSpinner.setAdapter(teamsAdapter);
}
@Override
public void setTeam(Team team) {
teamSpinner.setSelection(teamsAdapter.getPosition(team));
}
@Override
public void showReadyControl() {
readySwitch.setVisibility(View.VISIBLE);
}
@Override
public void hideReadyControl() {
readySwitch.setVisibility(View.GONE);
}
@Override
public void setControlsEnabled() {
readySwitch.setClickable(true);
readySwitch.setFocusable(true);
playerTypeSpinner.setEnabled(true);
civilisationSpinner.setEnabled(true);
startPositionSpinner.setEnabled(true);
teamSpinner.setEnabled(true);
}
@Override
public void setControlsDisabled() {
readySwitch.setClickable(false);
readySwitch.setFocusable(false);
playerTypeSpinner.setEnabled(false);
civilisationSpinner.setEnabled(false);
startPositionSpinner.setEnabled(false);
teamSpinner.setEnabled(false);
}
void bind(PlayerSlotPresenter playerSlotPresenter) {
this.presenter = playerSlotPresenter;
playerSlotPresenter.initView(this);
}
}
private abstract class SpinnerListener implements AdapterView.OnItemSelectedListener {
@Override
public void onNothingSelected(AdapterView<?> adapterView) {
// No op
}
}
}