package com.alimuzaffar.ramadanalarm.util;
import android.content.Context;
import android.content.SharedPreferences;
import android.text.format.DateFormat;
import java.lang.ref.WeakReference;
/*
* A Singleton for managing your SharedPreferences.
*
* You should make sure to change the SETTINGS_NAME to what you want
* and choose the operating made that suits your needs, the default is
* MODE_PRIVATE.
*
* IMPORTANT: The class is not thread safe. It should work fine in most
* circumstances since the write and read operations are fast. However
* if you call edit for bulk updates and do not commit your changes
* there is a possibility of data loss if a background thread has modified
* preferences at the same time.
*
* Usage:
*
* int sampleInt = AppSettings.getInstance(context).getInt(Key.SAMPLE_INT);
* AppSettings.getInstance(context).set(Key.SAMPLE_INT, sampleInt);
*
* If AppSettings.getInstance(Context) has been called once, you can
* simple use AppSettings.getInstance() to save some precious line space.
*/
public class AppSettings {
public static final PrayTime sDefaults = new PrayTime();
private static final String SETTINGS_NAME = "default_settings";
private static AppSettings sSharedPrefs;
private SharedPreferences mPref;
private SharedPreferences.Editor mEditor;
private boolean mBulkUpdate = false;
private WeakReference<Context> mContextRef;
/**
* Class for keeping all the keys used for shared preferences in one place.
*/
public static class Key {
/* Recommended naming convention:
* ints, floats, doubles, longs:
* SAMPLE_NUM or SAMPLE_COUNT or SAMPLE_INT, SAMPLE_LONG etc.
*
* boolean: IS_SAMPLE, HAS_SAMPLE, CONTAINS_SAMPLE
*
* String: SAMPLE_KEY, SAMPLE_STR or just SAMPLE
*/
//ALARM RELATED
public static final String IS_ALARM_SET = "is_alarm_set_for_%d";
public static final String IS_FAJR_ALARM_SET = "is_fajr_alarm_set_for_%d";
public static final String IS_DHUHR_ALARM_SET = "is_dhuhr_alarm_set_for_%d";
public static final String IS_ASR_ALARM_SET = "is_asr_alarm_set_for_%d";
public static final String IS_MAGHRIB_ALARM_SET = "is_maghrib_alarm_set_for_%d";
public static final String IS_ISHA_ALARM_SET = "is_isha_alarm_set_for_%d";
public static final String IS_RAMADAN = "is_ramadan";
public static final String SUHOOR_OFFSET = "suhoor_offset";
public static final String IFTAR_OFFSET = "iftar_offset";
public static final String IS_ASCENDING_ALARM = "is_ascending_alarm";
public static final String IS_RANDOM_ALARM = "is_random_alarm";
public static final String SELECTED_RINGTONE = "ringtone_selected";
public static final String SELECTED_RINGTONE_NAME = "ringtone_selected_name";
public static final String USE_ADHAN = "use_adhan";
//CONFIG RELATED
public static final String HAS_DEFAULT_SET = "has_default_set";
public static final String CALC_METHOD = "calc_method_for_%d";
public static final String ASR_METHOD = "asr_method_for_%d";
public static final String ADJUST_METHOD = "adjust_high_latitudes_method_for_%d";
public static final String TIME_FORMAT = "time_format_for_%d";
//LOCATION RELATED
public static final String LAT_FOR = "lat_for_%d";
public static final String LNG_FOR = "lng_for_%d";
public static final String SHOW_ORIENATATION_INSTRACTIONS = "showOrientationInstructions";
//APP RELATED
public static final String IS_INIT = "app_init";
public static final String APP_VERSION_CODE = "current_version_code";
public static final String IS_TNC_ACCEPTED = "is_tnc_accepted";
}
private AppSettings(Context context) {
mPref = context.getSharedPreferences(SETTINGS_NAME, Context.MODE_PRIVATE);
mContextRef = new WeakReference<Context>(context);
}
public static AppSettings getInstance(Context context) {
if (sSharedPrefs == null) {
sSharedPrefs = new AppSettings(context.getApplicationContext());
}
return sSharedPrefs;
}
public static AppSettings getInstance() {
if (sSharedPrefs != null) {
return sSharedPrefs;
}
//Option 1:
throw new IllegalArgumentException("Should use getInstance(Context) at least once before using this method.");
//Option 2:
// Alternatively, you can create a new instance here
// with something like this:
// getInstance(MyCustomApplication.getAppContext());
}
public void set(String key, String val) {
doEdit();
mEditor.putString(key, val);
doCommit();
}
public void set(String key, int val) {
doEdit();
mEditor.putInt(key, val);
doCommit();
}
public void set(String key, boolean val) {
doEdit();
mEditor.putBoolean(key, val);
doCommit();
}
public void set(String key, float val) {
doEdit();
mEditor.putFloat(key, val);
doCommit();
}
/**
* Convenience method for storing doubles.
* <p/>
* There may be instances where the accuracy of a double is desired.
* SharedPreferences does not handle doubles so they have to
* cast to and from String.
*
* @param key The name of the preference to store.
* @param val The new value for the preference.
*/
public void set(String key, double val) {
doEdit();
mEditor.putString(key, String.valueOf(val));
doCommit();
}
public void set(String key, long val) {
doEdit();
mEditor.putLong(key, val);
doCommit();
}
public String getString(String key, String defaultValue) {
return mPref.getString(key, defaultValue);
}
public String getString(String key) {
return mPref.getString(key, null);
}
public int getInt(String key) {
return mPref.getInt(key, 0);
}
public int getInt(String key, int defaultValue) {
return mPref.getInt(key, defaultValue);
}
public long getLong(String key) {
return mPref.getLong(key, 0);
}
public long getLong(String key, long defaultValue) {
return mPref.getLong(key, defaultValue);
}
public float getFloat(String key) {
return mPref.getFloat(key, 0);
}
public float getFloat(String key, float defaultValue) {
return mPref.getFloat(key, defaultValue);
}
/**
* Convenience method for retrieving doubles.
* <p/>
* There may be instances where the accuracy of a double is desired.
* SharedPreferences does not handle doubles so they have to
* cast to and from String.
*
* @param key The name of the preference to fetch.
*/
public double getDouble(String key) {
return getDouble(key, 0);
}
/**
* Convenience method for retrieving doubles.
* <p/>
* There may be instances where the accuracy of a double is desired.
* SharedPreferences does not handle doubles so they have to
* cast to and from String.
*
* @param key The name of the preference to fetch.
*/
public double getDouble(String key, double defaultValue) {
try {
return Double.valueOf(mPref.getString(key, String.valueOf(defaultValue)));
} catch (NumberFormatException nfe) {
return defaultValue;
}
}
public boolean getBoolean(String key, boolean defaultValue) {
return mPref.getBoolean(key, defaultValue);
}
public boolean getBoolean(String key) {
return mPref.getBoolean(key, false);
}
/**
* Remove keys from SharedPreferences.
*
* @param keys The name of the key(s) to be removed.
*/
public void remove(String... keys) {
doEdit();
for (String key : keys) {
mEditor.remove(key);
}
doCommit();
}
/**
* Remove all keys from SharedPreferences.
*/
public void clear() {
doEdit();
mEditor.clear();
doCommit();
}
public void edit() {
mBulkUpdate = true;
mEditor = mPref.edit();
}
public void commit() {
mBulkUpdate = false;
mEditor.commit();
mEditor = null;
}
private void doEdit() {
if (!mBulkUpdate && mEditor == null) {
mEditor = mPref.edit();
}
}
private void doCommit() {
if (!mBulkUpdate && mEditor != null) {
mEditor.commit();
mEditor = null;
}
}
public String getKeyFor(String key, int index) {
return String.format(key, index);
}
public boolean isAlarmSetFor(int index) {
return getBoolean(getKeyFor(Key.IS_ALARM_SET, index));
}
public void setAlarmFor(int index, boolean alarmOn) {
set(getKeyFor(Key.IS_ALARM_SET, index), alarmOn);
}
public int getCalcMethodSetFor(int index) {
return getInt(getKeyFor(Key.CALC_METHOD, index), PrayTime.MWL);
}
public void setCalcMethodFor(int index, int value) {
set(getKeyFor(Key.CALC_METHOD, index), value);
}
public int getAsrMethodSetFor(int index) {
return getInt(String.format(Key.ASR_METHOD, index), PrayTime.SHAFII);
}
public void setAsrMethodFor(int index, int value) {
set(getKeyFor(Key.ASR_METHOD, index), value);
}
public int getHighLatitudeAdjustmentFor(int index) {
return getInt(getKeyFor(Key.ADJUST_METHOD, index), PrayTime.ONE_SEVENTH);
}
public void setHighLatitudeAdjustmentMethodFor(int index, int value) {
set(getKeyFor(Key.ADJUST_METHOD, index), value);
}
public int getTimeFormatFor(int index) {
return getInt(getKeyFor(Key.TIME_FORMAT, index), DateFormat.is24HourFormat(mContextRef.get())? PrayTime.TIME_24 : PrayTime.TIME_12);
}
public void setTimeFormatFor(int index, int format) {
set(getKeyFor(Key.TIME_FORMAT, index), format);
}
public double getLatFor(int index) {
return getDouble(getKeyFor(Key.LAT_FOR, index));
}
public double getLngFor(int index) {
return getDouble(getKeyFor(Key.LNG_FOR, index));
}
public void setLatFor(int index, double lat) {
set(getKeyFor(Key.LAT_FOR, index), lat);
}
public void setLngFor(int index, double lng) {
set(getKeyFor(Key.LNG_FOR, index), lng);
}
public boolean isDefaultSet() {
return getBoolean(Key.HAS_DEFAULT_SET);
}
}