

package org.odk.collect.android.preferences;

import android.accounts.Account;
import android.accounts.AccountManager;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
import android.net.Uri;
import android.os.Bundle;
import android.preference.CheckBoxPreference;
import android.preference.EditTextPreference;
import android.preference.ListPreference;
import android.preference.Preference;
import android.preference.Preference.OnPreferenceChangeListener;
import android.preference.Preference.OnPreferenceClickListener;
import android.preference.PreferenceActivity;
import android.preference.PreferenceCategory;
import android.preference.PreferenceManager;
import android.preference.PreferenceScreen;
import android.provider.MediaStore.Images;
import android.text.InputFilter;
import android.text.Spanned;

import org.javarosa.core.services.IPropertyManager;
import org.odk.collect.android.R;
import org.odk.collect.android.activities.OpenSourceLicensesActivity;
import org.odk.collect.android.logic.FormController;
import org.odk.collect.android.logic.PropertyManager;
import org.odk.collect.android.utilities.MediaUtils;

import java.util.ArrayList;

/**
 * Handles general preferences.
 *
 * @author Thomas Smyth, Sassafras Tech Collective (tom@sassafrastech.com;
 *         constraint behavior option)
 */
public class PreferencesActivity extends PreferenceActivity implements OnPreferenceChangeListener {

    public static final String INTENT_KEY_ADMIN_MODE = "adminMode";
    protected static final int IMAGE_CHOOSER = 0;

    // PUT ALL PREFERENCE KEYS HERE
    public static final String KEY_LAST_VERSION = "lastVersion";
    public static final String KEY_FIRST_RUN = "firstRun";
    public static final String KEY_SHOW_SPLASH = "showSplash";
    public static final String KEY_SPLASH_PATH = "splashPath";
    public static final String KEY_FONT_SIZE = "font_size";
    public static final String KEY_DELETE_AFTER_SEND = "delete_send";

    public static final String KEY_PROTOCOL = "protocol";
    public static final String KEY_OPEN_SOURCE_LICENSES = "open_source_licenses";
    public static final String KEY_PROTOCOL_SETTINGS = "protocol_settings";

    // leaving these in the main screen because username can be used as a
    // pre-fill
    // value in a form
    public static final String KEY_SELECTED_GOOGLE_ACCOUNT = "selected_google_account";
    public static final String KEY_USERNAME = "username";
    public static final String KEY_PASSWORD = "password";

    // AGGREGATE SPECIFIC
    public static final String KEY_SERVER_URL = "server_url";

    // GOOGLE SPECIFIC
    public static final String KEY_GOOGLE_SHEETS_URL = "google_sheets_url";

    // OTHER SPECIFIC
    public static final String KEY_FORMLIST_URL = "formlist_url";
    public static final String KEY_SUBMISSION_URL = "submission_url";

    public static final String NAVIGATION_SWIPE = "swipe";
    public static final String NAVIGATION_BUTTONS = "buttons";

    public static final String CONSTRAINT_BEHAVIOR_ON_SWIPE = "on_swipe";
    public static final String CONSTRAINT_BEHAVIOR_DEFAULT = "on_swipe";

    public static final String KEY_COMPLETED_DEFAULT = "default_completed";

    public static final String KEY_HIGH_RESOLUTION = "high_resolution";

    public static final String KEY_AUTOSEND_WIFI = "autosend_wifi";
    public static final String KEY_AUTOSEND_NETWORK = "autosend_network";

    public static final String KEY_NAVIGATION = "navigation";
    public static final String KEY_CONSTRAINT_BEHAVIOR = "constraint_behavior";

    // MAP SPECIFIC

    public static final String KEY_MAP_SDK = "map_sdk_behavior";
    public static final String KEY_MAP_BASEMAP = "map_basemap_behavior";

    public static final int ARRAY_INDEX_GOOGLE_MAPS = 0;
    public static final int ARRAY_INDEX_OSM_MAPS = 1;
    public static final String OSM_BASEMAP_KEY = "osmdroid";
    public static final String GOOGLE_MAPS_BASEMAP_DEFAULT = "streets";
    public static final String OSM_MAPS_BASEMAP_DEFAULT = "mapquest_streets";


