package org.wordpress.android.ui.prefs;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import android.app.AlertDialog;
import android.app.Dialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.AsyncTask;
import android.os.Bundle;
import android.preference.CheckBoxPreference;
import android.preference.EditTextPreference;
import android.preference.Preference;
import android.preference.Preference.OnPreferenceChangeListener;
import android.preference.Preference.OnPreferenceClickListener;
import android.preference.PreferenceCategory;
import android.preference.PreferenceGroup;
import android.preference.PreferenceManager;
import android.preference.PreferenceScreen;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.Toast;
import com.actionbarsherlock.app.ActionBar;
import com.actionbarsherlock.app.SherlockPreferenceActivity;
import com.actionbarsherlock.view.MenuItem;
import com.google.gson.Gson;
import com.google.gson.JsonSyntaxException;
import com.google.gson.internal.StringMap;
import com.justsystems.hpb.pad.R;
import org.xmlrpc.android.WPComXMLRPCApi;
import org.xmlrpc.android.XMLRPCCallback;
import org.xmlrpc.android.XMLRPCException;
import org.wordpress.android.WordPress;
import org.wordpress.android.lockmanager.AppLockManager;
import org.wordpress.android.models.Blog;
import org.wordpress.android.ui.accounts.AccountSetupActivity;
import org.wordpress.android.ui.accounts.NewAccountActivity;
import org.wordpress.android.util.DeviceUtils;
import org.wordpress.android.util.StringUtils;
@SuppressWarnings("deprecation")
public class PreferencesActivity extends SherlockPreferenceActivity {
EditTextPreference taglineTextPreference;
OnPreferenceChangeListener preferenceChangeListener;
private Object[] mTypeList;
private ArrayList<StringMap<Double>> mMutedBlogsList;
private Map<String, Object> mNotificationSettings;
private SharedPreferences mSettings;
private PreferenceGroup mNotificationsGroup;
@Override
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
overridePendingTransition(R.anim.slide_up, R.anim.do_nothing);
setTitle(getResources().getText(R.string.settings));
ActionBar ab = getSupportActionBar();
ab.setDisplayHomeAsUpEnabled(true);
if (WordPress.currentBlog == null) {
try {
WordPress.currentBlog = new Blog(WordPress.wpDB.getLastBlogId());
} catch (Exception e) {
Toast.makeText(this,
getResources().getText(R.string.blog_not_found),
Toast.LENGTH_SHORT).show();
finish();
}
}
addPreferencesFromResource(R.xml.preferences);
mNotificationsGroup = (PreferenceGroup) findPreference("wp_pref_notifications_category");
preferenceChangeListener = new OnPreferenceChangeListener() {
@Override
public boolean onPreferenceChange(Preference preference,
Object newValue) {
// Set summary to changed value
preference.setSummary(newValue.toString());
return true;
}
};
taglineTextPreference = (EditTextPreference) findPreference("wp_pref_post_signature");
taglineTextPreference
.setOnPreferenceChangeListener(preferenceChangeListener);
Preference signOutPreference = (Preference) findPreference("wp_pref_sign_out");
signOutPreference
.setOnPreferenceClickListener(signOutPreferenceClickListener);
mSettings = PreferenceManager.getDefaultSharedPreferences(this);
// Request notification settings if needed
if (WordPress.hasValidWPComCredentials(PreferencesActivity.this)) {
String settingsJson = mSettings.getString(
"wp_pref_notification_settings", null);
if (settingsJson == null) {
new WPComXMLRPCApi().getNotificationSettings(
new XMLRPCCallback() {
public void onSuccess(long id, Object result) {
refreshWPComAuthCategory();
}
public void onFailure(long id, XMLRPCException error) {
// prompt?
}
}, this);
}
}
//Passcode Lock not supported
if (AppLockManager.getInstance().isAppLockFeatureEnabled() == false) {
PreferenceScreen rootScreen = (PreferenceScreen) findPreference("wp_pref_root");
PreferenceGroup passcodeGroup = (PreferenceGroup) findPreference("wp_passcode_lock_category");
rootScreen.removePreference(passcodeGroup);
}
displayPreferences();
}
@Override
public void onResume() {
super.onResume();
// the set of blogs may have changed while we were away
updateBlogsPreferenceCategory();
updateAppLockPreferenceCategory();
}
@Override
protected void onPause() {
overridePendingTransition(R.anim.do_nothing, R.anim.slide_down);
setResult(RESULT_OK);
super.onPause();
}
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
finish();
}
return super.onOptionsItemSelected(item);
}
protected void updateAppLockPreferenceCategory() {
AppLockManager appLockManager = AppLockManager.getInstance();
if (appLockManager.isAppLockFeatureEnabled() == false)
return;
Preference passcodeLockPreference = (Preference) findPreference("wp_pref_passlock_enabled");
if (passcodeLockPreference == null)
return;
if (appLockManager.getCurrentAppLock().isPasswordLocked())
passcodeLockPreference.setTitle("Turn passcode off");
else
passcodeLockPreference.setTitle("Turn passcode on");
}
/**
* Update the "blogs" preference category to contain a preference for each
* blog to configure blog-specific settings. This also adds an "add blog"
* preference for setting up new blogs.
*/
protected void updateBlogsPreferenceCategory() {
PreferenceCategory blogsCategory = (PreferenceCategory) findPreference("wp_pref_category_blogs");
blogsCategory.removeAll();
List<Map<String, Object>> accounts = WordPress.wpDB.getAccounts();
int order = 0;
for (Map<String, Object> account : accounts) {
String blogName = StringUtils.unescapeHTML(account.get("blogName")
.toString());
int accountId = (Integer) account.get("id");
Preference blogSettingsPreference = new Preference(this);
blogSettingsPreference.setTitle(blogName);
try {
// set blog hostname as preference summary if it differs from the blog name
URL blogUrl = new URL(account.get("url").toString());
if (!blogName.equals(blogUrl.getHost())) {
blogSettingsPreference.setSummary(blogUrl.getHost());
}
} catch (MalformedURLException e) {
// do nothing
}
Intent intent = new Intent(this, BlogPreferencesActivity.class);
intent.putExtra("id", accountId);
blogSettingsPreference.setIntent(intent);
blogSettingsPreference.setOrder(order++);
blogsCategory.addPreference(blogSettingsPreference);
}
Preference addBlogPreference = new Preference(this);
addBlogPreference.setTitle(R.string.add_account);
Intent intent = new Intent(this, NewAccountActivity.class);
addBlogPreference.setIntent(intent);
addBlogPreference.setOrder(order++);
blogsCategory.addPreference(addBlogPreference);
}
protected int getEnabledBlogsCount() {
PreferenceScreen selectBlogsCategory = (PreferenceScreen) findPreference("wp_pref_notification_blogs");
int enabledBlogCtr = 0;
for (int i = 0; i < selectBlogsCategory.getPreferenceCount(); i++) {
CheckBoxPreference blogPreference = (CheckBoxPreference) selectBlogsCategory
.getPreference(i);
if (blogPreference.isChecked())
enabledBlogCtr++;
}
return enabledBlogCtr;
}
public void displayPreferences() {
// WordPress.com auth area and notifications
refreshWPComAuthCategory();
// Post signature
if (taglineTextPreference.getText() == null
|| taglineTextPreference.getText().equals("")) {
if (DeviceUtils.isBlackBerry()) {
taglineTextPreference
.setSummary(R.string.posted_from_blackberry);
taglineTextPreference
.setText(getString(R.string.posted_from_blackberry));
} else {
taglineTextPreference.setSummary(R.string.posted_from);
taglineTextPreference.setText(getString(R.string.posted_from));
}
} else {
taglineTextPreference.setSummary(taglineTextPreference.getText());
}
if (DeviceUtils.isBlackBerry()) {
PreferenceCategory appAboutSectionName = (PreferenceCategory) findPreference("wp_pref_app_about_section");
appAboutSectionName
.setTitle(getString(R.string.app_title_blackberry));
Preference appName = (Preference) findPreference("wp_pref_app_title");
appName.setTitle(getString(R.string.app_title_blackberry));
}
}
/**
* Listens for changes to notification type settings
*/
private OnPreferenceChangeListener mTypeChangeListener = new OnPreferenceChangeListener() {
@Override
public boolean onPreferenceChange(Preference preference, Object newValue) {
// Update the mNoteSettings map with the new value
if (preference instanceof CheckBoxPreference) {
CheckBoxPreference checkBoxPreference = (CheckBoxPreference) preference;
boolean isChecked = (Boolean) newValue;
String key = preference.getKey();
StringMap<Integer> typeMap = (StringMap<Integer>) mNotificationSettings
.get(key);
typeMap.put("value", (isChecked) ? 1 : 0);
mNotificationSettings.put(key, typeMap);
checkBoxPreference.setChecked(isChecked);
new sendNotificationSettingsTask().execute();
}
return false;
}
};
/**
* Listens for changes to notification blogs settings
*/
private OnPreferenceChangeListener mMuteBlogChangeListener = new OnPreferenceChangeListener() {
@Override
public boolean onPreferenceChange(Preference preference, Object newValue) {
if (preference instanceof CheckBoxPreference) {
CheckBoxPreference checkBoxPreference = (CheckBoxPreference) preference;
boolean isChecked = (Boolean) newValue;
int id = checkBoxPreference.getOrder();
StringMap<Double> blogMap = (StringMap<Double>) mMutedBlogsList
.get(id);
blogMap.put("value", (!isChecked) ? 1.0 : 0.0);
mMutedBlogsList.set(id, blogMap);
StringMap<ArrayList> mutedBlogsMap = (StringMap<ArrayList>) mNotificationSettings
.get("muted_blogs");
mutedBlogsMap.put("value", mMutedBlogsList);
mNotificationSettings.put("muted_blogs", mutedBlogsMap);
checkBoxPreference.setChecked(isChecked);
new sendNotificationSettingsTask().execute();
}
return false;
}
};
/**
* Listens for changes to notification enabled toggle
*/
private OnPreferenceChangeListener mNotificationsEnabledChangeListener = new OnPreferenceChangeListener() {
@Override
public boolean onPreferenceChange(Preference preference, Object newValue) {
if (preference instanceof CheckBoxPreference) {
final boolean isChecked = (Boolean) newValue;
if (isChecked) {
StringMap<String> muteUntilMap = (StringMap<String>) mNotificationSettings
.get("mute_until");
muteUntilMap.put("value", "0");
mNotificationSettings.put("mute_until", muteUntilMap);
new sendNotificationSettingsTask().execute();
return true;
} else {
final Dialog dialog = new Dialog(PreferencesActivity.this);
dialog.setContentView(R.layout.notifications_enabled_dialog);
dialog.setTitle(R.string.notifications);
dialog.setCancelable(true);
Button offButton = (Button) dialog
.findViewById(R.id.notificationsOff);
offButton.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
enabledButtonClick(v);
dialog.dismiss();
}
});
Button oneHourButton = (Button) dialog
.findViewById(R.id.notifications1Hour);
oneHourButton.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
enabledButtonClick(v);
dialog.dismiss();
}
});
Button eightHoursButton = (Button) dialog
.findViewById(R.id.notifications8Hours);
eightHoursButton.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
enabledButtonClick(v);
dialog.dismiss();
}
});
dialog.show();
}
}
return false;
}
};
private void enabledButtonClick(View v) {
StringMap<String> muteUntilMap = (StringMap<String>) mNotificationSettings
.get("mute_until");
if (muteUntilMap != null) {
if (v.getId() == R.id.notificationsOff) {
muteUntilMap.put("value", "forever");
} else if (v.getId() == R.id.notifications1Hour) {
muteUntilMap.put("value", String.valueOf((System
.currentTimeMillis() / 1000) + 3600));
} else if (v.getId() == R.id.notifications8Hours) {
muteUntilMap.put(
"value",
String.valueOf((System.currentTimeMillis() / 1000)
+ (3600 * 8)));
}
CheckBoxPreference enabledCheckBoxPreference = (CheckBoxPreference) findPreference("wp_pref_notifications_enabled");
enabledCheckBoxPreference.setChecked(false);
mNotificationSettings.put("mute_until", muteUntilMap);
new sendNotificationSettingsTask().execute();
}
}
/**
* Performs the notification settings save in the background
*/
private class sendNotificationSettingsTask extends
AsyncTask<Object, Object, Object> {
// Sends updated notification settings to WP.com
@Override
protected Object doInBackground(Object... params) {
if (mNotificationSettings != null) {
SharedPreferences settings = PreferenceManager
.getDefaultSharedPreferences(PreferencesActivity.this);
SharedPreferences.Editor editor = settings.edit();
Gson gson = new Gson();
String settingsJson = gson.toJson(mNotificationSettings);
editor.putString("wp_pref_notification_settings", settingsJson);
editor.commit();
new WPComXMLRPCApi()
.setNotificationSettings(PreferencesActivity.this);
}
return null;
}
}
private void refreshWPComAuthCategory() {
PreferenceCategory wpcomCategory = (PreferenceCategory) findPreference("wp_pref_wpcom_auth");
wpcomCategory.removeAll();
if (WordPress.hasValidWPComCredentials(PreferencesActivity.this)) {
String username = mSettings.getString(
WordPress.WPCOM_USERNAME_PREFERENCE, null);
Preference usernamePref = new Preference(this);
usernamePref.setTitle(getString(R.string.username));
usernamePref.setSummary(username);
usernamePref.setSelectable(false);
wpcomCategory.addPreference(usernamePref);
loadNotifications();
} else {
Preference signInPref = new Preference(this);
signInPref.setTitle(getString(R.string.sign_in));
signInPref
.setOnPreferenceClickListener(signInPreferenceClickListener);
wpcomCategory.addPreference(signInPref);
PreferenceScreen rootScreen = (PreferenceScreen) findPreference("wp_pref_root");
rootScreen.removePreference(mNotificationsGroup);
}
}
private static Comparator<StringMap<?>> BlogNameComparatorForMutedBlogsList = new Comparator<StringMap<?>>() {
public int compare(StringMap<?> blog1, StringMap<?> blog2) {
StringMap<?> blogMap1 = (StringMap<?>) blog1;
StringMap<?> blogMap2 = (StringMap<?>) blog2;
String blogName1 = blogMap1.get("blog_name").toString();
if (blogName1.length() == 0) {
blogName1 = blogMap1.get("url").toString();
}
String blogName2 = blogMap2.get("blog_name").toString();
if (blogName2.length() == 0) {
blogName2 = blogMap2.get("url").toString();
}
return blogName1.compareToIgnoreCase(blogName2);
}
};
private void loadNotifications() {
// Add notifications group back in case it was previously removed from being logged out
PreferenceScreen rootScreen = (PreferenceScreen) findPreference("wp_pref_root");
rootScreen.addPreference(mNotificationsGroup);
PreferenceCategory notificationTypesCategory = (PreferenceCategory) findPreference("wp_pref_notification_types");
SharedPreferences settings = PreferenceManager
.getDefaultSharedPreferences(this);
String settingsJson = settings.getString(
"wp_pref_notification_settings", null);
if (settingsJson == null) {
rootScreen.removePreference(mNotificationsGroup);
return;
} else {
try {
Gson gson = new Gson();
mNotificationSettings = gson.fromJson(settingsJson,
HashMap.class);
StringMap<?> mutedBlogsMap = (StringMap<?>) mNotificationSettings
.get("muted_blogs");
mMutedBlogsList = (ArrayList<StringMap<Double>>) mutedBlogsMap
.get("value");
Collections.sort(mMutedBlogsList,
this.BlogNameComparatorForMutedBlogsList);
mTypeList = mNotificationSettings.keySet().toArray();
for (int i = 0; i < mTypeList.length; i++) {
if (!mTypeList[i].equals("muted_blogs")
&& !mTypeList[i].equals("mute_until")) {
StringMap<?> typeMap = (StringMap<?>) mNotificationSettings
.get(mTypeList[i].toString());
CheckBoxPreference typePreference = new CheckBoxPreference(
this);
typePreference.setKey(mTypeList[i].toString());
typePreference.setChecked(typeMap.get("value")
.toString().equals("1"));
typePreference.setTitle(typeMap.get("desc").toString());
typePreference
.setOnPreferenceChangeListener(mTypeChangeListener);
notificationTypesCategory.addPreference(typePreference);
}
}
PreferenceCategory selectBlogsCategory = (PreferenceCategory) findPreference("wp_pref_notification_blogs");
for (int i = 0; i < mMutedBlogsList.size(); i++) {
StringMap<?> blogMap = (StringMap<?>) mMutedBlogsList
.get(i);
String blogName = (String) blogMap.get("blog_name");
if (blogName == null || blogName.trim().equals(""))
blogName = (String) blogMap.get("url");
CheckBoxPreference blogPreference = new CheckBoxPreference(
this);
blogPreference.setChecked(!blogMap.get("value").toString()
.equals("1"));
blogPreference.setTitle(StringUtils.unescapeHTML(blogName));
blogPreference
.setOnPreferenceChangeListener(mMuteBlogChangeListener);
selectBlogsCategory.addPreference(blogPreference);
}
} catch (JsonSyntaxException e) {
Log.v("WORDPRESS",
"Notification Settings Json could not be parsed.");
return;
} catch (Exception e) {
Log.v("WORDPRESS", "Failed to load notification settings.");
return;
}
CheckBoxPreference notificationsEnabledCheckBox = (CheckBoxPreference) findPreference("wp_pref_notifications_enabled");
notificationsEnabledCheckBox
.setOnPreferenceChangeListener(mNotificationsEnabledChangeListener);
}
}
private OnPreferenceClickListener signInPreferenceClickListener = new OnPreferenceClickListener() {
@Override
public boolean onPreferenceClick(Preference preference) {
Intent i = new Intent(PreferencesActivity.this,
AccountSetupActivity.class);
i.putExtra("wpcom", true);
i.putExtra("auth-only", true);
startActivityForResult(i, 0);
return true;
}
};
private OnPreferenceClickListener signOutPreferenceClickListener = new OnPreferenceClickListener() {
@Override
public boolean onPreferenceClick(Preference preference) {
AlertDialog.Builder dialogBuilder = new AlertDialog.Builder(
PreferencesActivity.this);
dialogBuilder.setTitle(getResources().getText(R.string.sign_out));
dialogBuilder.setMessage(getString(R.string.sign_out_confirm));
dialogBuilder.setPositiveButton(R.string.sign_out,
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog,
int whichButton) {
WordPress.signOut(PreferencesActivity.this);
finish();
}
});
dialogBuilder.setNegativeButton(R.string.cancel,
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog,
int whichButton) {
// Just close the window.
}
});
dialogBuilder.setCancelable(true);
if (!isFinishing())
dialogBuilder.create().show();
return true;
}
};
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
refreshWPComAuthCategory();
super.onActivityResult(requestCode, resultCode, data);
}
}