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

172 lines
6.8 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.Identifiable
import net.pokeranalytics.android.model.realm.*
import java.util.*
sealed class Criteria {
abstract class RealmCriteria : Criteria() {
inline fun <reified T:Identifiable> comparison(): List<QueryCondition> {
return compare < QueryCondition.QueryDataCondition<Identifiable>, T >()
}
}
abstract class SimpleCriteria(private val conditions:List<QueryCondition>): Criteria() {
fun comparison(): List<QueryCondition> {
return conditions
}
}
abstract class StaticCriteria : Criteria() {
inline fun <reified T:QueryCondition.StaticDataQueryCondition> comparison(): List<QueryCondition> {
QueryCondition.distinct<Session, T>()?.let {
val values = it.mapNotNull { session ->
when (this) {
is Limits -> session.limit
is TournamentTypes -> session.tournamentType
is TableSizes -> session.tableSize
//is TournamentFees -> session.tournamentEntryFee
else -> null
}
}
return compare<T>(values)
}
return listOf<T>()
}
}
object Bankrolls: RealmCriteria()
object Games: RealmCriteria()
object TournamentNames: RealmCriteria()
object Locations: RealmCriteria()
object TournamentFeatures: RealmCriteria()
object Limits: StaticCriteria()
object TableSizes: StaticCriteria()
object TournamentTypes: StaticCriteria()
object monthOfYear: SimpleCriteria(List(12) { index -> QueryCondition.MONTH().apply { intValue = index } })
object dayOfWeek: SimpleCriteria(List(7) { index -> QueryCondition.DAY_OF_WEEK().apply { intValue = index } })
object SessionType: SimpleCriteria(listOf(QueryCondition.CASH, QueryCondition.TOURNAMENT))
object BankrollType: SimpleCriteria(listOf(QueryCondition.LIVE, QueryCondition.ONLINE))
object dayPeriod: SimpleCriteria(listOf(QueryCondition.WEEK_DAY, QueryCondition.WEEK_END))
object Year: Criteria()
object Blinds: Criteria()
//object TournamentFees: StaticCriteria()
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.LIMIT>()
is TournamentTypes -> comparison<QueryCondition.TOURNAMENT_TYPE>()
is TableSizes -> comparison<QueryCondition.TABLE_SIZE>()
is Year -> {
val years = arrayListOf<QueryCondition.YEAR>()
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.YEAR().apply {
intValue = yearNow - index
})
}
}
realm.close()
years
}
is Blinds -> {
val blinds = arrayListOf<QueryCondition.BLIND>()
val realm = Realm.getDefaultInstance()
realm.where<Session>().distinct("blinds", "bankroll.currency.code").findAll().sort("cgSmallBlind", Sort.ASCENDING).map {
it.blinds?.let { stake ->
blinds.add(QueryCondition.BLIND().apply {
blind = stake
hasDefaultCurrency = it.hasDefaultCurrency
})
}
}
realm.close()
blinds
}
else -> throw PokerAnalyticsException.QueryTypeUnhandled
}
}
companion object {
inline fun < reified S : QueryCondition.QueryDataCondition<Identifiable>, reified T : Identifiable > 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.StaticDataQueryCondition > compare(values:List<Int>): List<S> {
val objects = arrayListOf<S>()
values.forEach {
objects.add((S::class.java.newInstance()).apply {
intValues.add(it)
})
}
return objects
}
}
fun List<Criteria>.combined(): List<List<QueryCondition>> {
val comparatorList = ArrayList<List<QueryCondition>>()
this.forEach {
comparatorList.add(it.queryConditions)
}
return getCombinations(comparatorList)
}
private fun <T> getCombinations(lists: List<List<T>>): List<List<T>> {
var combinations: MutableSet<List<T>> = LinkedHashSet()
var newCombinations: MutableSet<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()
}
}