    private PreferenceScreen mSplashPathPreference;
    private PreferenceScreen mOpenSourceLicensesPreference;
    private ListPreference mSelectedGoogleAccountPreference;
    private ListPreference mFontSizePreference;
    private ListPreference mNavigationPreference;
    private ListPreference mConstraintBehaviorPreference;
    private CheckBoxPreference mAutosendWifiPreference;
    private CheckBoxPreference mAutosendNetworkPreference;
    private ListPreference mProtocolPreference;
    private PreferenceScreen mProtocolSettings;
    protected EditTextPreference mUsernamePreference;
    protected EditTextPreference mPasswordPreference;

    protected ListPreference mMapSdk;
    protected ListPreference mMapBasemap;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        addPreferencesFromResource(R.xml.preferences);

        setTitle(getString(R.string.app_name) + " > " + getString(R.string.general_preferences));

        // not super safe, but we're just putting in this mode to help
        // administrate
        // would require code to access it
        final boolean adminMode = getIntent().getBooleanExtra(INTENT_KEY_ADMIN_MODE, false);

        SharedPreferences adminPreferences = getSharedPreferences(
                AdminPreferencesActivity.ADMIN_PREFERENCES, 0);

        // assign all the preferences in advance because changing one often
        // affects another
        // also avoids npe
        PreferenceCategory autosendCategory = (PreferenceCategory) findPreference(
                getString(R.string.autosend));
        mAutosendWifiPreference = (CheckBoxPreference) findPreference(KEY_AUTOSEND_WIFI);
        mAutosendNetworkPreference = (CheckBoxPreference) findPreference(KEY_AUTOSEND_NETWORK);
        PreferenceCategory serverCategory = (PreferenceCategory) findPreference(
                getString(R.string.server_preferences));

        mProtocolPreference = (ListPreference) findPreference(KEY_PROTOCOL);

        mSelectedGoogleAccountPreference = (ListPreference) findPreference(
                KEY_SELECTED_GOOGLE_ACCOUNT);
        PreferenceCategory clientCategory = (PreferenceCategory) findPreference(
                getString(R.string.client));
        PreferenceCategory mapCategory = (PreferenceCategory) findPreference(
                getString(R.string.map_preferences));
        mNavigationPreference = (ListPreference) findPreference(KEY_NAVIGATION);
        mFontSizePreference = (ListPreference) findPreference(KEY_FONT_SIZE);
        Preference defaultFinalized = findPreference(KEY_COMPLETED_DEFAULT);
        Preference deleteAfterSend = findPreference(KEY_DELETE_AFTER_SEND);
        mSplashPathPreference = (PreferenceScreen) findPreference(KEY_SPLASH_PATH);
        mConstraintBehaviorPreference = (ListPreference) findPreference(KEY_CONSTRAINT_BEHAVIOR);

        mUsernamePreference = (EditTextPreference) findPreference(PreferencesActivity.KEY_USERNAME);
        mPasswordPreference = (EditTextPreference) findPreference(PreferencesActivity.KEY_PASSWORD);

        mProtocolSettings = (PreferenceScreen) findPreference(KEY_PROTOCOL_SETTINGS);
        mOpenSourceLicensesPreference = (PreferenceScreen) findPreference(KEY_OPEN_SOURCE_LICENSES);

        mMapSdk = (ListPreference) findPreference(KEY_MAP_SDK);
        mMapBasemap = (ListPreference) findPreference(KEY_MAP_BASEMAP);

        boolean autosendWifiAvailable = adminPreferences.getBoolean(
                AdminPreferencesActivity.KEY_AUTOSEND_WIFI, true);
        if (!(autosendWifiAvailable || adminMode)) {
            autosendCategory.removePreference(mAutosendWifiPreference);
        }

        boolean autosendNetworkAvailable = adminPreferences.getBoolean(
                AdminPreferencesActivity.KEY_AUTOSEND_NETWORK, true);
        if (!(autosendNetworkAvailable || adminMode)) {
            autosendCategory.removePreference(mAutosendNetworkPreference);
        }

        if (!(autosendNetworkAvailable || autosendWifiAvailable || adminMode)) {
            getPreferenceScreen().removePreference(autosendCategory);
        }

        mProtocolPreference = (ListPreference) findPreference(KEY_PROTOCOL);
        mProtocolPreference.setSummary(mProtocolPreference.getEntry());
        Intent prefIntent = null;

