package uz.startandroid.kidcontrol.util import android.content.SharedPreferences import com.google.gson.Gson import io.reactivex.Completable import io.reactivex.Single import kotlin.reflect.KClass import kotlin.reflect.KProperty fun SharedPreferences.boolean(key: String, defValue: Boolean = false) = BoolItem(this, key, defValue) fun SharedPreferences.int(key: String) = IntItem(this, key) fun SharedPreferences.long(key: String) = LongItem(this, key) fun SharedPreferences.string(key: String) = StringItem(this, key) fun SharedPreferences.stringNullable(key: String) = StringItemNullable(this, key) fun SharedPreferences.json(key: String, clazz: KClass) = JsonItem(this, key, clazz) fun SharedPreferences.rxJson(key: String, clazz: KClass) = RxJsonPreference(this, key, clazz) class BoolItem( private val preferences: SharedPreferences, private val key: String, private val defValue: Boolean ) { operator fun getValue(thisRef: Any?, property: KProperty<*>): Boolean { return preferences.getBoolean(key, defValue) } operator fun setValue(thisRef: Any?, property: KProperty<*>, value: Boolean) { preferences.edit().putBoolean(key, value).apply() } } class IntItem(private val preferences: SharedPreferences, private val key: String) { operator fun getValue(thisRef: Any?, property: KProperty<*>): Int { return preferences.getInt(key, 0) } operator fun setValue(thisRef: Any?, property: KProperty<*>, value: Int) { preferences.edit().putInt(key, value).apply() } } class LongItem(private val preferences: SharedPreferences, private val key: String) { operator fun getValue(thisRef: Any?, property: KProperty<*>): Long { return preferences.getLong(key, 0) } operator fun setValue(thisRef: Any?, property: KProperty<*>, value: Long) { preferences.edit().putLong(key, value).apply() } } class StringItem(private val preferences: SharedPreferences, private val key: String) { operator fun getValue(thisRef: Any?, property: KProperty<*>): String { return preferences.getString(key, "").orEmpty() } operator fun setValue(thisRef: Any?, property: KProperty<*>, value: String) { preferences.edit().putString(key, value).apply() } } class StringItemNullable(private val preferences: SharedPreferences, private val key: String) { operator fun getValue(thisRef: Any?, property: KProperty<*>): String? { return preferences.getString(key, null) } operator fun setValue(thisRef: Any?, property: KProperty<*>, value: String?) { preferences.edit().putString(key, value).apply() } } class JsonItem( private val preferences: SharedPreferences, private val key: String, private val clazz: KClass ) { operator fun getValue(thisRef: Any?, property: KProperty<*>): T? { val jsonValue = preferences.getString(key, null) return try { Gson().fromJson(jsonValue, clazz.java) } catch (e: Exception) { null } } operator fun setValue(thisRef: Any?, property: KProperty<*>, value: T?) { val jsonValue = Gson().toJson(value) preferences.edit().putString(key, jsonValue).apply() } } class RxJsonPreference( preferences: SharedPreferences, key: String, clazz: KClass ) { private var jsonItem by JsonItem(preferences, key, clazz) fun get(): Single { return Single.create { emitter -> jsonItem?.let { emitter.onSuccess(it) } ?: emitter.onError(NoSuchElementException()) } } fun save(value: T): Completable { return Completable.create { emitter -> try { jsonItem = value emitter.onComplete() } catch (e: Exception) { emitter.onError(e) } } } }