You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
poker-analytics/app/src/main/java/net/pokeranalytics/android/model/Criteria.kt

213 lines
8.5 KiB

package net.pokeranalytics.android.model
import io.realm.Realm
import io.realm.Sort
import io.realm.kotlin.where
import net.pokeranalytics.android.exceptions.PokerAnalyticsException
import net.pokeranalytics.android.model.filter.QueryCondition
import net.pokeranalytics.android.model.interfaces.NameManageable
import net.pokeranalytics.android.model.realm.*
import java.util.*
import kotlin.collections.ArrayList
fun List<Criteria>.combined(): List<List<QueryCondition>> {
val comparatorList = ArrayList<List<QueryCondition>>()
this.forEach {
comparatorList.add(it.queryConditions)
}
return getCombinations(comparatorList)
}
fun List<List<QueryCondition>>.upToNow(): List<List<QueryCondition>> {
val calendar = Calendar.getInstance()
calendar.time = Date()
val currentYear = calendar.get(Calendar.YEAR)
val currentMonth = calendar.get(Calendar.MONTH)
val realm = Realm.getDefaultInstance()
val firstSession = realm.where<Session>().sort("year", Sort.ASCENDING).findFirst()
realm.close()
val firstYear = firstSession?.year ?: currentYear
val firstMonth = firstSession?.month ?: currentMonth
val toRemove = this.filter { list ->
list.any { it is QueryCondition.AnyYear && it.listOfValues.first() == currentYear }
}.filter { list ->
list.any {
it is QueryCondition.AnyMonthOfYear && it.listOfValues.first() > currentMonth
}
}
val toRemoveBefore = this.filter { list ->
list.any { it is QueryCondition.AnyYear && it.listOfValues.first() == firstYear }
}.filter { list ->
list.any {
it is QueryCondition.AnyMonthOfYear && it.listOfValues.first() < firstMonth
}
}
return this.filter{ list ->
var keep = true
toRemove.forEach {
if (list.containsAll(it)) {
keep = false
}
}
firstSession?.let {
toRemoveBefore.forEach {
if (list.containsAll(it)) {
keep = false
}
}
}
keep
}
}
fun <T> getCombinations(lists: List<List<T>>): List<List<T>> {
var combinations: LinkedHashSet<List<T>> = LinkedHashSet()
var newCombinations: LinkedHashSet<List<T>>
var index = 0
// extract each of the integers in the first list
// and add each to ints as a new list
if (lists.isNotEmpty()) {
for (i in lists[0]) {
val newList = ArrayList<T>()
newList.add(i)
combinations.add(newList)
}
index++
}
while (index < lists.size) {
val nextList = lists[index]
newCombinations = LinkedHashSet()
for (first in combinations) {
for (second in nextList) {
val newList = ArrayList<T>()
newList.addAll(first)
newList.add(second)
newCombinations.add(newList)
}
}
combinations = newCombinations
index++
}
return combinations.toList()
}
sealed class Criteria {
abstract class RealmCriteria : Criteria() {
inline fun <reified T: NameManageable> comparison(): List<QueryCondition> {
return compare<QueryCondition.QueryDataCondition<NameManageable>, T>()
.sorted()
}
}
abstract class SimpleCriteria(private val conditions:List<QueryCondition>): Criteria() {
fun comparison(): List<QueryCondition> {
return conditions
}
}
abstract class ListCriteria : Criteria() {
inline fun <reified T:QueryCondition.ListOfValues<S>, reified S:Comparable<S>> comparison(): List<QueryCondition> {
QueryCondition.distinct<Session, T, S>()?.let {
val values = it.mapNotNull { session ->
when (this) {
is Limits -> if (session.limit is S) { session.limit as S } else throw PokerAnalyticsException.QueryValueMapUnexpectedValue
is TournamentTypes -> if (session.tournamentType is S) { session.tournamentType as S } else throw PokerAnalyticsException.QueryValueMapUnexpectedValue
is TableSizes -> if (session.tableSize is S) { session.tableSize as S } else throw PokerAnalyticsException.QueryValueMapUnexpectedValue
is TournamentFees -> if (session.tournamentEntryFee is S) { session.tournamentEntryFee as S } else throw PokerAnalyticsException.QueryValueMapUnexpectedValue
is Blinds -> if (session.blinds is S) { session.blinds as S } else throw PokerAnalyticsException.QueryValueMapUnexpectedValue
else -> null
}
}.distinct()
return compareList<T, S>(values = values).sorted()
}
return listOf<T>()
}
}
object Bankrolls: RealmCriteria()
object Games: RealmCriteria()
object TournamentNames: RealmCriteria()
object Locations: RealmCriteria()
object TournamentFeatures: RealmCriteria()
object Limits: ListCriteria()
object TableSizes: ListCriteria()
object TournamentTypes: ListCriteria()
object MonthsOfYear: SimpleCriteria(List(12) { index -> QueryCondition.AnyMonthOfYear().apply { listOfValues = arrayListOf(index)} })
object DaysOfWeek: SimpleCriteria(List(7) { index -> QueryCondition.AnyDayOfWeek().apply { listOfValues = arrayListOf(index + 1) } })
object SessionTypes: SimpleCriteria(listOf(QueryCondition.IsCash, QueryCondition.IsTournament))
object BankrollTypes: SimpleCriteria(listOf(QueryCondition.IsLive, QueryCondition.IsOnline))
object DayPeriods: SimpleCriteria(listOf(QueryCondition.IsWeekDay, QueryCondition.IsWeekEnd))
object Years: ListCriteria()
object Blinds: ListCriteria()
object TournamentFees: ListCriteria()
object Cash: SimpleCriteria(listOf(QueryCondition.IsCash))
object Tournament: SimpleCriteria(listOf(QueryCondition.IsTournament))
val queryConditions: List<QueryCondition>
get() {
return when (this) {
is Bankrolls -> comparison<Bankroll>()
is Games -> comparison<Game>()
is TournamentFeatures -> comparison<TournamentFeature>()
is TournamentNames -> comparison<TournamentName>()
is Locations -> comparison<Location>()
is SimpleCriteria -> comparison()
is Limits -> comparison<QueryCondition.AnyLimit, Int>()
is TournamentTypes -> comparison<QueryCondition.AnyTournamentType, Int>()
is TableSizes -> comparison<QueryCondition.AnyTableSize, Int>()
is TournamentFees -> comparison<QueryCondition.TournamentFee, Double >()
is Years -> {
val years = arrayListOf<QueryCondition.AnyYear>()
val calendar = Calendar.getInstance()
calendar.time = Date()
val yearNow = calendar.get(Calendar.YEAR)
val realm = Realm.getDefaultInstance()
realm.where<Session>().sort("year", Sort.ASCENDING).findFirst()?.year?.let {
for (index in 0..(yearNow - it)) {
years.add(QueryCondition.AnyYear().apply {
listOfValues = arrayListOf(yearNow - index)
})
}
}
realm.close()
years.sorted()
}
is Blinds -> comparison<QueryCondition.AnyBlind, String >()
else -> throw PokerAnalyticsException.QueryTypeUnhandled
}
}
companion object {
inline fun < reified S : QueryCondition.QueryDataCondition<NameManageable >, reified T : NameManageable > compare(): List<S> {
val objects = arrayListOf<S>()
val realm = Realm.getDefaultInstance()
realm.where<T>().findAll().forEach {
objects.add((QueryCondition.getInstance<T>() as S).apply {
setObject(it)
})
}
realm.close()
return objects
}
inline fun < reified S : QueryCondition.ListOfValues<T>, T:Any > compareList(values:List<T>): List<S> {
val objects = arrayListOf<S>()
values.forEach {
objects.add((S::class.java.newInstance()).apply {
listOfValues = arrayListOf(it)
})
}
return objects
}
}
}