diff --git a/app/src/androidTest/java/net/pokeranalytics/android/unitTests/BankrollInstrumentedUnitTest.kt b/app/src/androidTest/java/net/pokeranalytics/android/unitTests/BankrollInstrumentedUnitTest.kt index 7fe1fb99..b96a63d8 100644 --- a/app/src/androidTest/java/net/pokeranalytics/android/unitTests/BankrollInstrumentedUnitTest.kt +++ b/app/src/androidTest/java/net/pokeranalytics/android/unitTests/BankrollInstrumentedUnitTest.kt @@ -28,53 +28,7 @@ class BankrollInstrumentedUnitTest : RealmInstrumentedUnitTest() { @Test fun testSessionStats() { - val realm = this.mockRealm - realm.beginTransaction() - val s1 = newSessionInstance(realm) - val s2 = newSessionInstance(realm) - - val br1 = realm.createObject(Bankroll::class.java, "1") - val br2 = realm.createObject(Bankroll::class.java, "2") - - val c1 = realm.createObject(Currency::class.java, "1") - val c2 = realm.createObject(Currency::class.java, "2") - c1.rate = 0.1 - c2.rate = 2.0 - br1.currency = c1 - br2.currency = c2 - - s1.bankroll = br1 - s2.bankroll = br2 - - s1.result?.netResult = 100.0 - s2.result?.netResult = 200.0 - - realm.commitTransaction() - - val computableResults = realm.where(ComputableResult::class.java).findAll() - val sets = realm.where(SessionSet::class.java).findAll() - val stats: List = listOf(Stat.NETRESULT, Stat.AVERAGE) - val group = ComputableGroup("test", computableResults, sets, stats) - - val options = Calculator.Options() - - val results: ComputedResults = Calculator.compute(group, options) - val delta = 0.01 - - val sum = results.computedStat(Stat.NETRESULT) - if (sum != null) { - Assert.assertEquals(410.0, sum.value, delta) - } else { - Assert.fail("No Net result stat") - } - - val average = results.computedStat(Stat.AVERAGE) - if (average != null) { - Assert.assertEquals(205.0, average.value, delta) - } else { - Assert.fail("No AVERAGE stat") - } } diff --git a/app/src/androidTest/java/net/pokeranalytics/android/unitTests/filter/BlindFilterInstrumentedTest.kt b/app/src/androidTest/java/net/pokeranalytics/android/unitTests/filter/BlindFilterInstrumentedTest.kt index d19cee4a..9ace6e81 100644 --- a/app/src/androidTest/java/net/pokeranalytics/android/unitTests/filter/BlindFilterInstrumentedTest.kt +++ b/app/src/androidTest/java/net/pokeranalytics/android/unitTests/filter/BlindFilterInstrumentedTest.kt @@ -21,7 +21,7 @@ class BlindFilterInstrumentedTest : BaseFilterInstrumentedUnitTest() { realm.beginTransaction() val currency = realm.createObject(net.pokeranalytics.android.model.realm.Currency::class.java, "1") - currency.code = "AUD" + currency.code = "USD" val b1 = realm.createObject(Bankroll::class.java, "1") val b2 = realm.createObject(Bankroll::class.java, "2") @@ -42,9 +42,9 @@ class BlindFilterInstrumentedTest : BaseFilterInstrumentedUnitTest() { realm.commitTransaction() - val filter = QueryCondition.BLINDS - val blind = FilterElementRow.Blind(0.5, 1.0, null) - blind.filterSectionRow = FilterSectionRow.BLINDS + val filter = QueryCondition.BLIND + val blind = FilterElementRow.Blind(s1.blinds!!, true) + blind.filterSectionRow = FilterSectionRow.BLIND val filterElement = FilterCondition(filterElementRows = arrayListOf(blind)) filter.updateValueMap(filterElement) @@ -86,12 +86,14 @@ class BlindFilterInstrumentedTest : BaseFilterInstrumentedUnitTest() { realm.commitTransaction() - val filter = QueryCondition.BLINDS - val blind = FilterElementRow.Blind(null, 1.0, null) - blind.filterSectionRow = FilterSectionRow.BLINDS + val filter = QueryCondition.BLIND + val blind1 = FilterElementRow.Blind(s1.blinds!!, true) + val blind2 = FilterElementRow.Blind(s2.blinds!!, true) + blind1.filterSectionRow = FilterSectionRow.BLIND + blind2.filterSectionRow = FilterSectionRow.BLIND - val filterElement = FilterCondition(filterElementRows = arrayListOf(blind)) - filter.updateValueMap(filterElement) + val filterElements = FilterCondition(filterElementRows = arrayListOf(blind1, blind2)) + filter.updateValueMap(filterElements) val sessions = Filter.queryOn(realm, arrayListOf(filter)) @@ -108,13 +110,14 @@ class BlindFilterInstrumentedTest : BaseFilterInstrumentedUnitTest() { realm.beginTransaction() val currency = realm.createObject(net.pokeranalytics.android.model.realm.Currency::class.java, "1") - currency.code = "AUD" + currency.code = "USD" val b1 = realm.createObject(Bankroll::class.java, "1") val b2 = realm.createObject(Bankroll::class.java, "2") b2.currency = currency val s1 = Session.testInstance(100.0, false, Date(), 1, b1) + s1.cgBigBlind = 1.0 s1.cgSmallBlind = 0.5 @@ -129,9 +132,9 @@ class BlindFilterInstrumentedTest : BaseFilterInstrumentedUnitTest() { realm.commitTransaction() - val filter = QueryCondition.BLINDS - val blind = FilterElementRow.Blind(1.0, 2.0, "AUD") - blind.filterSectionRow = FilterSectionRow.BLINDS + val filter = QueryCondition.BLIND + val blind = FilterElementRow.Blind(s3.blinds!!, false) + blind.filterSectionRow = FilterSectionRow.BLIND val filterElement = FilterCondition(filterElementRows = arrayListOf(blind)) filter.updateValueMap(filterElement) @@ -172,12 +175,12 @@ class BlindFilterInstrumentedTest : BaseFilterInstrumentedUnitTest() { realm.commitTransaction() - val filter = QueryCondition.BLINDS - val blind1 = FilterElementRow.Blind(1.0, 2.0, null) - blind1.filterSectionRow = FilterSectionRow.BLINDS + val filter = QueryCondition.BLIND + val blind1 = FilterElementRow.Blind(s1.blinds!!, false) + blind1.filterSectionRow = FilterSectionRow.BLIND - val blind2 = FilterElementRow.Blind(0.5, 1.0, null) - blind2.filterSectionRow = FilterSectionRow.BLINDS + val blind2 = FilterElementRow.Blind(s2.blinds!!, false) + blind2.filterSectionRow = FilterSectionRow.BLIND val filterElement = FilterCondition(filterElementRows = arrayListOf(blind1, blind2)) filter.updateValueMap(filterElement) diff --git a/app/src/androidTest/java/net/pokeranalytics/android/unitTests/filter/DateFilterInstrumentedUnitTest.kt b/app/src/androidTest/java/net/pokeranalytics/android/unitTests/filter/DateFilterInstrumentedUnitTest.kt index 2fd4b380..8ef9c845 100644 --- a/app/src/androidTest/java/net/pokeranalytics/android/unitTests/filter/DateFilterInstrumentedUnitTest.kt +++ b/app/src/androidTest/java/net/pokeranalytics/android/unitTests/filter/DateFilterInstrumentedUnitTest.kt @@ -35,14 +35,14 @@ class DateFilterInstrumentedUnitTest : BaseFilterInstrumentedUnitTest() { val filterElementRow = FilterElementRow.Day(cal.get(Calendar.DAY_OF_WEEK)) filterElementRow.filterSectionRow = FilterSectionRow.DYNAMIC_DATE - val filterElement = FilterCondition(filterElementRow) + val filterElement = FilterCondition(arrayListOf(filterElementRow)) filter.updateValueMap(filterElement) val sessions = Filter.queryOn(realm, arrayListOf(filter)) Assert.assertEquals(1, sessions.size) sessions[0]?.run { - Assert.assertEquals(s1.id, (this as Session).id) + Assert.assertEquals(s1.id, (this).id) } } @@ -64,14 +64,14 @@ class DateFilterInstrumentedUnitTest : BaseFilterInstrumentedUnitTest() { val filterElementRow = FilterElementRow.Month(cal.get(Calendar.MONTH)) filterElementRow.filterSectionRow = FilterSectionRow.DYNAMIC_DATE - val filterElement = FilterCondition(filterElementRow) + val filterElement = FilterCondition(arrayListOf(filterElementRow)) filter.updateValueMap(filterElement) val sessions = Filter.queryOn(realm, arrayListOf(filter)) Assert.assertEquals(1, sessions.size) sessions[0]?.run { - Assert.assertEquals(s1.id, (this as Session).id) + Assert.assertEquals(s1.id, (this).id) } } @@ -92,14 +92,14 @@ class DateFilterInstrumentedUnitTest : BaseFilterInstrumentedUnitTest() { cal.time = s1.startDate val filterElementRow = FilterElementRow.Year(cal.get(Calendar.YEAR)) filterElementRow.filterSectionRow = FilterSectionRow.DYNAMIC_DATE - val filterElement = FilterCondition(filterElementRow) + val filterElement = FilterCondition(arrayListOf(filterElementRow)) filter.updateValueMap(filterElement) val sessions = Filter.queryOn(realm, arrayListOf(filter)) Assert.assertEquals(1, sessions.size) sessions[0]?.run { - Assert.assertEquals(s1.id, (this as Session).id) + Assert.assertEquals(s1.id, (this).id) } } @@ -122,7 +122,7 @@ class DateFilterInstrumentedUnitTest : BaseFilterInstrumentedUnitTest() { Assert.assertEquals(1, sessions.size) sessions[0]?.run { - Assert.assertEquals(s1.id, (this as Session).id) + Assert.assertEquals(s1.id, (this).id) } } @@ -147,7 +147,7 @@ class DateFilterInstrumentedUnitTest : BaseFilterInstrumentedUnitTest() { Assert.assertEquals(1, sessions.size) sessions[0]?.run { - Assert.assertEquals(s1.id, (this as Session).id) + Assert.assertEquals(s1.id, (this).id) } } @@ -384,15 +384,15 @@ class DateFilterInstrumentedUnitTest : BaseFilterInstrumentedUnitTest() { realm.commitTransaction() val filter = QueryCondition.STARTED_FROM_DATE - val filterElementRow = FilterElementRow.From(s2.startDate!!) + val filterElementRow = FilterElementRow.From.apply { dateValue = s2.startDate!!} filterElementRow.filterSectionRow = FilterSectionRow.FIXED_DATE - filter.updateValueMap(FilterCondition(filterElementRow)) + filter.updateValueMap(FilterCondition(arrayListOf(filterElementRow))) val sessions = Filter.queryOn(realm, arrayListOf(filter)) Assert.assertEquals(1, sessions.size) sessions[0]?.run { - Assert.assertEquals(s2.id, (this as Session).id) + Assert.assertEquals(s2.id, (this).id) } } @@ -412,15 +412,15 @@ class DateFilterInstrumentedUnitTest : BaseFilterInstrumentedUnitTest() { realm.commitTransaction() val filter = QueryCondition.STARTED_TO_DATE - val filterElementRow = FilterElementRow.From(s1.startDate!!) + val filterElementRow = FilterElementRow.From.apply { dateValue = s1.startDate!! } filterElementRow.filterSectionRow = FilterSectionRow.FIXED_DATE - filter.updateValueMap(FilterCondition(filterElementRow)) + filter.updateValueMap(FilterCondition(arrayListOf(filterElementRow))) val sessions = Filter.queryOn(realm, arrayListOf(filter)) Assert.assertEquals(1, sessions.size) sessions[0]?.run { - Assert.assertEquals(s1.id, (this as Session).id) + Assert.assertEquals(s1.id, (this).id) } } @@ -441,15 +441,15 @@ class DateFilterInstrumentedUnitTest : BaseFilterInstrumentedUnitTest() { realm.commitTransaction() val filter = QueryCondition.ENDED_FROM_DATE - val filterElementRow = FilterElementRow.From(s2.endDate()) + val filterElementRow = FilterElementRow.From.apply { dateValue = s2.endDate() } filterElementRow.filterSectionRow = FilterSectionRow.FIXED_DATE - filter.updateValueMap(FilterCondition(filterElementRow)) + filter.updateValueMap(FilterCondition(arrayListOf(filterElementRow))) val sessions = Filter.queryOn(realm, arrayListOf(filter)) Assert.assertEquals(1, sessions.size) sessions[0]?.run { - Assert.assertEquals(s2.id, (this as Session).id) + Assert.assertEquals(s2.id, (this).id) } } @@ -470,15 +470,15 @@ class DateFilterInstrumentedUnitTest : BaseFilterInstrumentedUnitTest() { val filter = QueryCondition.ENDED_TO_DATE - val filterElementRow = FilterElementRow.From(s1.endDate()) + val filterElementRow = FilterElementRow.From.apply { dateValue = s1.endDate() } filterElementRow.filterSectionRow = FilterSectionRow.FIXED_DATE - filter.updateValueMap(FilterCondition(filterElementRow)) + filter.updateValueMap(FilterCondition(arrayListOf(filterElementRow))) val sessions = Filter.queryOn(realm, arrayListOf(filter)) Assert.assertEquals(1, sessions.size) sessions[0]?.run { - Assert.assertEquals(s1.id, (this as Session).id) + Assert.assertEquals(s1.id, (this).id) } } } \ No newline at end of file diff --git a/app/src/androidTest/java/net/pokeranalytics/android/unitTests/filter/SessionFilterInstrumentedUnitTest.kt b/app/src/androidTest/java/net/pokeranalytics/android/unitTests/filter/SessionFilterInstrumentedUnitTest.kt index b4348fa2..1ad26832 100644 --- a/app/src/androidTest/java/net/pokeranalytics/android/unitTests/filter/SessionFilterInstrumentedUnitTest.kt +++ b/app/src/androidTest/java/net/pokeranalytics/android/unitTests/filter/SessionFilterInstrumentedUnitTest.kt @@ -30,7 +30,7 @@ class SessionFilterInstrumentedUnitTest : BaseFilterInstrumentedUnitTest() { Assert.assertEquals(1, sessions.size) sessions[0]?.run { - Assert.assertEquals(Session.Type.CASH_GAME.ordinal, (this as Session).type) + Assert.assertEquals(Session.Type.CASH_GAME.ordinal, (this).type) } } @@ -48,7 +48,7 @@ class SessionFilterInstrumentedUnitTest : BaseFilterInstrumentedUnitTest() { Assert.assertEquals(1, sessions.size) sessions[0]?.run { - Assert.assertEquals(Session.Type.TOURNAMENT.ordinal, (this as Session).type) + Assert.assertEquals(Session.Type.TOURNAMENT.ordinal, (this).type) } } @@ -480,9 +480,9 @@ class SessionFilterInstrumentedUnitTest : BaseFilterInstrumentedUnitTest() { realm.commitTransaction() val filter = QueryCondition.MORE_THAN_NET_RESULT - val filterElementRow = FilterElementRow.ResultMoreThan(204.0) + val filterElementRow = FilterElementRow.ResultMoreThan.apply { this.amount = 204.0 } filterElementRow.filterSectionRow = FilterSectionRow.VALUE - filter.updateValueMap(FilterCondition(filterElementRow)) + filter.updateValueMap(FilterCondition(arrayListOf(filterElementRow))) val sessions = Filter.queryOn(realm, arrayListOf(filter)) @@ -505,9 +505,9 @@ class SessionFilterInstrumentedUnitTest : BaseFilterInstrumentedUnitTest() { realm.commitTransaction() val filter = QueryCondition.LESS_THAN_NET_RESULT - val filterElementRow = FilterElementRow.ResultLessThan(540.0) + val filterElementRow = FilterElementRow.ResultMoreThan.apply { this.amount = 540.0 } filterElementRow.filterSectionRow = FilterSectionRow.VALUE - filter.updateValueMap(FilterCondition(filterElementRow)) + filter.updateValueMap(FilterCondition(arrayListOf(filterElementRow))) val sessions = Filter.queryOn(realm, arrayListOf(filter)) @@ -530,14 +530,14 @@ class SessionFilterInstrumentedUnitTest : BaseFilterInstrumentedUnitTest() { realm.commitTransaction() val filterMore = QueryCondition.MORE_THAN_NET_RESULT - val filterElementRow = FilterElementRow.ResultMoreThan(200.0) + val filterElementRow = FilterElementRow.ResultMoreThan.apply { this.amount = 200.0 } filterElementRow.filterSectionRow = FilterSectionRow.VALUE - filterMore.updateValueMap(FilterCondition(filterElementRow)) + filterMore.updateValueMap(FilterCondition(arrayListOf(filterElementRow))) val filterLess = QueryCondition.LESS_THAN_NET_RESULT - val filterElementRow2 = FilterElementRow.ResultLessThan(400.0) + val filterElementRow2 = FilterElementRow.ResultMoreThan.apply { this.amount = 400.0 } filterElementRow2.filterSectionRow = FilterSectionRow.VALUE - filterLess.updateValueMap(FilterCondition(filterElementRow2)) + filterLess.updateValueMap(FilterCondition(arrayListOf(filterElementRow2))) val sessions = Filter.queryOn(realm, arrayListOf(filterMore, filterLess)) diff --git a/app/src/main/java/net/pokeranalytics/android/PokerAnalyticsApplication.kt b/app/src/main/java/net/pokeranalytics/android/PokerAnalyticsApplication.kt index be1d6117..a92e3af4 100644 --- a/app/src/main/java/net/pokeranalytics/android/PokerAnalyticsApplication.kt +++ b/app/src/main/java/net/pokeranalytics/android/PokerAnalyticsApplication.kt @@ -14,6 +14,7 @@ import net.pokeranalytics.android.model.realm.Session import net.pokeranalytics.android.model.utils.Seed import net.pokeranalytics.android.util.FakeDataManager import net.pokeranalytics.android.util.PokerAnalyticsLogs +import net.pokeranalytics.android.util.UserDefaults import timber.log.Timber @@ -22,6 +23,8 @@ class PokerAnalyticsApplication : Application() { override fun onCreate() { super.onCreate() + UserDefaults.init(this) + println("UserPreferences.defaultCurrency: ${UserDefaults.currency.symbol}") // Realm Realm.init(this) diff --git a/app/src/main/java/net/pokeranalytics/android/calculus/Calculator.kt b/app/src/main/java/net/pokeranalytics/android/calculus/Calculator.kt index 2617ae13..e8cd78ca 100644 --- a/app/src/main/java/net/pokeranalytics/android/calculus/Calculator.kt +++ b/app/src/main/java/net/pokeranalytics/android/calculus/Calculator.kt @@ -147,19 +147,19 @@ class Calculator { tHands += computable.estimatedHands val session = computable.session ?: throw IllegalStateException("Computing lone ComputableResult") - results.addEvolutionValue(tSum, NETRESULT, session) - results.addEvolutionValue(tSum / index, AVERAGE, session) - results.addEvolutionValue(index.toDouble(), NUMBER_OF_GAMES, session) - results.addEvolutionValue(tBBSum / tBBSessionCount, AVERAGE_NET_BB, session) - results.addEvolutionValue((tWinningSessionCount / index).toDouble(), WIN_RATIO, session) - results.addEvolutionValue(tBuyinSum / index, AVERAGE_BUYIN, session) + results.addEvolutionValue(tSum, stat = NETRESULT, data = session) + results.addEvolutionValue(tSum / index, stat = AVERAGE, data = session) + results.addEvolutionValue(index.toDouble(), stat = NUMBER_OF_GAMES, data = session) + results.addEvolutionValue(tBBSum / tBBSessionCount, stat = AVERAGE_NET_BB, data = session) + results.addEvolutionValue((tWinningSessionCount / index).toDouble(), stat = WIN_RATIO, data = session) + results.addEvolutionValue(tBuyinSum / index, stat = AVERAGE_BUYIN, data = session) Stat.netBBPer100Hands(tBBSum, tHands)?.let { netBB100 -> - results.addEvolutionValue(netBB100, NET_BB_PER_100_HANDS, session) + results.addEvolutionValue(netBB100, stat = NET_BB_PER_100_HANDS, data = session) } Stat.returnOnInvestment(tSum, tBuyinSum)?.let { roi -> - results.addEvolutionValue(roi, ROI, session) + results.addEvolutionValue(roi, stat = ROI, data = session) } } diff --git a/app/src/main/java/net/pokeranalytics/android/calculus/Report.kt b/app/src/main/java/net/pokeranalytics/android/calculus/Report.kt index de8c329f..e97d56f9 100644 --- a/app/src/main/java/net/pokeranalytics/android/calculus/Report.kt +++ b/app/src/main/java/net/pokeranalytics/android/calculus/Report.kt @@ -158,13 +158,14 @@ class ComputedResults(group: ComputableGroup) { /** * Adds a value to the evolution values */ - fun addEvolutionValue(value: Double, stat: Stat, data: Any) { - this._addEvolutionValue(Point(value, data), stat = stat) - } + fun addEvolutionValue(value: Double, duration: Double? = null, stat: Stat, data: Timed) { - fun addEvolutionValue(value: Double, duration: Double, stat: Stat, data: Timed) { - stat.underlyingClass = data::class.java - this._addEvolutionValue(Point(value, y = duration, data = data.id), stat = stat) + val point = if (duration != null) { + Point(duration, y = value, data = data.objectIdentifier) + } else { + Point(value, data = data.objectIdentifier) + } + this._addEvolutionValue(point, stat = stat) } private fun _addEvolutionValue(point: Point, stat: Stat) { diff --git a/app/src/main/java/net/pokeranalytics/android/calculus/Stat.kt b/app/src/main/java/net/pokeranalytics/android/calculus/Stat.kt index 1b111ecf..efbf89c7 100644 --- a/app/src/main/java/net/pokeranalytics/android/calculus/Stat.kt +++ b/app/src/main/java/net/pokeranalytics/android/calculus/Stat.kt @@ -1,23 +1,27 @@ package net.pokeranalytics.android.calculus import android.content.Context -import io.realm.RealmModel import net.pokeranalytics.android.R import net.pokeranalytics.android.exceptions.FormattingException +import net.pokeranalytics.android.model.interfaces.Identifiable import net.pokeranalytics.android.model.interfaces.Timed import net.pokeranalytics.android.ui.view.RowRepresentable import net.pokeranalytics.android.ui.view.RowViewType -import net.pokeranalytics.android.util.CurrencyUtils import net.pokeranalytics.android.util.NULL_TEXT import net.pokeranalytics.android.util.extensions.formatted import net.pokeranalytics.android.util.extensions.formattedHourlyDuration +import net.pokeranalytics.android.util.extensions.toCurrency import java.util.* class StatFormattingException(message: String) : Exception(message) { } -interface StatBase : RealmModel { +class ObjectIdentifier(var id: String, var clazz: Class) { + +} + +interface StatBase : Identifiable { fun formattedValue(stat: Stat, context: Context): TextFormat @@ -48,7 +52,7 @@ enum class AggregationType { /** * An enum representing all the types of Session statistics */ -enum class Stat(var underlyingClass: Class? = null) : RowRepresentable { +enum class Stat : RowRepresentable { NETRESULT, HOURLY_RATE, @@ -132,9 +136,8 @@ enum class Stat(var underlyingClass: Class? = null) : RowRepresentabl when (this) { // Amounts + red/green Stat.NETRESULT, Stat.HOURLY_RATE, Stat.AVERAGE -> { - val numberFormat = CurrencyUtils.getCurrencyFormatter(context, currency) val color = if (value >= this.threshold) R.color.green else R.color.red - return TextFormat(numberFormat.format(value), color) + return TextFormat(value.toCurrency(currency), color) } // Red/green numericValues Stat.HOURLY_RATE_BB, Stat.AVERAGE_NET_BB, Stat.NET_BB_PER_100_HANDS -> { @@ -154,8 +157,7 @@ enum class Stat(var underlyingClass: Class? = null) : RowRepresentabl } // white amountsr Stat.AVERAGE_BUYIN, Stat.STANDARD_DEVIATION, Stat.STANDARD_DEVIATION_HOURLY, Stat.STANDARD_DEVIATION_BB_PER_100_HANDS -> { - val numberFormat = CurrencyUtils.getCurrencyFormatter(context, currency) - return TextFormat(numberFormat.format(value)) + return TextFormat(value.toCurrency(currency)) } else -> throw FormattingException("Stat formatting of ${this.name} not handled") } diff --git a/app/src/main/java/net/pokeranalytics/android/model/filter/QueryCondition.kt b/app/src/main/java/net/pokeranalytics/android/model/filter/QueryCondition.kt index 8b16e84b..b9f24f47 100644 --- a/app/src/main/java/net/pokeranalytics/android/model/filter/QueryCondition.kt +++ b/app/src/main/java/net/pokeranalytics/android/model/filter/QueryCondition.kt @@ -1,12 +1,9 @@ package net.pokeranalytics.android.model.filter -import io.realm.RealmList import io.realm.RealmQuery import net.pokeranalytics.android.exceptions.PokerAnalyticsException import net.pokeranalytics.android.model.realm.FilterCondition -import net.pokeranalytics.android.model.realm.FilterElementBlind import net.pokeranalytics.android.model.realm.Session -import net.pokeranalytics.android.util.Preferences import net.pokeranalytics.android.util.extensions.endOfDay import net.pokeranalytics.android.util.extensions.startOfDay import java.util.* @@ -32,7 +29,7 @@ enum class QueryCondition(var operator: Operator? = null) { LIMIT, TABLE_SIZE, TOURNAMENT_TYPE, - BLINDS, + BLIND, LAST_GAMES, LAST_SESSIONS, MORE_NUMBER_OF_TABLE(Operator.MORE), @@ -77,10 +74,6 @@ enum class QueryCondition(var operator: Operator? = null) { STARTED_FROM_TIME, ENDED_TO_TIME, - CURRENCY, - CURRENCY_CODE, - BIG_BLIND, - SMALL_BLIND, COMMENT, ; @@ -118,7 +111,7 @@ enum class QueryCondition(var operator: Operator? = null) { return when (this) { BANKROLL, GAME, LOCATION, ANY_TOURNAMENT_FEATURES, ALL_TOURNAMENT_FEATURES, TOURNAMENT_NAME -> arrayOf("ids") LIMIT, TOURNAMENT_TYPE, TABLE_SIZE -> arrayOf("values") - BLINDS -> arrayOf("blinds") + BLIND -> arrayOf("blinds", "hasDefaultCurrency") STARTED_FROM_DATE, STARTED_TO_DATE, ENDED_FROM_DATE, ENDED_TO_DATE -> arrayOf("date") DAY_OF_WEEK -> arrayOf("dayOfWeek") MONTH -> arrayOf("month") @@ -132,169 +125,145 @@ enum class QueryCondition(var operator: Operator? = null) { * providing a base RealmQuery [realmQuery], the method is able to attached the corresponding query and returns the newly formed [RealmQuery] */ inline fun filter(realmQuery: RealmQuery): RealmQuery { - when { - this == BLINDS -> { - - val smallBlindFieldName = FilterHelper.fieldNameForQueryType(SMALL_BLIND) - val bigBlindFieldName = FilterHelper.fieldNameForQueryType(BIG_BLIND) - val currencyCodeFieldName = FilterHelper.fieldNameForQueryType(CURRENCY_CODE) - smallBlindFieldName ?: throw PokerAnalyticsException.QueryValueMapUnknown - bigBlindFieldName ?: throw PokerAnalyticsException.QueryValueMapUnknown - currencyCodeFieldName ?: throw PokerAnalyticsException.QueryValueMapUnknown - - val blinds: RealmList by valueMap - blinds.forEachIndexed { index, blind -> - realmQuery - .beginGroup() - - blind.sb?.let { - realmQuery - .equalTo(smallBlindFieldName, it) - .and() - } - - realmQuery - .equalTo(bigBlindFieldName, blind.bb) - .and() - - blind.currencyCode?.let { - realmQuery.equalTo(currencyCodeFieldName, it) - } ?: run { - realmQuery.isNull(currencyCodeFieldName) - } - - realmQuery.endGroup() + val fieldName = FilterHelper.fieldNameForQueryType(this) + fieldName ?: throw PokerAnalyticsException.QueryValueMapUnknown + when (operator) { + Operator.LESS -> { + val value: Double by valueMap + return realmQuery.lessThanOrEqualTo(fieldName, value) + } + Operator.MORE -> { + val value: Double by valueMap + return realmQuery.greaterThanOrEqualTo(fieldName, value) + } + Operator.BETWEEN -> { + val leftValue: Double by valueMap + val rightValue: Double by valueMap + return realmQuery.between(fieldName, leftValue, rightValue) + } + } - if (index < blinds.size - 1) { - realmQuery.or() - } + return when (this) { + LIVE, ONLINE -> realmQuery.equalTo(fieldName, this == LIVE) + CASH -> realmQuery.equalTo(fieldName, Session.Type.CASH_GAME.ordinal) + TOURNAMENT -> realmQuery.equalTo(fieldName, Session.Type.TOURNAMENT.ordinal) + ALL_TOURNAMENT_FEATURES -> { + val ids: Array by valueMap + ids.forEach { + realmQuery.equalTo(fieldName, it) } - return realmQuery + realmQuery } - else -> { - - val fieldName = FilterHelper.fieldNameForQueryType(this) - fieldName ?: throw PokerAnalyticsException.QueryValueMapUnknown - - when (operator) { - Operator.LESS -> { - val value: Double by valueMap - return realmQuery.lessThanOrEqualTo(fieldName, value) - } - Operator.MORE -> { - val value: Double by valueMap - return realmQuery.greaterThanOrEqualTo(fieldName, value) - } - Operator.BETWEEN -> { - val leftValue: Double by valueMap - val rightValue: Double by valueMap - return realmQuery.between(fieldName, leftValue, rightValue) + ANY_TOURNAMENT_FEATURES -> { + val ids: Array by valueMap + realmQuery.`in`(fieldName, ids) + } + BLIND -> { + val blinds: Array by valueMap + val hasDefaultCurrency: Array by valueMap + //realmQuery.`in`(fieldName, blinds) + blinds.forEachIndexed { index, s -> + val isUsingDefaultCurrency = hasDefaultCurrency[index] + realmQuery.beginGroup() + if (isUsingDefaultCurrency) { + realmQuery.endsWith(fieldName, s) + .and() + .isNull("bankroll.currency.code") + } else { + realmQuery.equalTo(fieldName, s) } + .endGroup() + if (index < blinds.size - 1) { + realmQuery.or() + } } - - return when (this) { - LIVE, ONLINE -> realmQuery.equalTo(fieldName, this == LIVE) - CASH -> realmQuery.equalTo(fieldName, Session.Type.CASH_GAME.ordinal) - TOURNAMENT -> realmQuery.equalTo(fieldName, Session.Type.TOURNAMENT.ordinal) - ALL_TOURNAMENT_FEATURES -> { - val ids: Array by valueMap - ids.forEach { - realmQuery.equalTo(fieldName, it) - } - realmQuery - } - ANY_TOURNAMENT_FEATURES -> { - val ids: Array by valueMap - realmQuery.`in`(fieldName, ids) - } - BANKROLL, GAME, LOCATION, TOURNAMENT_NAME -> { - val ids: Array by valueMap - realmQuery.`in`(fieldName, ids) - } - LIMIT, TOURNAMENT_TYPE, TABLE_SIZE -> { - val values: Array? by valueMap - realmQuery.`in`(fieldName, values) - } - STARTED_FROM_DATE -> { - val date: Date by valueMap - realmQuery.greaterThanOrEqualTo(fieldName, date) - } - STARTED_TO_DATE -> { - val date: Date by valueMap - realmQuery.lessThanOrEqualTo(fieldName, date) - } - ENDED_FROM_DATE -> { - val date: Date by valueMap - realmQuery.greaterThanOrEqualTo(fieldName, date) - } - ENDED_TO_DATE -> { - val date: Date by valueMap - realmQuery.lessThanOrEqualTo(fieldName, date) - } - DAY_OF_WEEK -> { - val dayOfWeek: Int by valueMap - realmQuery.equalTo(fieldName, dayOfWeek) - } - MONTH -> { - val month: Int by valueMap - realmQuery.equalTo(fieldName, month) - } - YEAR -> { - val year: Int by valueMap - realmQuery.equalTo(fieldName, year) - } - WEEK_END, WEEK_DAY -> { - var query = realmQuery - if (this == WEEK_DAY) { - query = realmQuery.not() - } - query.`in`(fieldName, arrayOf(Calendar.SATURDAY, Calendar.SUNDAY)) - } - TODAY -> { - val startDate = Date() - realmQuery.between(fieldName, startDate.startOfDay(), startDate.endOfDay()) - } - TODAY_AND_YESTERDAY-> { - val startDate = Date() - val calendar = Calendar.getInstance() - calendar.time = startDate - calendar.add(Calendar.HOUR_OF_DAY, -24) - realmQuery.between(fieldName, calendar.time.startOfDay(), startDate.endOfDay()) - } - YESTERDAY -> { - val calendar = Calendar.getInstance() - calendar.time = Date() - calendar.add(Calendar.HOUR_OF_DAY, -24) - realmQuery.between(fieldName, calendar.time.startOfDay(), calendar.time.endOfDay()) - } - THIS_WEEK -> { - val startDate = Date() - val calendar = Calendar.getInstance() - calendar.time = startDate - calendar.set(Calendar.DAY_OF_WEEK_IN_MONTH, Calendar.SUNDAY) - realmQuery.between(fieldName, calendar.time.startOfDay(), startDate.endOfDay()) - } - THIS_MONTH -> { - val startDate = Date() - val calendar = Calendar.getInstance() - calendar.time = startDate - calendar.set(Calendar.DAY_OF_MONTH, 1) - realmQuery.between(fieldName, calendar.time.startOfDay(), startDate.endOfDay()) - } - THIS_YEAR -> { - val startDate = Date() - val calendar = Calendar.getInstance() - calendar.time = startDate - calendar.set(Calendar.DAY_OF_YEAR, 1) - realmQuery.between(fieldName, calendar.time.startOfDay(), startDate.endOfDay()) - } - else -> { - throw PokerAnalyticsException.QueryTypeUnhandled - } + realmQuery + } + BANKROLL, GAME, LOCATION, TOURNAMENT_NAME -> { + val ids: Array by valueMap + realmQuery.`in`(fieldName, ids) + } + LIMIT, TOURNAMENT_TYPE, TABLE_SIZE -> { + val values: Array? by valueMap + realmQuery.`in`(fieldName, values) + } + STARTED_FROM_DATE -> { + val date: Date by valueMap + realmQuery.greaterThanOrEqualTo(fieldName, date) + } + STARTED_TO_DATE -> { + val date: Date by valueMap + realmQuery.lessThanOrEqualTo(fieldName, date) + } + ENDED_FROM_DATE -> { + val date: Date by valueMap + realmQuery.greaterThanOrEqualTo(fieldName, date) + } + ENDED_TO_DATE -> { + val date: Date by valueMap + realmQuery.lessThanOrEqualTo(fieldName, date) + } + DAY_OF_WEEK -> { + val dayOfWeek: Int by valueMap + realmQuery.equalTo(fieldName, dayOfWeek) + } + MONTH -> { + val month: Int by valueMap + realmQuery.equalTo(fieldName, month) + } + YEAR -> { + val year: Int by valueMap + realmQuery.equalTo(fieldName, year) + } + WEEK_END, WEEK_DAY -> { + var query = realmQuery + if (this == WEEK_DAY) { + query = realmQuery.not() } + query.`in`(fieldName, arrayOf(Calendar.SATURDAY, Calendar.SUNDAY)) + } + TODAY -> { + val startDate = Date() + realmQuery.between(fieldName, startDate.startOfDay(), startDate.endOfDay()) + } + TODAY_AND_YESTERDAY-> { + val startDate = Date() + val calendar = Calendar.getInstance() + calendar.time = startDate + calendar.add(Calendar.HOUR_OF_DAY, -24) + realmQuery.between(fieldName, calendar.time.startOfDay(), startDate.endOfDay()) + } + YESTERDAY -> { + val calendar = Calendar.getInstance() + calendar.time = Date() + calendar.add(Calendar.HOUR_OF_DAY, -24) + realmQuery.between(fieldName, calendar.time.startOfDay(), calendar.time.endOfDay()) + } + THIS_WEEK -> { + val startDate = Date() + val calendar = Calendar.getInstance() + calendar.time = startDate + calendar.set(Calendar.DAY_OF_WEEK_IN_MONTH, Calendar.SUNDAY) + realmQuery.between(fieldName, calendar.time.startOfDay(), startDate.endOfDay()) + } + THIS_MONTH -> { + val startDate = Date() + val calendar = Calendar.getInstance() + calendar.time = startDate + calendar.set(Calendar.DAY_OF_MONTH, 1) + realmQuery.between(fieldName, calendar.time.startOfDay(), startDate.endOfDay()) + } + THIS_YEAR -> { + val startDate = Date() + val calendar = Calendar.getInstance() + calendar.time = startDate + calendar.set(Calendar.DAY_OF_YEAR, 1) + realmQuery.between(fieldName, calendar.time.startOfDay(), startDate.endOfDay()) + } + else -> { + throw PokerAnalyticsException.QueryTypeUnhandled } } - } fun updateValueMap(filterCondition: FilterCondition) { @@ -314,8 +283,10 @@ enum class QueryCondition(var operator: Operator? = null) { LIMIT, TOURNAMENT_TYPE, TABLE_SIZE -> { valueMap = mapOf("values" to filterCondition.values) } - BLINDS -> { - valueMap = mapOf("blinds" to filterCondition.blinds) + BLIND -> { + valueMap = mapOf( + "blinds" to filterCondition.blinds, + "hasDefaultCurrency" to filterCondition.hasDefaultCurrency) } STARTED_FROM_DATE, STARTED_TO_DATE, ENDED_FROM_DATE, ENDED_TO_DATE -> { valueMap = mapOf("date" to filterCondition.date) diff --git a/app/src/main/java/net/pokeranalytics/android/model/interfaces/Timed.kt b/app/src/main/java/net/pokeranalytics/android/model/interfaces/Timed.kt index 01431a6e..49ba2542 100644 --- a/app/src/main/java/net/pokeranalytics/android/model/interfaces/Timed.kt +++ b/app/src/main/java/net/pokeranalytics/android/model/interfaces/Timed.kt @@ -1,9 +1,10 @@ package net.pokeranalytics.android.model.interfaces +import net.pokeranalytics.android.calculus.ObjectIdentifier import net.pokeranalytics.android.calculus.StatBase import java.util.* -interface Timed : StatBase, Identifiable { +interface Timed : StatBase { fun startDate() : Date? @@ -29,4 +30,6 @@ interface Timed : StatBase, Identifiable { val hourlyDuration: Double get() = this.netDuration / 3600000.0 + val objectIdentifier : ObjectIdentifier + } \ No newline at end of file diff --git a/app/src/main/java/net/pokeranalytics/android/model/migrations/PokerAnalyticsMigration.kt b/app/src/main/java/net/pokeranalytics/android/model/migrations/PokerAnalyticsMigration.kt index 29e15c3b..2d41451d 100644 --- a/app/src/main/java/net/pokeranalytics/android/model/migrations/PokerAnalyticsMigration.kt +++ b/app/src/main/java/net/pokeranalytics/android/model/migrations/PokerAnalyticsMigration.kt @@ -35,7 +35,9 @@ class PokerAnalyticsMigration : RealmMigration { // Migrate to version 2 if (currentVersion == 1) { Timber.d("*** Running migration ${currentVersion + 1}") - + schema.get("Session")?.let { + it.addField("blinds", String::class.java).setNullable("blinds", true) + } schema.rename("FilterElement", "FilterCondition") schema.get("Filter")?.let { it.renameField("filterElements", "filterConditions") diff --git a/app/src/main/java/net/pokeranalytics/android/model/realm/Bankroll.kt b/app/src/main/java/net/pokeranalytics/android/model/realm/Bankroll.kt index c5a3df93..9ceba9f5 100644 --- a/app/src/main/java/net/pokeranalytics/android/model/realm/Bankroll.kt +++ b/app/src/main/java/net/pokeranalytics/android/model/realm/Bankroll.kt @@ -3,6 +3,8 @@ package net.pokeranalytics.android.model.realm import io.realm.Realm import io.realm.RealmList import io.realm.RealmObject +import io.realm.RealmResults +import io.realm.annotations.LinkingObjects import io.realm.annotations.PrimaryKey import io.realm.kotlin.where import net.pokeranalytics.android.R @@ -32,6 +34,9 @@ open class Bankroll() : RealmObject(), NameManageable, StaticRowRepresentableDat } } + @LinkingObjects("bankroll") + private val sessions: RealmResults? = null + @PrimaryKey override var id = UUID.randomUUID().toString() @@ -46,6 +51,12 @@ open class Bankroll() : RealmObject(), NameManageable, StaticRowRepresentableDat // The currency of the bankroll var currency: Currency? = null + fun currencyCodeHasBeenUpdated() { + sessions?.forEach { + it.bankrollHasBeenUpdated() + } + } + override fun getDisplayName(): String { return this.name } @@ -86,6 +97,7 @@ open class Bankroll() : RealmObject(), NameManageable, StaticRowRepresentableDat this.live = if (value is Boolean) !value else false } BankrollRow.CURRENCY -> { + //TODO handle a use default currency option this.currency?.code = value as String? } BankrollRow.RATE -> { diff --git a/app/src/main/java/net/pokeranalytics/android/model/realm/Currency.kt b/app/src/main/java/net/pokeranalytics/android/model/realm/Currency.kt index e6b96fca..60e67d27 100644 --- a/app/src/main/java/net/pokeranalytics/android/model/realm/Currency.kt +++ b/app/src/main/java/net/pokeranalytics/android/model/realm/Currency.kt @@ -1,8 +1,11 @@ package net.pokeranalytics.android.model.realm import io.realm.RealmObject +import io.realm.RealmResults import io.realm.annotations.Ignore +import io.realm.annotations.LinkingObjects import io.realm.annotations.PrimaryKey +import net.pokeranalytics.android.util.Preferences import java.util.* open class Currency : RealmObject() { @@ -13,10 +16,19 @@ open class Currency : RealmObject() { @PrimaryKey var id = UUID.randomUUID().toString() - /** + @LinkingObjects("currency") + private val bankrolls: RealmResults? = null + + /** * The currency code of the currency, i.e. USD, EUR... */ var code: String? = null + set(value) { + field = value + bankrolls?.forEach { + it.currencyCodeHasBeenUpdated() + } + } /** * The rate of the currency with the main currency diff --git a/app/src/main/java/net/pokeranalytics/android/model/realm/Filter.kt b/app/src/main/java/net/pokeranalytics/android/model/realm/Filter.kt index dbbba9bc..5184b586 100644 --- a/app/src/main/java/net/pokeranalytics/android/model/realm/Filter.kt +++ b/app/src/main/java/net/pokeranalytics/android/model/realm/Filter.kt @@ -65,8 +65,8 @@ open class Filter : RealmObject() { private set fun createOrUpdateFilterConditions(filterConditionRows: ArrayList) { - filterConditions.clear() - filterConditionRows + val casted = arrayListOf() + filterConditionRows .map { it.filterName } @@ -77,10 +77,14 @@ open class Filter : RealmObject() { it.filterName == filterName } .apply { - val casted = arrayListOf() casted.addAll(this) - filterConditions.add(FilterCondition(casted)) - } + val newFilterCondition = FilterCondition(casted) + val previousCondition = filterConditions.filter { + it.sectionName == newFilterCondition.filterName + } + filterConditions.removeAll(previousCondition) + filterConditions.add(newFilterCondition) + } } } diff --git a/app/src/main/java/net/pokeranalytics/android/model/realm/FilterCondition.kt b/app/src/main/java/net/pokeranalytics/android/model/realm/FilterCondition.kt index cd853f3d..52851300 100644 --- a/app/src/main/java/net/pokeranalytics/android/model/realm/FilterCondition.kt +++ b/app/src/main/java/net/pokeranalytics/android/model/realm/FilterCondition.kt @@ -23,6 +23,19 @@ open class FilterCondition() : RealmObject() { is DateFilterElementRow -> { this.dateValue = row.dateValue } + is Blind -> { + //TODO refactor raz + this.stringValues = RealmList().apply { + this.addAll(filterElementRows.map { + (it as Blind).blind + }) + } + this.booleanValues = RealmList().apply { + this.addAll(filterElementRows.map { + (it as Blind).hasDefaultCurrency + }) + } + } is StringFilterElementRow -> { this.stringValues = RealmList().apply { this.addAll(filterElementRows.map { @@ -37,13 +50,6 @@ open class FilterCondition() : RealmObject() { }) } } - is FilterElementBlind -> { - this.blindValues = RealmList().apply { - this.addAll(filterElementRows.map { - FilterElementBlind((it as FilterElementRow.Blind).sb, it.bb, it.code) - }) - } - } } } @@ -59,25 +65,18 @@ open class FilterCondition() : RealmObject() { private var numericValues: RealmList? = null private var dateValue: Date? = null private var stringValues: RealmList? = null - private var blindValues: RealmList? = null + private var booleanValues: RealmList? = null val ids: Array get() = stringValues?.toTypedArray() ?: throw PokerAnalyticsException.FilterElementExpectedValueMissing - val blinds: RealmList - get() { - blindValues?.let { - if (it.isNotEmpty()) { - return it - } else { - throw PokerAnalyticsException.FilterElementExpectedValueMissing - } - } - throw PokerAnalyticsException.FilterElementExpectedValueMissing - } + val blinds: Array + get() = stringValues?.toTypedArray() ?: throw PokerAnalyticsException.FilterElementExpectedValueMissing + val hasDefaultCurrency: Array + get() = booleanValues?.toTypedArray() ?: throw PokerAnalyticsException.FilterElementExpectedValueMissing - val date: Date + val date: Date get() = dateValue ?: throw PokerAnalyticsException.FilterElementExpectedValueMissing diff --git a/app/src/main/java/net/pokeranalytics/android/model/realm/FilterElementBlind.kt b/app/src/main/java/net/pokeranalytics/android/model/realm/FilterElementBlind.kt deleted file mode 100644 index ebde6cad..00000000 --- a/app/src/main/java/net/pokeranalytics/android/model/realm/FilterElementBlind.kt +++ /dev/null @@ -1,8 +0,0 @@ -package net.pokeranalytics.android.model.realm - -import io.realm.RealmObject - -open class FilterElementBlind(var sb : Double? = null, - var bb : Double? = null, - var currencyCode : String? = null -) : RealmObject() \ No newline at end of file diff --git a/app/src/main/java/net/pokeranalytics/android/model/realm/Session.kt b/app/src/main/java/net/pokeranalytics/android/model/realm/Session.kt index 486aca1b..0b7b044f 100644 --- a/app/src/main/java/net/pokeranalytics/android/model/realm/Session.kt +++ b/app/src/main/java/net/pokeranalytics/android/model/realm/Session.kt @@ -11,10 +11,7 @@ import io.realm.annotations.LinkingObjects import io.realm.annotations.PrimaryKey import io.realm.kotlin.where import net.pokeranalytics.android.R -import net.pokeranalytics.android.calculus.ComputedStat -import net.pokeranalytics.android.calculus.Stat -import net.pokeranalytics.android.calculus.StatFormattingException -import net.pokeranalytics.android.calculus.TextFormat +import net.pokeranalytics.android.calculus.* import net.pokeranalytics.android.exceptions.ModelException import net.pokeranalytics.android.model.Limit import net.pokeranalytics.android.model.LiveData @@ -35,8 +32,8 @@ import net.pokeranalytics.android.ui.view.RowViewType import net.pokeranalytics.android.ui.view.rowrepresentable.CustomizableRowRepresentable import net.pokeranalytics.android.ui.view.rowrepresentable.SeparatorRowRepresentable import net.pokeranalytics.android.ui.view.rowrepresentable.SessionRow -import net.pokeranalytics.android.util.CurrencyUtils import net.pokeranalytics.android.util.NULL_TEXT +import net.pokeranalytics.android.util.UserDefaults import net.pokeranalytics.android.util.extensions.* import java.util.* import java.util.Currency @@ -47,7 +44,6 @@ typealias BB = Double open class Session : RealmObject(), Savable, Editable, StaticRowRepresentableDataSource, RowRepresentable, Timed, TimeFilterable, Filterable { - enum class Type { CASH_GAME, TOURNAMENT @@ -78,10 +74,7 @@ open class Session : RealmObject(), Savable, Editable, StaticRowRepresentableDat LIMIT -> "limit" TABLE_SIZE -> "tableSize" TOURNAMENT_TYPE -> "tournamentType" - CURRENCY -> "bankroll.currency" - CURRENCY_CODE -> "bankroll.currency.code" - BIG_BLIND -> "cgBigBlind" - SMALL_BLIND -> "cgSmallBlind" + BLIND -> "blind" COMMENT -> "comment" BETWEEN_NUMBER_OF_TABLE, MORE_NUMBER_OF_TABLE, LESS_NUMBER_OF_TABLE -> "numberOfTable" MORE_THAN_NET_RESULT, LESS_THAN_NET_RESULT -> "computableResults.ratedNet" @@ -220,14 +213,22 @@ open class Session : RealmObject(), Savable, Editable, StaticRowRepresentableDat // The small blind value var cgSmallBlind: Double? = null + set(value) { + field = value + formatBlinds() + } // The big blind value var cgBigBlind: Double? = null set(value) { field = value this.computeStats() + formatBlinds() } + var blinds: String? = null + private set + // Tournament // The entry fee of the tournament @@ -245,6 +246,10 @@ open class Session : RealmObject(), Savable, Editable, StaticRowRepresentableDat // The features of the tournament, like Knockout, Shootout, Turbo... var tournamentFeatures: RealmList = RealmList() + fun bankrollHasBeenUpdated() { + formatBlinds() + } + /** * Manages impacts on SessionSets * Should be called when the start / end date are changed @@ -482,14 +487,19 @@ open class Session : RealmObject(), Savable, Editable, StaticRowRepresentableDat return NULL_TEXT } - /** - * Return the formatted blinds - */ - fun getBlinds(): String { - val currencyCode = bankroll?.currency?.code ?: CurrencyUtils.getLocaleCurrency().currencyCode - val currencySymbol = Currency.getInstance(currencyCode).symbol - return if (cgSmallBlind == null) NULL_TEXT else "$currencySymbol ${cgSmallBlind?.formatted()}/${cgBigBlind?.round()}" - } + val hasDefaultCurrency: Boolean + get() { + return bankroll?.currency?.code == null + } + + val currency : Currency + get() { + return bankroll?.currency?.code?.let { + Currency.getInstance(it) + } ?: run { + UserDefaults.currency + } + } /** * Return the game title @@ -508,6 +518,19 @@ open class Session : RealmObject(), Savable, Editable, StaticRowRepresentableDat return if (gameTitle.isNotBlank()) gameTitle else NULL_TEXT } + fun getFormattedBlinds(): String { + return blinds ?: NULL_TEXT + } + + private fun formatBlinds() { + blinds = null + if (cgBigBlind == null) return + cgBigBlind?.let { bb -> + val sb = cgSmallBlind ?: bb / 2.0 + blinds = "${currency.symbol} ${sb.formatted()}/${bb.round()}" + } + } + // LifeCycle /** @@ -558,7 +581,7 @@ open class Session : RealmObject(), Savable, Editable, StaticRowRepresentableDat CustomizableRowRepresentable( RowViewType.HEADER_TITLE_AMOUNT_BIG, title = getFormattedDuration(), - computedStat = ComputedStat(Stat.NETRESULT, result?.net ?: 0.0, CurrencyUtils.getCurrency(bankroll)) + computedStat = ComputedStat(Stat.NETRESULT, result?.net ?: 0.0, currency) ) ) rows.add(SeparatorRowRepresentable()) @@ -568,7 +591,7 @@ open class Session : RealmObject(), Savable, Editable, StaticRowRepresentableDat CustomizableRowRepresentable( RowViewType.HEADER_TITLE_AMOUNT_BIG, resId = R.string.pause, - computedStat = ComputedStat(Stat.NETRESULT, result?.net ?: 0.0, CurrencyUtils.getCurrency(bankroll)) + computedStat = ComputedStat(Stat.NETRESULT, result?.net ?: 0.0, currency) ) ) rows.add(SeparatorRowRepresentable()) @@ -578,14 +601,14 @@ open class Session : RealmObject(), Savable, Editable, StaticRowRepresentableDat CustomizableRowRepresentable( RowViewType.HEADER_TITLE_AMOUNT_BIG, title = getFormattedDuration(), - computedStat = ComputedStat(Stat.NETRESULT, result?.net ?: 0.0, CurrencyUtils.getCurrency(bankroll)) + computedStat = ComputedStat(Stat.NETRESULT, result?.net ?: 0.0, currency) ) ) rows.add( CustomizableRowRepresentable( RowViewType.HEADER_TITLE_AMOUNT, resId = R.string.hour_rate_without_pauses, - computedStat = ComputedStat(Stat.HOURLY_RATE, this.hourlyRate, CurrencyUtils.getCurrency(bankroll)) + computedStat = ComputedStat(Stat.HOURLY_RATE, this.hourlyRate, currency) ) ) @@ -624,20 +647,20 @@ open class Session : RealmObject(), Savable, Editable, StaticRowRepresentableDat override fun stringForRow(row: RowRepresentable, context: Context): String { return when (row) { SessionRow.BANKROLL -> bankroll?.name ?: NULL_TEXT - SessionRow.BLINDS -> getBlinds() + SessionRow.BLINDS -> getFormattedBlinds() SessionRow.BREAK_TIME -> if (this.breakDuration > 0.0) this.breakDuration.toMinutes() else NULL_TEXT - SessionRow.BUY_IN -> this.result?.buyin?.toCurrency(CurrencyUtils.getCurrency(bankroll)) ?: NULL_TEXT - SessionRow.CASHED_OUT, SessionRow.PRIZE, SessionRow.NET_RESULT -> this.result?.cashout?.toCurrency(CurrencyUtils.getCurrency(bankroll)) ?: NULL_TEXT + SessionRow.BUY_IN -> this.result?.buyin?.toCurrency(currency) ?: NULL_TEXT + SessionRow.CASHED_OUT, SessionRow.PRIZE, SessionRow.NET_RESULT -> this.result?.cashout?.toCurrency(currency) ?: NULL_TEXT SessionRow.COMMENT -> if (this.comment.isNotEmpty()) this.comment else NULL_TEXT SessionRow.END_DATE -> this.endDate?.shortDateTime() ?: NULL_TEXT SessionRow.GAME -> getFormattedGame() - SessionRow.INITIAL_BUY_IN -> tournamentEntryFee?.toCurrency(CurrencyUtils.getCurrency(bankroll)) ?: NULL_TEXT + SessionRow.INITIAL_BUY_IN -> tournamentEntryFee?.toCurrency(currency) ?: NULL_TEXT SessionRow.LOCATION -> location?.name ?: NULL_TEXT SessionRow.PLAYERS -> tournamentNumberOfPlayers?.toString() ?: NULL_TEXT SessionRow.POSITION -> result?.tournamentFinalPosition?.toString() ?: NULL_TEXT SessionRow.START_DATE -> this.startDate?.shortDateTime() ?: NULL_TEXT SessionRow.TABLE_SIZE -> this.tableSize?.let { TableSize(it).localizedTitle(context) } ?: NULL_TEXT - SessionRow.TIPS -> result?.tips?.toCurrency(CurrencyUtils.getCurrency(bankroll)) ?: NULL_TEXT + SessionRow.TIPS -> result?.tips?.toCurrency(currency) ?: NULL_TEXT SessionRow.TOURNAMENT_TYPE -> this.tournamentType?.let { TournamentType.values()[it].localizedTitle(context) } ?: run { @@ -860,7 +883,7 @@ open class Session : RealmObject(), Savable, Editable, StaticRowRepresentableDat } value?.let { - return stat.format(it, CurrencyUtils.getCurrency(this.bankroll), context) + return stat.format(it, currency, context) } ?: run { return TextFormat(NULL_TEXT) } @@ -871,6 +894,11 @@ open class Session : RealmObject(), Savable, Editable, StaticRowRepresentableDat } + // Timed + + override val objectIdentifier: ObjectIdentifier + get() = ObjectIdentifier(this.id, Session::class.java) + } diff --git a/app/src/main/java/net/pokeranalytics/android/model/realm/SessionSet.kt b/app/src/main/java/net/pokeranalytics/android/model/realm/SessionSet.kt index 9774e1b7..4b3178e7 100644 --- a/app/src/main/java/net/pokeranalytics/android/model/realm/SessionSet.kt +++ b/app/src/main/java/net/pokeranalytics/android/model/realm/SessionSet.kt @@ -7,6 +7,7 @@ import io.realm.RealmResults import io.realm.annotations.Ignore import io.realm.annotations.LinkingObjects import io.realm.annotations.PrimaryKey +import net.pokeranalytics.android.calculus.ObjectIdentifier import net.pokeranalytics.android.calculus.Stat import net.pokeranalytics.android.calculus.StatFormattingException import net.pokeranalytics.android.calculus.TextFormat @@ -109,5 +110,10 @@ open class SessionSet() : RealmObject(), Timed, Filterable { } + // Timed + + override val objectIdentifier: ObjectIdentifier + get() = ObjectIdentifier(this.id, SessionSet::class.java) + } diff --git a/app/src/main/java/net/pokeranalytics/android/model/utils/Seed.kt b/app/src/main/java/net/pokeranalytics/android/model/utils/Seed.kt index aa0d4988..2bc66fc3 100644 --- a/app/src/main/java/net/pokeranalytics/android/model/utils/Seed.kt +++ b/app/src/main/java/net/pokeranalytics/android/model/utils/Seed.kt @@ -5,11 +5,10 @@ import io.realm.Realm import io.realm.kotlin.where import net.pokeranalytics.android.model.realm.Bankroll import net.pokeranalytics.android.model.realm.Currency -import net.pokeranalytics.android.model.realm.Game import net.pokeranalytics.android.model.realm.TournamentFeature -import net.pokeranalytics.android.util.CurrencyUtils import java.util.* - +import net.pokeranalytics.android.model.realm.Game +import net.pokeranalytics.android.util.UserDefaults class Seed(var context:Context) : Realm.Transaction { @@ -32,7 +31,7 @@ class Seed(var context:Context) : Realm.Transaction { private fun createDefaultCurrencyAndBankroll(realm: Realm) { // Currency - val localeCurrency = CurrencyUtils.getLocaleCurrency() + val localeCurrency = UserDefaults.getLocaleCurrency() val defaultCurrency = Currency() defaultCurrency.code = localeCurrency.currencyCode realm.insertOrUpdate(defaultCurrency) diff --git a/app/src/main/java/net/pokeranalytics/android/ui/fragment/BankrollDataFragment.kt b/app/src/main/java/net/pokeranalytics/android/ui/fragment/BankrollDataFragment.kt index 586888cb..1f02d4ec 100644 --- a/app/src/main/java/net/pokeranalytics/android/ui/fragment/BankrollDataFragment.kt +++ b/app/src/main/java/net/pokeranalytics/android/ui/fragment/BankrollDataFragment.kt @@ -17,9 +17,9 @@ import net.pokeranalytics.android.ui.view.RowViewType import net.pokeranalytics.android.ui.view.rowrepresentable.BankrollRow import net.pokeranalytics.android.ui.view.rowrepresentable.CustomizableRowRepresentable import net.pokeranalytics.android.ui.view.rowrepresentable.SimpleRow -import net.pokeranalytics.android.util.CurrencyUtils import net.pokeranalytics.android.util.NULL_TEXT import net.pokeranalytics.android.util.Preferences +import net.pokeranalytics.android.util.extensions.toRate import retrofit2.Call import retrofit2.Response import java.util.* @@ -96,9 +96,9 @@ class BankrollDataFragment : EditableDataFragment(), StaticRowRepresentableDataS } BankrollRow.RATE -> { this.bankroll.currency?.rate?.let { rate -> - CurrencyUtils.getCurrencyRateFormatter().format(rate) + rate.toRate() } ?: run { - CurrencyUtils.getCurrencyRateFormatter().format(1.0) + 1.0.toRate() } } else -> super.stringForRow(row) @@ -119,7 +119,7 @@ class BankrollDataFragment : EditableDataFragment(), StaticRowRepresentableDataS BankrollRow.RATE -> { this.bankroll.currency?.rate?.let { rate -> - row.editingDescriptors(mapOf("defaultValue" to CurrencyUtils.getCurrencyRateFormatter().format(rate))) + row.editingDescriptors(mapOf("defaultValue" to rate.toRate())) } ?: run { row.editingDescriptors(mapOf()) } diff --git a/app/src/main/java/net/pokeranalytics/android/ui/fragment/GraphFragment.kt b/app/src/main/java/net/pokeranalytics/android/ui/fragment/GraphFragment.kt index 9577935c..effd8574 100644 --- a/app/src/main/java/net/pokeranalytics/android/ui/fragment/GraphFragment.kt +++ b/app/src/main/java/net/pokeranalytics/android/ui/fragment/GraphFragment.kt @@ -17,6 +17,7 @@ import com.google.android.material.chip.ChipGroup import kotlinx.android.synthetic.main.fragment_evograph.* import net.pokeranalytics.android.R import net.pokeranalytics.android.calculus.GraphType +import net.pokeranalytics.android.calculus.ObjectIdentifier import net.pokeranalytics.android.calculus.Stat import net.pokeranalytics.android.ui.activity.components.PokerAnalyticsActivity import net.pokeranalytics.android.ui.fragment.components.PokerAnalyticsFragment @@ -25,16 +26,11 @@ import net.pokeranalytics.android.ui.view.LegendView import net.pokeranalytics.android.util.extensions.ChipGroupExtension import net.pokeranalytics.android.util.extensions.px import net.pokeranalytics.android.util.extensions.toast - -interface GraphDataSource { - - -} +import java.text.DateFormat class GraphFragment : PokerAnalyticsFragment(), OnChartValueSelectedListener { private lateinit var parentActivity: PokerAnalyticsActivity - lateinit var dataSource: GraphDataSource private var stat: Stat = Stat.NETRESULT private var entries: List = ArrayList() @@ -70,7 +66,7 @@ class GraphFragment : PokerAnalyticsFragment(), OnChartValueSelectedListener { this.legendView = LegendView(requireContext()) this.legendContainer.addView(this.legendView) - this.legendView.prepareWithStat(this.stat) + this.legendView.prepareWithStat(this.stat, this.entries.size) val dataSet = LineDataSet(this.entries, this.stat.name) val colors = arrayOf(R.color.green_light).toIntArray() @@ -125,23 +121,16 @@ class GraphFragment : PokerAnalyticsFragment(), OnChartValueSelectedListener { e?.let { entry -> h?.let { highlight -> - val id = entry.data as String - val item = getRealm().where(this.stat.underlyingClass).equalTo("id", id).findAll().firstOrNull() + val identifier = entry.data as ObjectIdentifier + val item = getRealm().where(identifier.clazz).equalTo("id", identifier.id).findAll().firstOrNull() item?.let { - val date = it.startDate() - - val entryStatName = this.stat.localizedTitle(requireContext()) + val formattedDate = DateFormat.getDateInstance(DateFormat.SHORT).format(it.startDate()) val entryValue = it.formattedValue(this.stat, requireContext()) - - val totalStatName = this.stat.cumulativeLabelResId(requireContext()) val totalStatValue = this.stat.format(e.y.toDouble(), null, requireContext()) + this.legendView.setItemData(this.stat, formattedDate, entryValue, totalStatValue) } - -// this.text.text = "" - - } } diff --git a/app/src/main/java/net/pokeranalytics/android/ui/fragment/SessionFragment.kt b/app/src/main/java/net/pokeranalytics/android/ui/fragment/SessionFragment.kt index b318e54b..41fdd733 100644 --- a/app/src/main/java/net/pokeranalytics/android/ui/fragment/SessionFragment.kt +++ b/app/src/main/java/net/pokeranalytics/android/ui/fragment/SessionFragment.kt @@ -27,7 +27,6 @@ import net.pokeranalytics.android.ui.view.RowRepresentable import net.pokeranalytics.android.ui.view.RowRepresentableDiffCallback import net.pokeranalytics.android.ui.view.SmoothScrollLinearLayoutManager import net.pokeranalytics.android.ui.view.rowrepresentable.SessionRow -import net.pokeranalytics.android.util.CurrencyUtils import java.util.* @@ -104,9 +103,9 @@ class SessionFragment : PokerAnalyticsFragment(), RowRepresentableDelegate { } SessionRow.BANKROLL -> { - BottomSheetFragment.create(fragmentManager, row, this, data, false, CurrencyUtils.getCurrency(currentSession.bankroll)) + BottomSheetFragment.create(fragmentManager, row, this, data, false, currentSession.currency) } - else -> BottomSheetFragment.create(fragmentManager, row, this, data, currentCurrency = CurrencyUtils.getCurrency(currentSession.bankroll)) + else -> BottomSheetFragment.create(fragmentManager, row, this, data, currentCurrency = currentSession.currency) } } diff --git a/app/src/main/java/net/pokeranalytics/android/ui/fragment/SettingsFragment.kt b/app/src/main/java/net/pokeranalytics/android/ui/fragment/SettingsFragment.kt index cb19e3d0..7b4af852 100644 --- a/app/src/main/java/net/pokeranalytics/android/ui/fragment/SettingsFragment.kt +++ b/app/src/main/java/net/pokeranalytics/android/ui/fragment/SettingsFragment.kt @@ -7,9 +7,11 @@ import android.view.LayoutInflater import android.view.View import android.view.ViewGroup import androidx.recyclerview.widget.LinearLayoutManager +import io.realm.Realm import kotlinx.android.synthetic.main.fragment_settings.* import net.pokeranalytics.android.BuildConfig import net.pokeranalytics.android.R +import net.pokeranalytics.android.model.realm.Bankroll import net.pokeranalytics.android.ui.activity.CurrenciesActivity import net.pokeranalytics.android.ui.activity.DataListActivity import net.pokeranalytics.android.ui.activity.GDPRActivity @@ -22,6 +24,7 @@ import net.pokeranalytics.android.ui.view.RowRepresentable import net.pokeranalytics.android.ui.view.rowrepresentable.SettingRow import net.pokeranalytics.android.util.Preferences import net.pokeranalytics.android.util.URL +import net.pokeranalytics.android.util.UserDefaults import net.pokeranalytics.android.util.extensions.openContactMail import net.pokeranalytics.android.util.extensions.openPlayStorePage import net.pokeranalytics.android.util.extensions.openUrl @@ -70,6 +73,13 @@ class SettingsFragment : PokerAnalyticsFragment(), RowRepresentableDelegate, Sta if (requestCode == REQUEST_CODE_CURRENCY && resultCode == Activity.RESULT_OK) { data?.let { Preferences.setCurrencyCode(data.getStringExtra(CurrenciesFragment.INTENT_CURRENCY_CODE), requireContext()) + val realm = Realm.getDefaultInstance() + realm.executeTransaction { + it.where(Bankroll::class.java).isNull("currency.code").findAll().forEach { bankroll -> + bankroll.currencyCodeHasBeenUpdated() + } + } + realm.close() settingsAdapterRow.refreshRow(SettingRow.CURRENCY) } } diff --git a/app/src/main/java/net/pokeranalytics/android/ui/view/LegendView.kt b/app/src/main/java/net/pokeranalytics/android/ui/view/LegendView.kt index a5d4ad1b..03552cde 100644 --- a/app/src/main/java/net/pokeranalytics/android/ui/view/LegendView.kt +++ b/app/src/main/java/net/pokeranalytics/android/ui/view/LegendView.kt @@ -8,8 +8,8 @@ import androidx.constraintlayout.widget.ConstraintLayout import kotlinx.android.synthetic.main.layout_legend_default.view.* import net.pokeranalytics.android.R import net.pokeranalytics.android.calculus.Stat -import net.pokeranalytics.android.model.realm.Session - +import net.pokeranalytics.android.calculus.TextFormat +import net.pokeranalytics.android.ui.view.fields.setTextFormat /** * Display a row session @@ -46,23 +46,22 @@ class LegendView : FrameLayout { /** * Set the stat data to the view */ - fun prepareWithStat(stat: Stat) { + fun prepareWithStat(stat: Stat, counter: Int) { this.stat1Name.text = stat.localizedTitle(context) this.stat2Name.text = stat.cumulativeLabelResId(context) - - //TODO: Set real data - this.title.text = "11/04/2019" - this.stat1Value.text = "$521" - this.stat2Value.text = "$15,051" - this.counter.text = "21 Sessions" + this.counter.text = "$counter ${context.getString(R.string.sessions)}" } /** * */ - fun setData(session: Session) { + fun setItemData(stat: Stat, title: String, statFormat1: TextFormat, statFormat2: TextFormat) { + + this.title.text = title + this.stat1Value.setTextFormat(statFormat1, context) + this.stat2Value.setTextFormat(statFormat2, context) } diff --git a/app/src/main/java/net/pokeranalytics/android/ui/view/RowViewType.kt b/app/src/main/java/net/pokeranalytics/android/ui/view/RowViewType.kt index 5757a64d..1659120d 100644 --- a/app/src/main/java/net/pokeranalytics/android/ui/view/RowViewType.kt +++ b/app/src/main/java/net/pokeranalytics/android/ui/view/RowViewType.kt @@ -16,6 +16,7 @@ import net.pokeranalytics.android.R import net.pokeranalytics.android.model.realm.Session import net.pokeranalytics.android.model.realm.Transaction import net.pokeranalytics.android.ui.adapter.RowRepresentableAdapter +import net.pokeranalytics.android.ui.view.fields.setTextFormat import net.pokeranalytics.android.ui.view.rowrepresentable.CustomizableRowRepresentable /** @@ -121,8 +122,9 @@ enum class RowViewType(private var layoutRes: Int) { itemView.findViewById(R.id.value)?.let { if (row.computedStat != null) { val format = row.computedStat!!.format(itemView.context) - it.setTextColor(format.getColor(itemView.context)) - it.text = format.text + it.setTextFormat(format, itemView.context) +// it.setTextColor(format.getColor(itemView.context)) +// it.text = format.text } else if (row.value != null) { it.text = row.value } @@ -229,8 +231,9 @@ enum class RowViewType(private var layoutRes: Int) { // Value itemView.findViewById(R.id.value)?.let { view -> adapter.dataSource.contentDescriptorForRow(row)?.textFormat?.let { - view.text = it.text - view.setTextColor(it.getColor(itemView.context)) + view.setTextFormat(it, itemView.context) +// view.text = it.text +// view.setTextColor(it.getColor(itemView.context)) } } diff --git a/app/src/main/java/net/pokeranalytics/android/ui/view/SessionRowView.kt b/app/src/main/java/net/pokeranalytics/android/ui/view/SessionRowView.kt index 6cef22f9..bce8118f 100644 --- a/app/src/main/java/net/pokeranalytics/android/ui/view/SessionRowView.kt +++ b/app/src/main/java/net/pokeranalytics/android/ui/view/SessionRowView.kt @@ -15,7 +15,7 @@ import net.pokeranalytics.android.model.TournamentType import net.pokeranalytics.android.model.extensions.SessionState import net.pokeranalytics.android.model.extensions.getState import net.pokeranalytics.android.model.realm.Session -import net.pokeranalytics.android.util.CurrencyUtils +import net.pokeranalytics.android.ui.view.fields.setTextFormat import net.pokeranalytics.android.util.extensions.getDayNumber import net.pokeranalytics.android.util.extensions.getShortDayName import net.pokeranalytics.android.util.extensions.shortTime @@ -68,7 +68,7 @@ class SessionRowView : FrameLayout { if (session.isTournament()) { session.tournamentEntryFee?.let { - parameters.add(it.toCurrency(CurrencyUtils.getCurrency(session.bankroll))) + parameters.add(it.toCurrency(session.currency)) } session.tournamentName?.let { @@ -85,7 +85,7 @@ class SessionRowView : FrameLayout { } } else { if (session.cgSmallBlind != null && session.cgBigBlind != null) { - parameters.add(session.getBlinds()) + parameters.add(session.getFormattedBlinds()) } session.game?.let { parameters.add(session.getFormattedGame()) @@ -149,9 +149,10 @@ class SessionRowView : FrameLayout { rowHistorySession.infoTitle.isVisible = false val result = session.result?.net ?: 0.0 - val formattedStat = ComputedStat(Stat.NETRESULT, result, currency = CurrencyUtils.getCurrency(session.bankroll)).format(context) - rowHistorySession.gameResult.setTextColor(formattedStat.getColor(context)) - rowHistorySession.gameResult.text = formattedStat.text + val formattedStat = ComputedStat(Stat.NETRESULT, result, currency = session.currency).format(context) + rowHistorySession.gameResult.setTextFormat(formattedStat, context) +// rowHistorySession.gameResult.setTextColor(formattedStat.getColor(context)) +// rowHistorySession.gameResult.text = formattedStat.text } } diff --git a/app/src/main/java/net/pokeranalytics/android/ui/view/TransactionRowView.kt b/app/src/main/java/net/pokeranalytics/android/ui/view/TransactionRowView.kt index ab45b09c..25f3b5a3 100644 --- a/app/src/main/java/net/pokeranalytics/android/ui/view/TransactionRowView.kt +++ b/app/src/main/java/net/pokeranalytics/android/ui/view/TransactionRowView.kt @@ -10,6 +10,7 @@ import net.pokeranalytics.android.R import net.pokeranalytics.android.calculus.ComputedStat import net.pokeranalytics.android.calculus.Stat import net.pokeranalytics.android.model.realm.Transaction +import net.pokeranalytics.android.ui.view.fields.setTextFormat import net.pokeranalytics.android.util.extensions.getDayNumber import net.pokeranalytics.android.util.extensions.getShortDayName @@ -63,8 +64,9 @@ class TransactionRowView : FrameLayout { // Amount val formattedStat = ComputedStat(Stat.NETRESULT, transaction.amount).format(context) - rowTransaction.transactionAmount.setTextColor(formattedStat.getColor(context)) - rowTransaction.transactionAmount.text = formattedStat.text + rowTransaction.transactionAmount.setTextFormat(formattedStat, context) +// rowTransaction.transactionAmount.setTextColor(formattedStat.getColor(context)) +// rowTransaction.transactionAmount.text = formattedStat.text } diff --git a/app/src/main/java/net/pokeranalytics/android/ui/view/fields/FieldsExtension.kt b/app/src/main/java/net/pokeranalytics/android/ui/view/fields/FieldsExtension.kt new file mode 100644 index 00000000..1a7b35c5 --- /dev/null +++ b/app/src/main/java/net/pokeranalytics/android/ui/view/fields/FieldsExtension.kt @@ -0,0 +1,10 @@ +package net.pokeranalytics.android.ui.view.fields + +import android.content.Context +import androidx.appcompat.widget.AppCompatTextView +import net.pokeranalytics.android.calculus.TextFormat + +fun AppCompatTextView.setTextFormat(textFormat: TextFormat, context: Context) { + this.setTextColor(textFormat.getColor(context)) + this.text = textFormat.text +} \ No newline at end of file diff --git a/app/src/main/java/net/pokeranalytics/android/ui/view/rowrepresentable/FilterCategoryRow.kt b/app/src/main/java/net/pokeranalytics/android/ui/view/rowrepresentable/FilterCategoryRow.kt index e9ac2482..d22bd4d0 100644 --- a/app/src/main/java/net/pokeranalytics/android/ui/view/rowrepresentable/FilterCategoryRow.kt +++ b/app/src/main/java/net/pokeranalytics/android/ui/view/rowrepresentable/FilterCategoryRow.kt @@ -54,7 +54,7 @@ enum class FilterCategoryRow(override val resId: Int?, override val viewType: In BANKROLL ) CASH -> arrayListOf( - BLINDS, + BLIND, CASH_RE_BUY_COUNT ) TOURNAMENT -> arrayListOf( diff --git a/app/src/main/java/net/pokeranalytics/android/ui/view/rowrepresentable/FilterElementRow.kt b/app/src/main/java/net/pokeranalytics/android/ui/view/rowrepresentable/FilterElementRow.kt index d66d513f..747a2db6 100644 --- a/app/src/main/java/net/pokeranalytics/android/ui/view/rowrepresentable/FilterElementRow.kt +++ b/app/src/main/java/net/pokeranalytics/android/ui/view/rowrepresentable/FilterElementRow.kt @@ -11,10 +11,8 @@ import net.pokeranalytics.android.ui.fragment.components.bottomsheet.BottomSheet import net.pokeranalytics.android.ui.view.RowRepresentable import net.pokeranalytics.android.ui.view.RowRepresentableEditDescriptor import net.pokeranalytics.android.ui.view.RowViewType -import net.pokeranalytics.android.util.CurrencyUtils -import net.pokeranalytics.android.util.NULL_TEXT -import net.pokeranalytics.android.util.extensions.formatted -import net.pokeranalytics.android.util.extensions.round +import net.pokeranalytics.android.util.Preferences +import net.pokeranalytics.android.util.UserDefaults import java.text.DateFormatSymbols import java.util.* @@ -105,14 +103,7 @@ sealed class FilterElementRow : RowRepresentable { data class Month(val month: Int) : SingleValueFilterElementRow(month) data class Day(val day: Int) : SingleValueFilterElementRow(day) - data class Blind(var sb: Double? = null, var bb: Double? = null, var code: String? = null) : FilterElementRow() { - val name: String - get() { - val currencyCode = code ?: CurrencyUtils.getLocaleCurrency().currencyCode - val currencySymbol = Currency.getInstance(currencyCode).symbol - return if (sb == null) NULL_TEXT else "$currencySymbol ${sb?.formatted()}/${bb?.round()}" - } - } + data class Blind(val blind: String, val hasDefaultCurrency: Boolean) : StringFilterElementRow(blind) //TODO: Refactor? data class PastDays(var lastDays: Int = 0) : SingleValueFilterElementRow(lastDays) { @@ -155,7 +146,7 @@ sealed class FilterElementRow : RowRepresentable { return when (this) { is Cash -> QueryCondition.CASH is Tournament -> QueryCondition.TOURNAMENT - is Blind -> QueryCondition.BLINDS + is Blind -> QueryCondition.BLIND is From -> QueryCondition.STARTED_FROM_DATE is To -> QueryCondition.ENDED_TO_DATE is FromTime -> QueryCondition.STARTED_FROM_TIME @@ -308,8 +299,8 @@ sealed class FilterElementRow : RowRepresentable { } is DataFilterElementRow -> this.name is StaticDataFilterElementRow -> this.name - is Blind -> this.name - else -> super.getDisplayName() + is Blind -> this.blind + else -> super.getDisplayName() } } diff --git a/app/src/main/java/net/pokeranalytics/android/ui/view/rowrepresentable/FilterSectionRow.kt b/app/src/main/java/net/pokeranalytics/android/ui/view/rowrepresentable/FilterSectionRow.kt index bebfde32..f64bc0ba 100644 --- a/app/src/main/java/net/pokeranalytics/android/ui/view/rowrepresentable/FilterSectionRow.kt +++ b/app/src/main/java/net/pokeranalytics/android/ui/view/rowrepresentable/FilterSectionRow.kt @@ -30,7 +30,7 @@ enum class FilterSectionRow(override val resId: Int?) : RowRepresentable { SESSION_DURATION(net.pokeranalytics.android.R.string.session_duration), RANGE(net.pokeranalytics.android.R.string.hour_slot), SESSIONS(R.string.sessions), - BLINDS(net.pokeranalytics.android.R.string.blinds), + BLIND(net.pokeranalytics.android.R.string.blinds), CASH_RE_BUY_COUNT(net.pokeranalytics.android.R.string.rebuy_count), TOURNAMENT_TYPE(net.pokeranalytics.android.R.string.tournament_types), TOURNAMENT_NAME(net.pokeranalytics.android.R.string.tournament_name), @@ -160,38 +160,17 @@ enum class FilterSectionRow(override val resId: Int?) : RowRepresentable { SESSIONS -> arrayListOf(LastGames(0), LastSessions(0)) // Cash - BLINDS -> { - - // TODO: Improve the way we get the blinds distinctly - val blinds = arrayListOf() + BLIND -> { + val blinds = arrayListOf() val realm = Realm.getDefaultInstance() - val sessions = - realm.where().isNotNull("cgSmallBlind").isNotNull("cgBigBlind").findAll() - .sort("cgSmallBlind", Sort.ASCENDING) - - val distinctBlinds: ArrayList = ArrayList() - val blindsHashMap: ArrayList = ArrayList() - sessions.forEach { - if (!blindsHashMap.contains(it.getBlinds())) { - blindsHashMap.add(it.getBlinds()) - distinctBlinds.add(it) - } - } - - distinctBlinds.forEach { session -> - blinds.add( - Blind( - session.cgSmallBlind, - session.cgBigBlind, - session.bankroll?.currency?.code - ) - ) - session.getBlinds() - } + realm.where().distinct("blind", "bankroll.currency.code").findAll().sort("cgSmallBlind", Sort.ASCENDING).map { + it.blinds?.let { stake -> + blinds.add(Blind(stake, it.hasDefaultCurrency)) + } + } realm.close() - - blinds - } + blinds + } CASH_RE_BUY_COUNT -> arrayListOf( ReBuyMoreThan as FilterElementRow, ReBuyLessThan as FilterElementRow diff --git a/app/src/main/java/net/pokeranalytics/android/util/CurrencyUtils.kt b/app/src/main/java/net/pokeranalytics/android/util/CurrencyUtils.kt deleted file mode 100644 index 2aa76778..00000000 --- a/app/src/main/java/net/pokeranalytics/android/util/CurrencyUtils.kt +++ /dev/null @@ -1,64 +0,0 @@ -package net.pokeranalytics.android.util - -import android.content.Context -import net.pokeranalytics.android.model.realm.Bankroll -import java.text.NumberFormat -import java.util.* - -class CurrencyUtils { - - companion object { - - /** - * return the currency associated with this bankroll - */ - fun getCurrency(bankroll: Bankroll? = null) : Currency { - val currencyCode = bankroll?.currency?.code ?: CurrencyUtils.getLocaleCurrency().currencyCode - return Currency.getInstance(currencyCode) - } - - /** - * Get a currency formatter - */ - fun getCurrencyFormatter(context: Context, currency: Currency? = null) : NumberFormat { - val currencyFormatter = NumberFormat.getCurrencyInstance(Preferences.getCurrencyLocale(context)) - currency?.let { - currencyFormatter.currency = it - } - currencyFormatter.minimumFractionDigits = 0 - currencyFormatter.maximumFractionDigits = 2 - return currencyFormatter - } - - /** - * Get a currency rate formatter - */ - fun getCurrencyRateFormatter() : NumberFormat { - val currencyFormatter = NumberFormat.getInstance() - currencyFormatter.minimumFractionDigits = 0 - currencyFormatter.maximumFractionDigits = 6 - return currencyFormatter - } - - /** - * 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")) - } - } - } - - } - -} \ No newline at end of file diff --git a/app/src/main/java/net/pokeranalytics/android/util/Preferences.kt b/app/src/main/java/net/pokeranalytics/android/util/Preferences.kt index adfe3790..13a13beb 100644 --- a/app/src/main/java/net/pokeranalytics/android/util/Preferences.kt +++ b/app/src/main/java/net/pokeranalytics/android/util/Preferences.kt @@ -16,8 +16,6 @@ class Preferences { companion object { - var currencyLocale : Locale? = null - fun setString(key: Keys, value: String, context: Context) { val preferences = PreferenceManager.getDefaultSharedPreferences(context) val editor = preferences.edit() @@ -43,21 +41,16 @@ class Preferences { } fun setCurrencyCode(currencyCode: String, context: Context) { - Preferences.setString(Keys.CURRENCY_CODE, currencyCode, context) - currencyLocale = null + setString(Keys.CURRENCY_CODE, currencyCode, context) + UserDefaults.setCurrencyValues(context) } private fun getCurrencyCode(context: Context) : String? { - return Preferences.getString(Keys.CURRENCY_CODE, context) + return getString(Keys.CURRENCY_CODE, context) } - fun getCurrencyLocale(context : Context) : Locale { - - currencyLocale?. let { - return it - } - - Preferences.getCurrencyCode(context)?.let { currencyCode -> + fun getCurrencyLocale(context : Context) : Locale? { + getCurrencyCode(context)?.let { currencyCode -> Locale.getAvailableLocales().filter{ try { Currency.getInstance(it).currencyCode == currencyCode @@ -65,22 +58,87 @@ class Preferences { false } }.first().let { - currencyLocale = it return it } } - currencyLocale = Locale.getDefault() - return currencyLocale!! + return null + } + + fun getDefaultCurrency(context: Context) : Currency? { + getCurrencyLocale(context)?.let { + return Currency.getInstance(it) + } + return null } fun setStopShowingDisclaimer(context: Context) { - Preferences.setBoolean(Keys.STOP_SHOWING_DISCLAIMER, true, context) + setBoolean(Keys.STOP_SHOWING_DISCLAIMER, true, context) } fun shouldShowDisclaimer(context: Context) : Boolean { - return !Preferences.getBoolean(Keys.STOP_SHOWING_DISCLAIMER, context) + return !getBoolean(Keys.STOP_SHOWING_DISCLAIMER, context) } } +} + +class UserDefaults private constructor(context: Context) { + init { + setCurrencyValues(context) + } + + companion object : SingletonHolder(::UserDefaults) { + lateinit var currency : Currency + lateinit var currencyLocale : Locale + + fun setCurrencyValues(context: Context) { + currency = Preferences.getDefaultCurrency(context) ?: getLocaleCurrency() + currencyLocale = Preferences.getCurrencyLocale(context) ?: Locale.getDefault() + } + + /** + * 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")) + } + } + } + } +} + + +open class SingletonHolder(creator: (A) -> T) { + private var creator: ((A) -> T)? = creator + @Volatile private var instance: T? = null + + fun init(context: A): T { + val i = instance + if (i != null) { + return i + } + + return synchronized(this) { + val i2 = instance + if (i2 != null) { + i2 + } else { + val created = creator!!(context) + instance = created + creator = null + created + } + } + } } \ No newline at end of file diff --git a/app/src/main/java/net/pokeranalytics/android/util/extensions/NumbersExtension.kt b/app/src/main/java/net/pokeranalytics/android/util/extensions/NumbersExtension.kt index 88330925..5ee1d3cd 100644 --- a/app/src/main/java/net/pokeranalytics/android/util/extensions/NumbersExtension.kt +++ b/app/src/main/java/net/pokeranalytics/android/util/extensions/NumbersExtension.kt @@ -2,6 +2,7 @@ package net.pokeranalytics.android.util.extensions import android.content.Context import net.pokeranalytics.android.R +import net.pokeranalytics.android.util.UserDefaults import java.text.DecimalFormat import java.text.NumberFormat import java.util.* @@ -23,7 +24,7 @@ fun Double.formatted(): String { fun Double.toCurrency(currency: Currency? = null): String { - val currencyFormatter = NumberFormat.getCurrencyInstance() + val currencyFormatter = NumberFormat.getCurrencyInstance(UserDefaults.currencyLocale) currency?.let { currencyFormatter.currency = currency } @@ -33,6 +34,14 @@ fun Double.toCurrency(currency: Currency? = null): String { return currencyFormatter.format(this) } + +fun Double.toRate(): String { + val currencyFormatter = NumberFormat.getInstance() + currencyFormatter.minimumFractionDigits = 0 + currencyFormatter.maximumFractionDigits = 6 + return currencyFormatter.format(this) +} + fun Double.formattedHourlyDuration() : String { return (this * 1000 * 3600).toLong().toMinutes() }