package com.sloydev.preferator;
import android.content.Context;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.support.v4.app.ShareCompat;
import android.support.v4.util.Pair;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.PopupMenu;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import com.sloydev.preferator.editor.BooleanPrefEditor;
import com.sloydev.preferator.editor.FloatPrefEditor;
import com.sloydev.preferator.editor.IntPrefEditor;
import com.sloydev.preferator.editor.LongPrefEditor;
import com.sloydev.preferator.editor.SetPrefEditor;
import com.sloydev.preferator.editor.StringPrefEditor;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;
public class PreferatorActivity extends AppCompatActivity {
private static final String TAG = "Preferator";
private ViewGroup sectionsView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_prefereitor);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
sectionsView = (ViewGroup) findViewById(R.id.sections);
parsePreferences();
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
if (item.getItemId() == android.R.id.home) {
finish();
return true;
} else {
return super.onOptionsItemSelected(item);
}
}
private void parsePreferences() {
//TODO
String rootPath = this.getApplicationInfo().dataDir + "/shared_prefs";
File prefsFolder = new File(rootPath);
String[] children = prefsFolder.list();
if (children == null) {
//TODO
return;
}
for (int i = 0; i < children.length; i++) {
String prefFileName = children[i];
String prefName = prefFileName.endsWith(".xml")
? prefFileName.substring(0, prefFileName.indexOf(".xml"))
: prefFileName;
generateForm(prefName);
}
}
private void generateForm(String prefsName) {
SharedPreferences preferences = getSharedPreferences(prefsName);
List<Pair<String, ?>> entries = new ArrayList<>();
for (Map.Entry<String, ?> entry : preferences.getAll().entrySet()) {
Log.d(TAG, String.format("(%s) %s = %s", prefsName, entry.getKey(), entry.getValue().toString()));
entries.add(Pair.create(entry.getKey(), entry.getValue()));
}
addSection(prefsName, entries, preferences);
}
private void addSection(String sectionTitle, List<Pair<String, ?>> entries, final SharedPreferences preferences) {
final View sectionView = LayoutInflater.from(this).inflate(R.layout.item_section, sectionsView, false);
TextView sectionNameView = (TextView) sectionView.findViewById(R.id.section_name);
final ViewGroup itemsView = (ViewGroup) sectionView.findViewById(R.id.section_items);
sectionNameView.setText(sectionTitle);
for (final Pair<String, ?> pref : entries) {
final String prefKey = pref.first;
final Object prefValue = pref.second;
Type prefType = Type.of(prefValue);
final View itemView = LayoutInflater.from(this).inflate(R.layout.item_preference, itemsView, false);
TextView nameView = (TextView) itemView.findViewById(R.id.pref_name);
TextView typeView = (TextView) itemView.findViewById(R.id.pref_type);
View moreView = itemView.findViewById(R.id.pref_more);
nameView.setText(prefKey);
typeView.setText(prefType.name);
ViewGroup editorContainer = (ViewGroup) itemView.findViewById(R.id.pref_value_editor_container);
View editorView = createEditorView(preferences, prefKey, prefValue, prefType);
editorContainer.addView(editorView);
final PopupMenu moreOptionsMenu = new PopupMenu(this, moreView);
moreOptionsMenu.inflate(R.menu.pref_more_options);
moreOptionsMenu.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
@Override
public boolean onMenuItemClick(MenuItem item) {
if (item.getItemId() == R.id.menu_pref_delete) {
preferences.edit().remove(prefKey).apply();
itemsView.removeView(itemView);
return true;
} else if (item.getItemId() == R.id.menu_pref_share) {
String sharedMessage = String.format("\"%s\":\"%s\"", prefKey, prefValue.toString());
ShareCompat.IntentBuilder.from(PreferatorActivity.this)
.setText(sharedMessage)
.setType("text/plain")
.startChooser();
return true;
}
return false;
}
});
moreView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
moreOptionsMenu.show();
}
});
itemsView.addView(itemView);
}
sectionsView.addView(sectionView);
}
private View createEditorView(final SharedPreferences preferences, final String prefKey, Object prefValue, Type prefType) {
switch (prefType) {
case STRING:
return createStringEditorView(preferences, prefKey, (String) prefValue);
case INT:
return createIntEditorView(preferences, prefKey, (Integer) prefValue);
case LONG:
return createLongEditorView(preferences, prefKey, (Long) prefValue);
case FLOAT:
return createFloatEditorView(preferences, prefKey, (Float) prefValue);
case BOOLEAN:
return createBooleanEditorView(preferences, prefKey, (Boolean) prefValue);
case SET:
return createSetEditorView(preferences, prefKey, (Set<String>) prefValue);
}
throw new IllegalStateException("No editor view found for type " + prefType.name);
}
private StringPrefEditor createStringEditorView(final SharedPreferences preferences, final String prefKey, String prefValue) {
StringPrefEditor stringEditor = new StringPrefEditor(this);
stringEditor.setValue(prefValue);
stringEditor.setOnStringValueChangeListener(new StringPrefEditor.OnStringValueChangeListener() {
@Override
public void onValueChange(String newValue) {
preferences.edit().putString(prefKey, newValue).apply();
}
});
return stringEditor;
}
private IntPrefEditor createIntEditorView(final SharedPreferences preferences, final String prefKey, Integer prefValue) {
IntPrefEditor intEditor = new IntPrefEditor(this);
intEditor.setValue(prefValue);
intEditor.setOnIntValueChangeListener(new IntPrefEditor.OnIntValueChangeListener() {
@Override
public void onValueChange(Integer newValue) {
preferences.edit().putInt(prefKey, newValue).apply();
}
});
return intEditor;
}
private LongPrefEditor createLongEditorView(final SharedPreferences preferences, final String prefKey, Long prefValue) {
LongPrefEditor longEditor = new LongPrefEditor(this);
longEditor.setValue(prefValue);
longEditor.setOnLongValueChangeListener(new LongPrefEditor.OnLongValueChangeListener() {
@Override
public void onValueChange(Long newValue) {
preferences.edit().putLong(prefKey, newValue).apply();
}
});
return longEditor;
}
private FloatPrefEditor createFloatEditorView(final SharedPreferences preferences, final String prefKey, Float prefValue) {
FloatPrefEditor floatEditor = new FloatPrefEditor(this);
floatEditor.setValue(prefValue);
floatEditor.setOnFloatValueChangeListener(new FloatPrefEditor.OnFloatValueChangeListener() {
@Override
public void onValueChange(Float newValue) {
preferences.edit().putFloat(prefKey, newValue).apply();
}
});
return floatEditor;
}
private BooleanPrefEditor createBooleanEditorView(final SharedPreferences preferences, final String prefKey, Boolean prefValue) {
BooleanPrefEditor booleanEditor = new BooleanPrefEditor(this);
booleanEditor.setValue(prefValue);
booleanEditor.setOnBooleanValueChangeListener(new BooleanPrefEditor.OnBooleanValueChangeListener() {
@Override
public void onValueChange(Boolean newValue) {
preferences.edit().putBoolean(prefKey, newValue).apply();
}
});
return booleanEditor;
}
private SetPrefEditor createSetEditorView(final SharedPreferences preferences, final String prefKey, Set<String> prefValue) {
SetPrefEditor booleanEditor = new SetPrefEditor(this);
booleanEditor.setValue(prefValue);
booleanEditor.setOnSetValueChangeListener(new SetPrefEditor.OnSetValueChangeListener() {
@Override
public void onValueChange(Set<String> newValue) {
preferences.edit().putStringSet(prefKey, newValue).apply();
}
});
return booleanEditor;
}
private SharedPreferences getSharedPreferences(String name) {
return this.getSharedPreferences(name, Context.MODE_MULTI_PROCESS);
}
private enum Type {
BOOLEAN("boolean"),
INT("int"),
LONG("long"),
FLOAT("float"),
STRING("string"),
SET("set");
private final String name;
Type(String name) {
this.name = name;
}
public static Type of(Object value) {
if (value instanceof String) {
return STRING;
} else if (value instanceof Integer) {
return INT;
} else if (value instanceof Boolean) {
return BOOLEAN;
} else if (value instanceof Long) {
return LONG;
} else if (value instanceof Float) {
return FLOAT;
} else if (value instanceof Set) {
return SET;
} else {
throw new IllegalStateException("Not type matching found for " + value.getClass().getName());
}
}
}
}