package net.pokeranalytics.android.util import android.content.Context import android.os.Build import android.preference.PreferenceManager import android.view.View import io.realm.Realm import net.pokeranalytics.android.PokerAnalyticsApplication import net.pokeranalytics.android.R import net.pokeranalytics.android.model.realm.Bankroll import net.pokeranalytics.android.model.realm.ResultCaptureType import net.pokeranalytics.android.model.realm.Session import net.pokeranalytics.android.ui.extensions.openUrl import net.pokeranalytics.android.util.extensions.count import java.util.* class Preferences { interface PreferenceKey { val identifier: String } enum class Keys(override var identifier: String) : PreferenceKey { CURRENCY_CODE("CurrencyCode"), LOCALE_CODE("LocaleCode"), FIRST_LAUNCH("firstLaunch"), STOP_SHOWING_DISCLAIMER("stopShowingDisclaimer"), STOP_SHOWING_DUPLICATE("stopShowingDuplicate"), STOP_SHOWING_DISCORD("stopShowingDiscord"), ACTIVE_FILTER_ID("ActiveFilterId"), LATEST_PURCHASE("latestPurchase"), PATCH_BREAK("patchBreaks"), PATCH_SESSION_SETS("patchSessionSet"), PATCH_TRANSACTION_TYPES_NAMES("patchTransactionTypesNames"), // PATCH_BLINDS_FORMAT("patchBlindFormat"), PATCH_COMPUTABLE_RESULTS("patchPositiveSessions"), PATCH_ZERO_TABLE("patchZeroTable"), SHOW_STOP_NOTIFICATIONS("showStopNotifications"), ADD_NEW_TRANSACTION_TYPES("addNewTransactionTypes_transfer"), SHOW_VILLAIN_CARDS("showVillainCards"), BANKROLL_RESULT_CAPTURE_TYPE("bankrollResultCaptureType_"), LATEST_BLOG_POST_ID_RETRIEVED("latestBlogPostIdRetrieved"), LATEST_BLOG_POST_ID_DISPLAYED("latestBlogPostIdDisplayed"), LAST_BLOG_TIPS_RETRIEVAL("lastBlogTipsRetrieval"), SHOW_BLOG_TIPS("showBlogTips"), LAST_REVIEW_REQUEST_DATE("lastReviewRequestDate"), PATCH_NEGATIVE_LIMITS("negativeLimits"), PATCH_STAKES("patchStakes"), CLEAN_BLINDS_FILTERS("deleteBlindsFilters"), SHOW_IN_APP_BADGES("showInAppBadges"), LAST_CALENDAR_BADGE_DATE("lastCalendarBadgeDate") } enum class FeedMessage { DISCLAIMER, DISCORD, DUPLICATE; val resId: Int get() { return when (this) { DISCLAIMER -> R.string.disclaimer DUPLICATE -> R.string.longtap_to_duplicate DISCORD -> R.string.discord_feed_message } } val key: Keys get() { return when (this) { DISCLAIMER -> Keys.STOP_SHOWING_DISCLAIMER DUPLICATE -> Keys.STOP_SHOWING_DUPLICATE DISCORD -> Keys.STOP_SHOWING_DISCORD } } val actionResId: Int? get() { return when (this) { DISCORD -> R.string.join_discord else -> null } } fun action(context: Context): ((View) -> (Unit))? { return when (this) { DISCORD -> { { context.openUrl(URL.DISCORD.value) } } else -> null } } val dismissResId: Int get() { return when (this) { DISCORD -> R.string.good_for_you else -> R.string.iunderstand } } } companion object { fun setStringSet(key: PreferenceKey, value: MutableSet, context: Context) { val preferences = PreferenceManager.getDefaultSharedPreferences(context) val editor = preferences.edit() editor.putStringSet(key.identifier, value) editor.apply() } fun getStringSet(key: Keys, context: Context): MutableSet? { val preferences = PreferenceManager.getDefaultSharedPreferences(context) return preferences.getStringSet(key.identifier, null) } fun setString(key: PreferenceKey, value: String, context: Context) { val preferences = PreferenceManager.getDefaultSharedPreferences(context) val editor = preferences.edit() editor.putString(key.identifier, value) editor.apply() } fun getString(key: Keys, context: Context): String? { val preferences = PreferenceManager.getDefaultSharedPreferences(context) return preferences.getString(key.identifier, null) } private fun setBoolean(key: PreferenceKey, value: Boolean, context: Context) { val preferences = PreferenceManager.getDefaultSharedPreferences(context) val editor = preferences.edit() editor.putBoolean(key.identifier, value) editor.apply() } private fun getBoolean(key: PreferenceKey, context: Context, defaultValue: Boolean? = false): Boolean { val preferences = PreferenceManager.getDefaultSharedPreferences(context) return preferences.getBoolean(key.identifier, defaultValue ?: false) } private fun setInt(key: PreferenceKey, value: Int, context: Context) { val preferences = PreferenceManager.getDefaultSharedPreferences(context) val editor = preferences.edit() editor.putInt(key.identifier, value) editor.apply() } private fun getInt(key: PreferenceKey, context: Context): Int { val preferences = PreferenceManager.getDefaultSharedPreferences(context) return preferences.getInt(key.identifier, -1) } private fun setLong(key: PreferenceKey, value: Long, context: Context) { val preferences = PreferenceManager.getDefaultSharedPreferences(context) val editor = preferences.edit() editor.putLong(key.identifier, value) editor.apply() } private fun getLong(key: PreferenceKey, context: Context): Long { val preferences = PreferenceManager.getDefaultSharedPreferences(context) return preferences.getLong(key.identifier, 0L) } fun setShowVillainCards(show: Boolean, context: Context) { setBoolean(Keys.SHOW_VILLAIN_CARDS, show, context) } fun getShowVillainCards(context: Context): Boolean { return getBoolean(Keys.SHOW_VILLAIN_CARDS, context, true) } fun setCurrencyCode(currencyCode: String, context: Context) { setString(Keys.CURRENCY_CODE, currencyCode, context) UserDefaults.setCurrencyValues(context) } fun setActiveFilterId(filterId: String, context: Context) { setString(Keys.ACTIVE_FILTER_ID, filterId, context) } fun getActiveFilterId(context: Context): String? { return getString(Keys.ACTIVE_FILTER_ID, context) } private fun getCurrencyCode(context: Context): String? { return getString(Keys.CURRENCY_CODE, context) } private fun getCurrencyLocale(context: Context): Locale? { getCurrencyCode(context)?.let { currencyCode -> UserDefaults.availableCurrencyLocales.firstOrNull { Currency.getInstance(it).currencyCode == currencyCode }?.let { return it } } return null } fun getDefaultCurrency(context: Context): Currency? { getCurrencyLocale(context)?.let { return Currency.getInstance(it) } return null } fun setShowStopNotifications(show: Boolean, context: Context) { setBoolean(Keys.SHOW_STOP_NOTIFICATIONS, show, context) } fun showStopNotifications(context: Context): Boolean { val defaultValue = (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) return getBoolean(Keys.SHOW_STOP_NOTIFICATIONS, context, defaultValue) } fun setStopShowingMessage(message: FeedMessage, context: Context) { setBoolean(message.key, true, context) } fun feedMessageToShow(context: Context): FeedMessage? { if (!getBoolean(Keys.STOP_SHOWING_DISCLAIMER, context)) { return FeedMessage.DISCLAIMER } val realm = Realm.getDefaultInstance() val sessionCount = realm.count(Session::class.java) realm.close() if (sessionCount > 1 && !getBoolean(Keys.STOP_SHOWING_DUPLICATE, context)) { return FeedMessage.DUPLICATE } if (!getBoolean(Keys.STOP_SHOWING_DISCORD, context) && PokerAnalyticsApplication.timeSinceInstall(context) > 1000 * 3600 * 24 * 30L) { return FeedMessage.DISCORD } return null } fun executeOnce(key: Keys, context: Context, executable: () -> Unit) { if (!getBoolean(key, context)) { executable.invoke() setBoolean(key, true, context) } } fun setResultCaptureType(bankroll: Bankroll, type: ResultCaptureType, context: Context) { val key = "${Keys.BANKROLL_RESULT_CAPTURE_TYPE}${bankroll.id}" val preferences = PreferenceManager.getDefaultSharedPreferences(context) val editor = preferences.edit() editor.putInt(key, type.ordinal) editor.apply() } fun getResultCaptureType(bankroll: Bankroll, context: Context): ResultCaptureType? { val key = "${Keys.BANKROLL_RESULT_CAPTURE_TYPE}${bankroll.id}" val preferences = PreferenceManager.getDefaultSharedPreferences(context) return when (val ordinal = preferences.getInt(key, -1)) { -1 -> null else -> ResultCaptureType.values()[ordinal] } } fun setLatestRetrievedBlogPostId(id: Int, context: Context) { setInt(Keys.LATEST_BLOG_POST_ID_RETRIEVED, id, context) } private fun getLatestRetrievedBlogPostId(context: Context): Int { return getInt(Keys.LATEST_BLOG_POST_ID_RETRIEVED, context) } fun setBlogTipsTapped(context: Context) { setInt(Keys.LATEST_BLOG_POST_ID_DISPLAYED, getLatestRetrievedBlogPostId(context), context) } fun getLatestDisplayedBlogPostId(context: Context): Int { return getInt(Keys.LATEST_BLOG_POST_ID_DISPLAYED, context) } fun showBlogTips(show: Boolean, context: Context) { setLastBlogTipsRetrievalDate(0L, context) setBoolean(Keys.SHOW_BLOG_TIPS, show, context) } fun shouldShowBlogTips(context: Context): Boolean { return getBoolean(Keys.SHOW_BLOG_TIPS, context, true) } fun setLastBlogTipsRetrievalDate(date: Long, context: Context) { setLong(Keys.LAST_BLOG_TIPS_RETRIEVAL, date, context) } fun getLastBlogTipsRetrievalDate(context: Context): Long { return getLong(Keys.LAST_BLOG_TIPS_RETRIEVAL, context) } fun setLastReviewRequestDate(date: Long, context: Context) { setLong(Keys.LAST_REVIEW_REQUEST_DATE, date, context) } fun getLastReviewRequestDate(context: Context): Long { return getLong(Keys.LAST_REVIEW_REQUEST_DATE, context) } fun setFirstLaunchDate(date: Long, context: Context) { setLong(Keys.FIRST_LAUNCH, date, context) } fun getFirstLaunchDate(context: Context): Long { return getLong(Keys.FIRST_LAUNCH, context) } fun showInAppBadges(context: Context): Boolean { return getBoolean(Keys.SHOW_IN_APP_BADGES, context, true) } fun setShowInAppBadges(context: Context, show: Boolean) { setBoolean(Keys.SHOW_IN_APP_BADGES, show, context) } fun lastCalendarBadgeDate(context: Context): Long { return getLong(Keys.LAST_CALENDAR_BADGE_DATE, context) } fun setLastCalendarBadgeDate(context: Context, date: Long) { setLong(Keys.LAST_CALENDAR_BADGE_DATE, date, context) } } } class UserDefaults private constructor(context: Context) { init { setCurrencyValues(context) } companion object : SingletonHolder(::UserDefaults) { lateinit var currency: Currency fun setCurrencyValues(context: Context) { currency = Preferences.getDefaultCurrency(context) ?: getLocaleCurrency() } val availableCurrencyLocales = Locale.getAvailableLocales().mapNotNull { try { Currency.getInstance(it) it } catch (e: Exception) { null } } /** * Return the locale currency, or en_US if there */ fun getLocaleCurrency(): Currency { return try { Currency.getInstance(Locale.getDefault()) } catch (ex: Exception) { when (Locale.getDefault().language) { "en" -> Currency.getInstance(Locale("en", "US")) "fr" -> Currency.getInstance(Locale("fr", "FR")) "es" -> Currency.getInstance(Locale("es", "ES")) "de" -> Currency.getInstance(Locale("de", "DE")) "ja" -> Currency.getInstance(Locale("ja", "JP")) "zh" -> Currency.getInstance(Locale("zh", "CN")) else -> Currency.getInstance(Locale("en", "US")) } } } } }