        if (mProtocolPreference.getValue().equals(getString(R.string.protocol_odk_default))) {
            setDefaultAggregatePaths();
            prefIntent = new Intent(this, AggregatePreferencesActivity.class);
        } else if (mProtocolPreference.getValue().equals(
                getString(R.string.protocol_google_sheets))) {
            prefIntent = new Intent(this, GooglePreferencesActivity.class);
        } else {
            // other
            prefIntent = new Intent(this, OtherPreferencesActivity.class);
        }
        prefIntent.putExtra(INTENT_KEY_ADMIN_MODE, adminMode);
        mProtocolSettings.setIntent(prefIntent);

        mProtocolPreference.setOnPreferenceChangeListener(new OnPreferenceChangeListener() {

            @Override
            public boolean onPreferenceChange(Preference preference, Object newValue) {
                String oldValue = ((ListPreference) preference).getValue();
                int index = ((ListPreference) preference).findIndexOfValue(newValue.toString());
                String entry = (String) ((ListPreference) preference).getEntries()[index];
                String value = (String) ((ListPreference) preference).getEntryValues()[index];
                ((ListPreference) preference).setSummary(entry);

                Intent prefIntent = null;
                if (value.equals(getString(R.string.protocol_odk_default))) {
                    setDefaultAggregatePaths();
                    prefIntent = new Intent(PreferencesActivity.this,
                            AggregatePreferencesActivity.class);
                } else if (value.equals(getString(R.string.protocol_google_sheets))) {
                    prefIntent = new Intent(PreferencesActivity.this,
                            GooglePreferencesActivity.class);
                } else {
                    // other
                    prefIntent = new Intent(PreferencesActivity.this,
                            OtherPreferencesActivity.class);
                }
                prefIntent.putExtra(INTENT_KEY_ADMIN_MODE, adminMode);
                mProtocolSettings.setIntent(prefIntent);

                if (!((String) newValue).equals(oldValue)) {
                    startActivity(prefIntent);
                }

                return true;
            }
        });

        boolean changeProtocol = adminPreferences.getBoolean(
                AdminPreferencesActivity.KEY_CHANGE_SERVER, true);
        if (!(changeProtocol || adminMode)) {
            serverCategory.removePreference(mProtocolPreference);
        }
        boolean changeProtocolSettings = adminPreferences.getBoolean(
                AdminPreferencesActivity.KEY_CHANGE_PROTOCOL_SETTINGS, true);
        if (!(changeProtocolSettings || adminMode)) {
            serverCategory.removePreference(mProtocolSettings);
        }

        // get list of google accounts
        final Account[] accounts = AccountManager.get(getApplicationContext()).getAccountsByType(
                "com.google");
        ArrayList<String> accountEntries = new ArrayList<String>();
        ArrayList<String> accountValues = new ArrayList<String>();

        for (int i = 0; i < accounts.length; i++) {
            accountEntries.add(accounts[i].name);
            accountValues.add(accounts[i].name);
        }
        accountEntries.add(getString(R.string.no_account));
        accountValues.add("");

        mSelectedGoogleAccountPreference.setEntries(accountEntries.toArray(new String[accountEntries
                .size()]));
        mSelectedGoogleAccountPreference.setEntryValues(
                accountValues.toArray(new String[accountValues
                        .size()]));
        mSelectedGoogleAccountPreference
                .setOnPreferenceChangeListener(new OnPreferenceChangeListener() {

                    @Override
                    public boolean onPreferenceChange(Preference preference, Object newValue) {
                        int index = ((ListPreference) preference).findIndexOfValue(
                                newValue.toString());
                        String value =
                                (String) ((ListPreference) preference).getEntryValues()[index];
                        ((ListPreference) preference).setSummary(value);
                        return true;
                    }
                });
        mSelectedGoogleAccountPreference.setSummary(mSelectedGoogleAccountPreference.getValue());

        boolean googleAccountAvailable = adminPreferences.getBoolean(
                AdminPreferencesActivity.KEY_CHANGE_GOOGLE_ACCOUNT, true);
        if (!(googleAccountAvailable || adminMode)) {
            serverCategory.removePreference(mSelectedGoogleAccountPreference);
        }

        mUsernamePreference.setOnPreferenceChangeListener(this);
        mUsernamePreference.setSummary(mUsernamePreference.getText());
        mUsernamePreference.getEditText().setFilters(new InputFilter[]{getReturnFilter()});

