package dan.dit.whatsthat.testsubject; import android.content.SharedPreferences; import android.support.annotation.NonNull; import android.support.annotation.Nullable; import android.text.TextUtils; import android.util.Log; import java.util.ArrayList; import java.util.Comparator; import java.util.Iterator; import java.util.List; import java.util.Random; import dan.dit.whatsthat.riddle.types.PracticalRiddleType; import dan.dit.whatsthat.util.compaction.CompactedDataCorruptException; import dan.dit.whatsthat.util.compaction.Compacter; /** * Created by daniel on 07.01.16. */ public class TestSubjectRiddleTypeController implements TestSubjectRiddleType.OnChangedListener { private static final String TEST_SUBJECT_PREF_RIDDLE_TYPES = "key_testsubject_riddletypes"; public static final Comparator<PracticalRiddleType> TYPE_COMPARATOR = new Comparator<PracticalRiddleType>() { @Override public int compare(PracticalRiddleType t1, PracticalRiddleType t2) { if (t1.equals(t2)) { return 0; } else if (TestSubject.isInitialized()) { List<TestSubjectRiddleType> sortedTypes = TestSubject.getInstance() .getTypesController().getAll(); int index = 0; int pos1 = 0; int pos2 = 0; for (TestSubjectRiddleType type : sortedTypes) { if (type.getType().equals(t1)) { pos1 = index; } else if (type.getType().equals(t2)) { pos2 = index; } index++; } return pos1 - pos2; } else { return t1.getFullName().compareTo(t2.getFullName()); } } }; private final SharedPreferences mPrefs; private List<TestSubjectRiddleType> mTypes = new ArrayList<>(PracticalRiddleType .ALL_PLAYABLE_TYPES.size()); private final Random mRand = new Random(); public TestSubjectRiddleTypeController(SharedPreferences prefs) { mPrefs = prefs; init(mPrefs.getString(TEST_SUBJECT_PREF_RIDDLE_TYPES, null)); } private void init(String typesDataRaw) { Compacter typesData = TextUtils.isEmpty(typesDataRaw) ? null : new Compacter(typesDataRaw); if (typesData != null) { for (String typeRaw : typesData) { try { TestSubjectRiddleType type = new TestSubjectRiddleType(new Compacter(typeRaw) , this); if (!mTypes.contains(type)) { mTypes.add(type); } } catch (CompactedDataCorruptException e) { Log.e("HomeStuff", "Could not load testsubject riddle type: " + e); } } } } public @Nullable PracticalRiddleType findNextRiddleType(boolean selectedTypesOnly, PracticalRiddleType exclude) { List<TestSubjectRiddleType> types = new ArrayList<>(mTypes); Iterator<TestSubjectRiddleType> it = types.iterator(); while (it.hasNext()) { TestSubjectRiddleType next = it.next(); if ((selectedTypesOnly && !next.isSelected()) || (exclude != null && next.getType().equals(exclude))) { it.remove(); } } if (types.size() > 0) { return types.get(mRand.nextInt(types.size())).getType(); } else { return null; } } public @NonNull PracticalRiddleType findNextRiddleType() { PracticalRiddleType type = findNextRiddleType(true, null); if (type == null) { // nothing was selected, ignore selection type = findNextRiddleType(false, null); } // if still null there were no riddle types, but we want to always return a valid one return type == null ? PracticalRiddleType.CIRCLE_INSTANCE : type; } public boolean isTypeAvailable(PracticalRiddleType type) { if (type == null) { return false; } for (TestSubjectRiddleType testType : mTypes) { if (testType.getType().equals(type)) { return true; } } return false; } public void saveTypes() { if (mTypes != null) { Compacter typesData = new Compacter(mTypes.size()); for (TestSubjectRiddleType type : mTypes) { typesData.appendData(type.compact()); } mPrefs.edit().putString(TEST_SUBJECT_PREF_RIDDLE_TYPES, typesData.compact()).apply(); } } List<TestSubjectRiddleType> getAll() { return mTypes; } boolean addNewType(PracticalRiddleType type) { for (TestSubjectRiddleType currType : mTypes) { if (currType.getType().equals(type)) { return false; } } mTypes.add(new TestSubjectRiddleType(type, this)); return true; } public int getCount() { return mTypes.size(); } @Override public void onSelectedChanged(TestSubjectRiddleType changed) { saveTypes(); } }