package com.boardgamegeek.ui.dialog;
import android.annotation.SuppressLint;
import android.app.Dialog;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.annotation.StringRes;
import android.support.v4.app.DialogFragment;
import android.support.v4.content.ContextCompat;
import android.support.v7.app.AlertDialog;
import android.util.Pair;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.BaseAdapter;
import android.widget.GridView;
import android.widget.TextView;
import com.boardgamegeek.R;
import com.boardgamegeek.util.ColorUtils;
import java.util.ArrayList;
import java.util.List;
import butterknife.BindView;
import butterknife.ButterKnife;
import butterknife.OnItemClick;
import butterknife.Unbinder;
import icepick.Icepick;
import icepick.State;
public class ColorPickerDialogFragment extends DialogFragment {
private static final String KEY_TITLE_ID = "title_id";
private static final String KEY_COLOR_COUNT = "color_count";
private static final String KEY_COLORS_DESCRIPTION = "colors_desc";
private static final String KEY_COLORS = "colors";
private static final String KEY_COLUMNS = "columns";
private Unbinder unbinder;
@BindView(R.id.color_grid) GridView colorGrid;
@BindView(R.id.featured_color_grid) GridView featuredColorGrid;
@BindView(R.id.hr) View divider;
private ColorGridAdapter colorGridAdapter;
private ColorGridAdapter featuredColorGridAdapter;
private List<Pair<String, Integer>> colorChoices = new ArrayList<>();
@State ArrayList<String> featuredColors = new ArrayList<>();
private int numberOfColumns = 3;
@State String selectedColor;
@State ArrayList<String> disabledColors;
@State ArrayList<String> hiddenColors;
@StringRes private int titleResId = 0;
private OnColorSelectedListener listener;
/**
* Constructor
*
* @param titleResId title resource id
* @param colors list of colors and their description
* @param featuredColors subset of the list of colors that should be featured above the rest
* @param selectedColor selected color
* @param disabledColors colors that should be displayed as disabled (but still selectable
* @param hiddenColors colors that should be hidden
* @param columns number of columns
* @return new ColorPickerDialog
*/
public static ColorPickerDialogFragment newInstance(@StringRes int titleResId,
List<Pair<String, Integer>> colors,
ArrayList<String> featuredColors,
String selectedColor,
ArrayList<String> disabledColors,
ArrayList<String> hiddenColors,
int columns) {
ColorPickerDialogFragment colorPicker = new ColorPickerDialogFragment();
colorPicker.initialize(titleResId, colors, featuredColors, selectedColor, disabledColors, hiddenColors, columns);
return colorPicker;
}
public void setArguments(int titleResId, int columns) {
Bundle bundle = new Bundle();
bundle.putInt(KEY_TITLE_ID, titleResId);
bundle.putInt(KEY_COLUMNS, columns);
setArguments(bundle);
}
/**
* Interface for a callback when a color square is selected.
*/
public interface OnColorSelectedListener {
/**
* Called when a specific color square has been selected.
*/
void onColorSelected(String description, int color);
}
public void setOnColorSelectedListener(OnColorSelectedListener listener) {
this.listener = listener;
}
private void initialize(@StringRes int titleResId,
List<Pair<String, Integer>> colors,
ArrayList<String> featuredColors,
String selectedColor,
ArrayList<String> disabledColors,
ArrayList<String> hiddenColors,
int columns) {
colorChoices = colors;
this.featuredColors = featuredColors;
numberOfColumns = columns;
this.selectedColor = selectedColor;
this.disabledColors = disabledColors;
this.hiddenColors = hiddenColors;
if (titleResId > 0) this.titleResId = titleResId;
setArguments(this.titleResId, numberOfColumns);
}
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (colorChoices.size() > 0) tryBindLists();
}
@Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
Icepick.saveInstanceState(this, outState);
outState.putInt(KEY_COLOR_COUNT, colorChoices.size());
for (int i = 0; i < colorChoices.size(); i++) {
Pair<String, Integer> color = colorChoices.get(i);
outState.putString(KEY_COLORS_DESCRIPTION + i, color.first);
outState.putInt(KEY_COLORS + i, color.second);
}
}
@Override
@NonNull
public Dialog onCreateDialog(Bundle savedInstanceState) {
LayoutInflater layoutInflater = LayoutInflater.from(getActivity());
@SuppressLint("InflateParams") View rootView = layoutInflater.inflate(R.layout.dialog_colors, null);
if (getArguments() != null) {
titleResId = getArguments().getInt(KEY_TITLE_ID);
numberOfColumns = getArguments().getInt(KEY_COLUMNS);
}
if (savedInstanceState != null) {
colorChoices = new ArrayList<>();
for (int i = 0; i < savedInstanceState.getInt(KEY_COLOR_COUNT); i++) {
colorChoices.add(new Pair<>(savedInstanceState.getString(KEY_COLORS_DESCRIPTION + i),
savedInstanceState.getInt(KEY_COLORS + i)));
}
}
Icepick.restoreInstanceState(this, savedInstanceState);
unbinder = ButterKnife.bind(this, rootView);
colorGrid.setNumColumns(numberOfColumns);
featuredColorGrid.setNumColumns(numberOfColumns);
tryBindLists();
divider.setVisibility(featuredColors == null ? View.GONE : View.VISIBLE);
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity(), R.style.Theme_bgglight_Dialog_Alert).setView(rootView);
if (titleResId > 0) {
builder.setTitle(titleResId);
}
return builder.create();
}
@Override
public void onDestroyView() {
super.onDestroyView();
if (unbinder != null) unbinder.unbind();
}
@SuppressWarnings("unused")
@OnItemClick({ R.id.color_grid, R.id.featured_color_grid })
public void onItemClick(AdapterView<?> listView, View view, int position, long itemId) {
if (listener != null) {
@SuppressWarnings("unchecked")
Pair<String, Integer> item = (Pair<String, Integer>) listView.getAdapter().getItem(position);
listener.onColorSelected(item.first, item.second);
}
dismiss();
}
private void tryBindLists() {
if (isAdded() && colorGridAdapter == null) {
ArrayList<Pair<String, Integer>> choices = new ArrayList<>(colorChoices);
if (hiddenColors != null) {
for (int i = colorChoices.size() - 1; i >= 0; i--) {
Pair<String, Integer> pair = choices.get(i);
if (hiddenColors.contains(pair.first)) {
choices.remove(i);
}
}
}
if (featuredColors == null) {
colorGridAdapter = new ColorGridAdapter(choices);
featuredColorGridAdapter = null;
} else {
ArrayList<Pair<String, Integer>> features = new ArrayList<>();
for (int i = colorChoices.size() - 1; i >= 0; i--) {
Pair<String, Integer> pair = choices.get(i);
if (featuredColors.contains(pair.first)) {
choices.remove(i);
features.add(0, pair);
}
}
colorGridAdapter = new ColorGridAdapter(choices);
featuredColorGridAdapter = new ColorGridAdapter(features);
}
}
if (colorGridAdapter != null && colorGrid != null) {
colorGridAdapter.setSelectedColor(selectedColor);
colorGrid.setAdapter(colorGridAdapter);
}
if (featuredColorGridAdapter != null && featuredColorGrid != null) {
featuredColorGridAdapter.setSelectedColor(selectedColor);
featuredColorGrid.setAdapter(featuredColorGridAdapter);
}
}
private class ColorGridAdapter extends BaseAdapter {
private List<Pair<String, Integer>> choices = new ArrayList<>();
private String selectedColor;
private ColorGridAdapter(List<Pair<String, Integer>> choices) {
this.choices = choices;
}
@Override
public int getCount() {
return choices.size();
}
@Override
public Pair<String, Integer> getItem(int position) {
return choices.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup container) {
if (convertView == null) {
convertView = LayoutInflater.from(getActivity()).inflate(R.layout.widget_color, container, false);
}
Pair<String, Integer> color = getItem(position);
((TextView) convertView.findViewById(R.id.color_description)).setText(color.first);
ColorUtils.setColorViewValue(convertView.findViewById(R.id.color_view), color.second);
View frame = convertView.findViewById(R.id.color_frame);
if (color.first.equals(selectedColor)) {
frame.setBackgroundColor(ContextCompat.getColor(getContext(), R.color.light_blue));
} else if (disabledColors != null && disabledColors.contains(color.first)) {
frame.setBackgroundColor(ContextCompat.getColor(getContext(), R.color.disabled));
}
return convertView;
}
public void setSelectedColor(String selectedColor) {
if (this.selectedColor == null ||
!this.selectedColor.equals(selectedColor)) {
this.selectedColor = selectedColor;
notifyDataSetChanged();
}
}
}
}