        boolean usernameAvailable = adminPreferences.getBoolean(
                AdminPreferencesActivity.KEY_CHANGE_USERNAME, true);
        if (!(usernameAvailable || adminMode)) {
            serverCategory.removePreference(mUsernamePreference);
        }

        mPasswordPreference.setOnPreferenceChangeListener(new OnPreferenceChangeListener() {
            @Override
            public boolean onPreferenceChange(Preference preference, Object newValue) {
                String pw = newValue.toString();

                if (pw.length() > 0) {
                    mPasswordPreference.setSummary("********");
                } else {
                    mPasswordPreference.setSummary("");
                }
                return true;
            }
        });
        if (mPasswordPreference.getText() != null && mPasswordPreference.getText().length() > 0) {
            mPasswordPreference.setSummary("********");
        }
        mPasswordPreference.getEditText().setFilters(new InputFilter[]{getReturnFilter()});

        boolean passwordAvailable = adminPreferences.getBoolean(
                AdminPreferencesActivity.KEY_CHANGE_PASSWORD, true);
        if (!(passwordAvailable || adminMode)) {
            serverCategory.removePreference(mPasswordPreference);
        }

        boolean navigationAvailable = adminPreferences.getBoolean(
                AdminPreferencesActivity.KEY_NAVIGATION, true);
        mNavigationPreference.setSummary(mNavigationPreference.getEntry());
        mNavigationPreference.setOnPreferenceChangeListener(new OnPreferenceChangeListener() {

            @Override
            public boolean onPreferenceChange(Preference preference, Object newValue) {
                int index = ((ListPreference) preference).findIndexOfValue(newValue.toString());
                String entry = (String) ((ListPreference) preference).getEntries()[index];
                ((ListPreference) preference).setSummary(entry);
                return true;
            }
        });
        if (!(navigationAvailable || adminMode)) {
            clientCategory.removePreference(mNavigationPreference);
        }

        boolean constraintBehaviorAvailable = adminPreferences.getBoolean(
                AdminPreferencesActivity.KEY_CONSTRAINT_BEHAVIOR, true);
        mConstraintBehaviorPreference.setSummary(mConstraintBehaviorPreference.getEntry());
        mConstraintBehaviorPreference.setOnPreferenceChangeListener(
                new OnPreferenceChangeListener() {

                    @Override
                    public boolean onPreferenceChange(Preference preference, Object newValue) {
                        int index = ((ListPreference) preference).findIndexOfValue(
                                newValue.toString());
                        String entry = (String) ((ListPreference) preference).getEntries()[index];
                        ((ListPreference) preference).setSummary(entry);
                        return true;
                    }
                });
        if (!(constraintBehaviorAvailable || adminMode)) {
            clientCategory.removePreference(mConstraintBehaviorPreference);
        }

        boolean fontAvailable = adminPreferences.getBoolean(
                AdminPreferencesActivity.KEY_CHANGE_FONT_SIZE, true);
        mFontSizePreference.setSummary(mFontSizePreference.getEntry());
        mFontSizePreference.setOnPreferenceChangeListener(new OnPreferenceChangeListener() {

            @Override
            public boolean onPreferenceChange(Preference preference, Object newValue) {
                int index = ((ListPreference) preference).findIndexOfValue(newValue.toString());
                String entry = (String) ((ListPreference) preference).getEntries()[index];
                ((ListPreference) preference).setSummary(entry);
                return true;
            }
        });
        if (!(fontAvailable || adminMode)) {
            clientCategory.removePreference(mFontSizePreference);
        }

        boolean defaultAvailable = adminPreferences.getBoolean(
                AdminPreferencesActivity.KEY_DEFAULT_TO_FINALIZED, true);

        if (!(defaultAvailable || adminMode)) {
            clientCategory.removePreference(defaultFinalized);
        }

        boolean deleteAfterAvailable = adminPreferences.getBoolean(
                AdminPreferencesActivity.KEY_DELETE_AFTER_SEND, true);
        if (!(deleteAfterAvailable || adminMode)) {
            clientCategory.removePreference(deleteAfterSend);
        }

        boolean resolutionAvailable = adminPreferences.getBoolean(
                AdminPreferencesActivity.KEY_HIGH_RESOLUTION, true);

        Preference highResolution = findPreference(KEY_HIGH_RESOLUTION);
        if (!(resolutionAvailable || adminMode)) {
            clientCategory.removePreference(highResolution);
        }

