package com.vaguehope.onosendai.ui.pref;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import org.json.JSONException;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.DialogInterface.OnClickListener;
import android.os.Bundle;
import android.preference.Preference;
import android.preference.Preference.OnPreferenceClickListener;
import android.preference.PreferenceFragment;
import com.vaguehope.onosendai.config.Account;
import com.vaguehope.onosendai.config.Column;
import com.vaguehope.onosendai.config.ColumnFeed;
import com.vaguehope.onosendai.config.Config;
import com.vaguehope.onosendai.config.Prefs;
import com.vaguehope.onosendai.storage.DbInterface;
import com.vaguehope.onosendai.ui.pref.ColumnChooser.ColumnChoiceListener;
import com.vaguehope.onosendai.update.KvKeys;
import com.vaguehope.onosendai.util.DialogHelper;
import com.vaguehope.onosendai.util.LogWrapper;
public class ColumnsPrefFragment extends PreferenceFragment {
private static final LogWrapper LOG = new LogWrapper("CPF");
private Prefs prefs;
private ColumnChooser columnChooser;
@Override
public void onCreate (final Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setPreferenceScreen(getPreferenceManager().createPreferenceScreen(getActivity()));
this.prefs = new Prefs(getPreferenceManager());
refreshColumnsList();
this.columnChooser = new ColumnChooser(getActivity(), this.prefs, this.columnChoiceListener);
}
protected Prefs getPrefs () {
return this.prefs;
}
protected void refreshColumnsList () {
getPreferenceScreen().removeAll();
final Preference pref = new Preference(getActivity());
pref.setTitle("Add Column"); //ES
pref.setSummary("Add a new column of updates"); //ES
pref.setOnPreferenceClickListener(new AddAcountClickListener(this));
getPreferenceScreen().addPreference(pref);
try {
final Config config = getPrefs().asConfig();
for (final Column column : config.getColumns()) {
final List<Account> accounts = config.getAccounts(column.uniqAccountIds());
getPreferenceScreen().addPreference(new ColumnDialogPreference(getActivity(), column, accounts, this));
}
}
catch (final JSONException e) {
DialogHelper.alertAndClose(getActivity(), "Error reading preferences:", e);
}
}
private final ColumnChoiceListener columnChoiceListener = new ColumnChoiceListener() {
@Override
public void onColumn (final Account account, final String resource, final String title) {
promptAddColumn(account, resource, title);
}
};
protected void promptAddColumn () {
this.columnChooser.promptAddColumn();
}
protected void promptAddColumn (final Account account, final String resource, final String title) {
final int id = getPrefs().getNextColumnId();
final ColumnDialog dlg = new ColumnDialog(getActivity(), this.prefs, id);
if (resource != null) dlg.setFeeds(Collections.singleton(new ColumnFeed(account != null ? account.getId() : null, resource)));
if (title != null) dlg.setTitle(title);
final AlertDialog.Builder dlgBuilder = new AlertDialog.Builder(getActivity());
dlgBuilder.setTitle("New Column (" + id + ")"); //ES
dlgBuilder.setView(dlg.getRootView());
dlgBuilder.setPositiveButton(android.R.string.ok, new OnClickListener() {
@Override
public void onClick (final DialogInterface dialog, final int which) {
dialog.dismiss();
try {
final Column column = dlg.getValue();
getPrefs().writeNewColumn(column);
moveColumnToPosition(column, dlg.getPosition());
}
catch (final JSONException e) {
DialogHelper.alert(getActivity(), "Failed to write new column: ", e);
}
refreshColumnsList();
}
});
dlgBuilder.setNegativeButton("Cancel", DialogHelper.DLG_CANCEL_CLICK_LISTENER); //ES
dlgBuilder.create().show();
}
protected void moveColumnToPosition (final Column column, final int newPosition) {
this.prefs.moveColumnToPosition(column.getId(), newPosition);
}
protected void askDeleteColumn (final Column column) {
DialogHelper.askYesNo(getActivity(),
String.format("Delete the column %s and all its data?", column.getUiTitle()), //ES
new Runnable() {
@Override
public void run () {
try {
discardColumnFromExcludes(column);
deleteDataForColumn(column);
getPrefs().deleteColumn(column);
refreshColumnsList();
}
catch (final Exception e) { // NOSONAR Need to report errors.
DialogHelper.alert(getActivity(), e);
}
}
});
}
protected void discardColumnFromExcludes (final Column delCol) throws JSONException {
final Integer delColId = Integer.valueOf(delCol.getId());
for (final Column otherCol : this.prefs.readColumns()) {
if (delCol.getId() == otherCol.getId()) continue;
if (setContains(otherCol.getExcludeColumnIds(), delColId)) {
final Set<Integer> newExcludeColumnIds = copyOfSetWithout(otherCol.getExcludeColumnIds(), delColId);
this.prefs.writeUpdatedColumn(new Column(newExcludeColumnIds, otherCol));
}
}
}
protected void deleteDataForColumn (final Column column) {
final OsPreferenceActivity act = (OsPreferenceActivity) getActivity();
final DbInterface db = act.getDb();
if (db == null) throw new IllegalStateException("Database not bound, aborting column deletion.");
db.deleteTweets(column);
db.deleteValue(KvKeys.colLastPushTime(column));
db.deleteValue(KvKeys.colLastRefreshError(column));
db.deleteValue(KvKeys.colLastRefreshTime(column));
for (final ColumnFeed feed : column.getFeeds()) {
db.deleteValue(KvKeys.feedSinceId(column, feed));
}
LOG.i("Deleted: %s", column);
}
private static class AddAcountClickListener implements OnPreferenceClickListener {
private final ColumnsPrefFragment columnsPrefFragment;
public AddAcountClickListener (final ColumnsPrefFragment columnsPrefFragment) {
this.columnsPrefFragment = columnsPrefFragment;
}
@Override
public boolean onPreferenceClick (final Preference preference) {
this.columnsPrefFragment.promptAddColumn();
return true;
}
}
private static <T> boolean setContains (final Set<T> set, final T item) {
if (set == null) return false;
return set.contains(item);
}
private static <T> Set<T> copyOfSetWithout (final Set<T> set, final T item) {
final Set<T> newSet = new HashSet<T>(set);
if (!newSet.remove(item)) throw new IllegalStateException("Failed to remove " + set + " from " + newSet + ".");
return newSet;
}
}