package com.thomasdh.roosterpgplus.CustomUI;
import android.app.AlertDialog;
import android.app.AlertDialog.Builder;
import android.content.Context;
import android.content.DialogInterface;
import android.content.res.TypedArray;
import android.preference.ListPreference;
import android.support.annotation.NonNull;
import android.util.AttributeSet;
import android.widget.ListView;
import com.thomasdh.roosterpgplus.R;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
public class ListPreferenceMultiSelect extends ListPreference {
private static final String DEFAULT_SEPARATOR = "OV=I=XseparatorX=I=VO";
private final String separator;
private String checkAllKey = null;
private boolean[] mClickedDialogEntryIndices;
// Constructor
public ListPreferenceMultiSelect(Context context, AttributeSet attrs) {
super(context, attrs);
TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.ListPreferenceMultiSelect);
if (a != null) {
checkAllKey = a.getString(R.styleable.ListPreferenceMultiSelect_checkAll);
}
String s = a != null ? a.getString(R.styleable.ListPreferenceMultiSelect_separator) : null;
if (s != null) {
separator = s;
} else {
separator = DEFAULT_SEPARATOR;
}
// Initialize the array of boolean to the same size as number of entries
CharSequence[] entries = getEntries();
mClickedDialogEntryIndices = new boolean[entries != null ? entries.length : 0];
}
// Credits to kurellajunior on this post http://snippets.dzone.com/posts/show/91
protected static String join(Iterable<?> pColl, String separator) {
Iterator<?> oIter;
if (pColl == null || !(oIter = pColl.iterator()).hasNext())
return "";
StringBuilder oBuilder = new StringBuilder(String.valueOf(oIter.next()));
while (oIter.hasNext())
oBuilder.append(separator).append(oIter.next());
return oBuilder.toString();
}
public void setEntries(CharSequence[] entries, boolean[] enabled) {
setEntries(entries);
mClickedDialogEntryIndices = enabled;
}
@Override
public void setEntries(CharSequence[] entries) {
super.setEntries(entries);
// Initialize the array of boolean to the same size as number of entries
mClickedDialogEntryIndices = new boolean[entries.length];
}
@Override
protected void onPrepareDialogBuilder(@NonNull Builder builder) {
CharSequence[] entries = getEntries();
CharSequence[] entryValues = getEntryValues();
if (entries == null || entryValues == null || entries.length != entryValues.length) {
throw new IllegalStateException(
"ListPreference requires an entries array and an entryValues array which are both the same length");
}
restoreCheckedEntries();
builder.setMultiChoiceItems(entries, mClickedDialogEntryIndices,
(dialog, which, val) -> {
if (isCheckAllValue(which)) {
checkAll(dialog, val);
}
mClickedDialogEntryIndices[which] = val;
}
);
}
private boolean isCheckAllValue(int which) {
CharSequence[] entryValues = getEntryValues();
return checkAllKey != null && entryValues[which].equals(checkAllKey);
}
private void checkAll(DialogInterface dialog, boolean val) {
ListView lv = ((AlertDialog) dialog).getListView();
int size = lv.getCount();
for (int i = 0; i < size; i++) {
lv.setItemChecked(i, val);
mClickedDialogEntryIndices[i] = val;
}
}
public String[] parseStoredValue(CharSequence val) {
if ("".equals(val)) {
return null;
} else {
return ((String) val).split(separator);
}
}
private void restoreCheckedEntries() {
CharSequence[] entryValues = getEntryValues();
// Explode the string read in sharedpreferences
String[] vals = parseStoredValue(getValue());
if (vals != null) {
List<String> valuesList = Arrays.asList(vals);
// for ( int j=0; j<vals.length; j++ ) {
//
// String val = vals[j].trim();
for (int i = 0; i < entryValues.length; i++) {
CharSequence entry = entryValues[i];
if (valuesList.contains(entry)) {
mClickedDialogEntryIndices[i] = true;
}
}
// }
}
}
@Override
protected void onDialogClosed(boolean positiveResult) {
// super.onDialogClosed(positiveResult);
ArrayList<String> values = new ArrayList<>();
CharSequence[] entryValues = getEntryValues();
if (positiveResult && entryValues != null) {
for (int i = 0; i < entryValues.length; i++) {
if (mClickedDialogEntryIndices[i]) {
// Don't save the state of check all option - if any
String val = (String) entryValues[i];
if (checkAllKey == null || !val.equals(checkAllKey)) {
values.add(val);
}
}
}
if (callChangeListener(values)) {
setValue(join(values, separator));
}
}
}
}