        mOpenSourceLicensesPreference.setOnPreferenceClickListener(new OnPreferenceClickListener() {
            @Override
            public boolean onPreferenceClick(Preference preference) {
                startActivity(new Intent(getApplicationContext(), OpenSourceLicensesActivity.class));
                return true;
            }
        });

        mSplashPathPreference.setOnPreferenceClickListener(new OnPreferenceClickListener() {

            private void launchImageChooser() {
                Intent i = new Intent(Intent.ACTION_GET_CONTENT);
                i.setType("image/*");
                startActivityForResult(i, PreferencesActivity.IMAGE_CHOOSER);
            }

            @Override
            public boolean onPreferenceClick(Preference preference) {
                // if you have a value, you can clear it or select new.
                CharSequence cs = mSplashPathPreference.getSummary();
                if (cs != null && cs.toString().contains("/")) {

                    final CharSequence[] items = {getString(R.string.select_another_image),
                            getString(R.string.use_odk_default)};

                    AlertDialog.Builder builder = new AlertDialog.Builder(PreferencesActivity.this);
                    builder.setTitle(getString(R.string.change_splash_path));
                    builder.setNeutralButton(getString(R.string.cancel),
                            new DialogInterface.OnClickListener() {
                                @Override
                                public void onClick(DialogInterface dialog, int id) {
                                    dialog.dismiss();
                                }
                            });
                    builder.setItems(items, new DialogInterface.OnClickListener() {
                        @Override
                        public void onClick(DialogInterface dialog, int item) {
                            if (items[item].equals(getString(R.string.select_another_image))) {
                                launchImageChooser();
                            } else {
                                setSplashPath(getString(R.string.default_splash_path));
                            }
                        }
                    });
                    AlertDialog alert = builder.create();
                    alert.show();

                } else {
                    launchImageChooser();
                }

                return true;
            }
        });

        mSplashPathPreference.setSummary(mSplashPathPreference.getSharedPreferences().getString(
                KEY_SPLASH_PATH, getString(R.string.default_splash_path)));

        boolean showSplashAvailable = adminPreferences.getBoolean(
                AdminPreferencesActivity.KEY_SHOW_SPLASH_SCREEN, true);

        CheckBoxPreference showSplashPreference = (CheckBoxPreference) findPreference(
                KEY_SHOW_SPLASH);

        if (!(showSplashAvailable || adminMode)) {
            clientCategory.removePreference(showSplashPreference);
            clientCategory.removePreference(mSplashPathPreference);
        }

        if (!(fontAvailable || defaultAvailable || showSplashAvailable || navigationAvailable
                || adminMode || resolutionAvailable)) {
            getPreferenceScreen().removePreference(clientCategory);
        }

        // MAP SPECIFIC
        boolean mMapSdkAvailable = adminPreferences.getBoolean(
                AdminPreferencesActivity.KEY_SHOW_MAP_SDK, true);
        mMapSdk.setSummary(mMapSdk.getEntry());
        mMapSdk.setOnPreferenceChangeListener(new OnPreferenceChangeListener() {

            @Override
            public boolean onPreferenceChange(Preference preference, Object newValue) {

                int index = ((ListPreference) preference).findIndexOfValue(newValue.toString());
                if (index == ARRAY_INDEX_GOOGLE_MAPS) {
                    mMapBasemap.setEntryValues(R.array.map_google_basemap_selector_entry_values);
                    mMapBasemap.setEntries(R.array.map_google_basemap_selector_entries);
                    mMapBasemap.setValue(GOOGLE_MAPS_BASEMAP_DEFAULT);
                    mMapBasemap.setSummary(mMapBasemap.getEntry());
                } else {
                    // Else its OSM Maps
                    mMapBasemap.setEntryValues(R.array.map_osm_basemap_selector_entry_values);
                    mMapBasemap.setEntries(R.array.map_osm_basemap_selector_entries);
                    mMapBasemap.setValue(OSM_MAPS_BASEMAP_DEFAULT);
                    mMapBasemap.setSummary(mMapBasemap.getEntry());
                }

                String entry = (String) ((ListPreference) preference).getEntries()[index];
                ((ListPreference) preference).setSummary(entry);
                return true;
            }
        });

        if (!(mMapSdkAvailable || adminMode)) {
            mapCategory.removePreference(mMapSdk);
        }

        boolean mMapBasemapAvailable = adminPreferences.getBoolean(
                AdminPreferencesActivity.KEY_SHOW_MAP_BASEMAP, true);

        if (mMapSdk.getValue().equals(OSM_BASEMAP_KEY)) {
            mMapBasemap.setEntryValues(R.array.map_osm_basemap_selector_entry_values);
            mMapBasemap.setEntries(R.array.map_osm_basemap_selector_entries);
        } else {
            mMapBasemap.setEntryValues(R.array.map_google_basemap_selector_entry_values);
            mMapBasemap.setEntries(R.array.map_google_basemap_selector_entries);
        }
        mMapBasemap.setSummary(mMapBasemap.getEntry());
        mMapBasemap.setOnPreferenceChangeListener(new OnPreferenceChangeListener() {
            @Override
            public boolean onPreferenceChange(Preference preference, Object newValue) {
                int index = ((ListPreference) preference).findIndexOfValue(newValue.toString());
                String entry = (String) ((ListPreference) preference).getEntries()[index];
                ((ListPreference) preference).setSummary(entry);
                return true;
            }
        });
        if (!(mMapBasemapAvailable || adminMode)) {
            mapCategory.removePreference(mMapBasemap);
        }
    }

    @Override
    protected void onPause() {
        super.onPause();

        // the property manager should be re-assigned, as properties
        // may have changed.
        IPropertyManager mgr = new PropertyManager(this);
        FormController.initializeJavaRosa(mgr);
    }

    @Override
    protected void onResume() {
        super.onResume();

        // has to go in onResume because it may get updated by
        // a sub-preference screen
        // this just keeps the widgets in sync
        SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(this);
        String account = sp.getString(KEY_SELECTED_GOOGLE_ACCOUNT, "");
        mSelectedGoogleAccountPreference.setSummary(account);
        mSelectedGoogleAccountPreference.setValue(account);

        String user = sp.getString(KEY_USERNAME, "");
        String pw = sp.getString(KEY_PASSWORD, "");
        mUsernamePreference.setSummary(user);
        mUsernamePreference.setText(user);
        if (pw != null && pw.length() > 0) {
            mPasswordPreference.setSummary("********");
            mPasswordPreference.setText(pw);
        }

    }

    private void setSplashPath(String path) {
        SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this);
        Editor editor = sharedPreferences.edit();
        editor.putString(KEY_SPLASH_PATH, path);
        editor.commit();

        mSplashPathPreference = (PreferenceScreen) findPreference(KEY_SPLASH_PATH);
        mSplashPathPreference.setSummary(mSplashPathPreference.getSharedPreferences().getString(
                KEY_SPLASH_PATH, getString(R.string.default_splash_path)));
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent intent) {
        super.onActivityResult(requestCode, resultCode, intent);
        if (resultCode == RESULT_CANCELED) {
            // request was canceled, so do nothing
            return;
        }

        switch (requestCode) {
            case IMAGE_CHOOSER:

                // get gp of chosen file
                Uri selectedMedia = intent.getData();
                String sourceMediaPath = MediaUtils.getPathFromUri(this, selectedMedia,
                        Images.Media.DATA);

                // setting image path
                setSplashPath(sourceMediaPath);
                break;
        }
    }

    private void setDefaultAggregatePaths() {
        SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(this);
        Editor editor = sp.edit();
        editor.putString(KEY_FORMLIST_URL, getString(R.string.default_odk_formlist));
        editor.putString(KEY_SUBMISSION_URL, getString(R.string.default_odk_submission));
        editor.commit();
    }

    /**
     * Disallows carriage returns from user entry
     */
    protected InputFilter getReturnFilter() {
        InputFilter returnFilter = new InputFilter() {
            public CharSequence filter(CharSequence source, int start, int end, Spanned dest,
                    int dstart,
                    int dend) {
                for (int i = start; i < end; i++) {
                    if (Character.getType((source.charAt(i))) == Character.CONTROL) {
                        return "";
                    }
                }
                return null;
            }
        };
        return returnFilter;
    }

    /**
     * Generic listener that sets the summary to the newly selected/entered value
     */
    @Override
    public boolean onPreferenceChange(Preference preference, Object newValue) {
        preference.setSummary((CharSequence) newValue);
        return true;
    }

}
