@ -35,6 +35,7 @@ import net.pokeranalytics.android.ui.view.rowrepresentable.SessionRow
import net.pokeranalytics.android.util.NULL_TEXT
import net.pokeranalytics.android.util.NULL_TEXT
import net.pokeranalytics.android.util.UserDefaults
import net.pokeranalytics.android.util.UserDefaults
import net.pokeranalytics.android.util.extensions.*
import net.pokeranalytics.android.util.extensions.*
import java.text.DateFormat
import java.util.*
import java.util.*
import java.util.Currency
import java.util.Currency
import kotlin.collections.ArrayList
import kotlin.collections.ArrayList
@ -42,7 +43,7 @@ import kotlin.collections.ArrayList
typealias BB = Double
typealias BB = Double
open class Session : RealmObject ( ) , Savable , Editable , StaticRowRepresentableDataSource , RowRepresentable , Timed ,
open class Session : RealmObject ( ) , Savable , Editable , StaticRowRepresentableDataSource , RowRepresentable , Timed ,
TimeFilterable , Filterable {
TimeFilterable , Filterable {
enum class Type {
enum class Type {
CASH _GAME ,
CASH _GAME ,
@ -67,28 +68,28 @@ open class Session : RealmObject(), Savable, Editable, StaticRowRepresentableDat
LIVE , ONLINE -> " bankroll.live "
LIVE , ONLINE -> " bankroll.live "
CASH , TOURNAMENT -> " type "
CASH , TOURNAMENT -> " type "
is BANKROLL -> " bankroll.id "
is BANKROLL -> " bankroll.id "
is GAME -> " game.id "
is GAME -> " game.id "
is TOURNAMENT _NAME -> " tournamentName.id "
is TOURNAMENT _NAME -> " tournamentName.id "
is ANY _TOURNAMENT _FEATURES , is ALL _TOURNAMENT _FEATURES -> " tournamentFeatures.id "
is ANY _TOURNAMENT _FEATURES , is ALL _TOURNAMENT _FEATURES -> " tournamentFeatures.id "
is LOCATION -> " location.id "
is LOCATION -> " location.id "
is LIMIT -> " limit "
is LIMIT -> " limit "
is TABLE _SIZE -> " tableSize "
is TABLE _SIZE -> " tableSize "
is TOURNAMENT _TYPE -> " tournamentType "
is TOURNAMENT _TYPE -> " tournamentType "
is BLIND -> " blinds "
is BLIND -> " blinds "
is COMMENT -> " comment "
is COMMENT -> " comment "
is BETWEEN _NUMBER _OF _TABLE , is MORE _NUMBER _OF _TABLE , is LESS _NUMBER _OF _TABLE -> " numberOfTable "
is BETWEEN _NUMBER _OF _TABLE , is MORE _NUMBER _OF _TABLE , is LESS _NUMBER _OF _TABLE -> " numberOfTable "
is MORE _THAN _NET _RESULT , is LESS _THAN _NET _RESULT -> " computableResults.ratedNet "
is MORE _THAN _NET _RESULT , is LESS _THAN _NET _RESULT -> " computableResults.ratedNet "
is MORE _THAN _BUY _IN , is LESS _THAN _BUY _IN -> " result.buyin "
is MORE _THAN _BUY _IN , is LESS _THAN _BUY _IN -> " result.buyin "
is MORE _THAN _CASH _OUT , is LESS _THAN _CASH _OUT -> " result.cashout "
is MORE _THAN _CASH _OUT , is LESS _THAN _CASH _OUT -> " result.cashout "
is MORE _THAN _TIPS , is LESS _THAN _TIPS -> " result.tips "
is MORE _THAN _TIPS , is LESS _THAN _TIPS -> " result.tips "
is MORE _THAN _NUMBER _OF _PLAYER , is LESS _THAN _NUMBER _OF _PLAYER , is BETWEEN _NUMBER _OF _PLAYER -> " tournamentNumberOfPlayers "
is MORE _THAN _NUMBER _OF _PLAYER , is LESS _THAN _NUMBER _OF _PLAYER , is BETWEEN _NUMBER _OF _PLAYER -> " tournamentNumberOfPlayers "
is MORE _THAN _TOURNAMENT _FEE , is LESS _THAN _TOURNAMENT _FEE , is BETWEEN _TOURNAMENT _FEE -> " tournamentEntryFee "
is MORE _THAN _TOURNAMENT _FEE , is LESS _THAN _TOURNAMENT _FEE , is BETWEEN _TOURNAMENT _FEE -> " tournamentEntryFee "
is STARTED _FROM _DATE , is STARTED _TO _DATE -> " startDate "
is STARTED _FROM _DATE , is STARTED _TO _DATE -> " startDate "
is ENDED _FROM _DATE , is ENDED _TO _DATE -> " endDate "
is ENDED _FROM _DATE , is ENDED _TO _DATE -> " endDate "
is DAY _OF _WEEK , is WEEK _END , is WEEK _DAY -> " dayOfWeek "
is DAY _OF _WEEK , is WEEK _END , is WEEK _DAY -> " dayOfWeek "
is MONTH -> " month "
is MONTH -> " month "
is YEAR -> " year "
is YEAR -> " year "
TODAY , YESTERDAY , TODAY _AND _YESTERDAY , THIS _YEAR , THIS _MONTH , THIS _WEEK -> " startDate "
TODAY , YESTERDAY , TODAY _AND _YESTERDAY , THIS _YEAR , THIS _MONTH , THIS _WEEK -> " startDate "
else -> null
else -> null
}
}
}
}
@ -114,7 +115,7 @@ open class Session : RealmObject(), Savable, Editable, StaticRowRepresentableDat
// Timed interface
// Timed interface
override var dayOfWeek : Int ? = null
override var dayOfWeek : Int ? = null
override var month : Int ? = null
override var month : Int ? = null
override var year : Int ? = null
override var year : Int ? = null
override var dayOfMonth : Int ? = null
override var dayOfMonth : Int ? = null
@ -213,21 +214,21 @@ open class Session : RealmObject(), Savable, Editable, StaticRowRepresentableDat
// The small blind value
// The small blind value
var cgSmallBlind : Double ? = null
var cgSmallBlind : Double ? = null
set ( value ) {
set ( value ) {
field = value
field = value
formatBlinds ( )
formatBlinds ( )
}
}
// The big blind value
// The big blind value
var cgBigBlind : Double ? = null
var cgBigBlind : Double ? = null
set ( value ) {
set ( value ) {
field = value
field = value
this . computeStats ( )
this . computeStats ( )
formatBlinds ( )
formatBlinds ( )
}
}
var blinds : String ? = null
var blinds : String ? = null
private set
private set
// Tournament
// Tournament
@ -246,9 +247,9 @@ open class Session : RealmObject(), Savable, Editable, StaticRowRepresentableDat
// The features of the tournament, like Knockout, Shootout, Turbo...
// The features of the tournament, like Knockout, Shootout, Turbo...
var tournamentFeatures : RealmList < TournamentFeature > = RealmList ( )
var tournamentFeatures : RealmList < TournamentFeature > = RealmList ( )
fun bankrollHasBeenUpdated ( ) {
fun bankrollHasBeenUpdated ( ) {
formatBlinds ( )
formatBlinds ( )
}
}
/ * *
/ * *
* Manages impacts on SessionSets
* Manages impacts on SessionSets
@ -303,7 +304,8 @@ open class Session : RealmObject(), Savable, Editable, StaticRowRepresentableDat
* /
* /
val bbNet : BB
val bbNet : BB
get ( ) {
get ( ) {
val bb = this . cgBigBlind ; val result = this . result
val bb = this . cgBigBlind ;
val result = this . result
if ( bb != null && result != null ) {
if ( bb != null && result != null ) {
return result . net / bb
return result . net / bb
} else {
} else {
@ -487,19 +489,19 @@ open class Session : RealmObject(), Savable, Editable, StaticRowRepresentableDat
return NULL _TEXT
return NULL _TEXT
}
}
val hasDefaultCurrency : Boolean
val hasDefaultCurrency : Boolean
get ( ) {
get ( ) {
return bankroll ?. currency ?. code == null
return bankroll ?. currency ?. code == null
}
}
val currency : Currency
val currency : Currency
get ( ) {
get ( ) {
return bankroll ?. currency ?. code ?. let {
return bankroll ?. currency ?. code ?. let {
Currency . getInstance ( it )
Currency . getInstance ( it )
} ?: run {
} ?: run {
UserDefaults . currency
UserDefaults . currency
}
}
}
}
/ * *
/ * *
* Return the game title
* Return the game title
@ -518,18 +520,18 @@ open class Session : RealmObject(), Savable, Editable, StaticRowRepresentableDat
return if ( gameTitle . isNotBlank ( ) ) gameTitle else NULL _TEXT
return if ( gameTitle . isNotBlank ( ) ) gameTitle else NULL _TEXT
}
}
fun getFormattedBlinds ( ) : String {
fun getFormattedBlinds ( ) : String {
return blinds ?: NULL _TEXT
return blinds ?: NULL _TEXT
}
}
private fun formatBlinds ( ) {
private fun formatBlinds ( ) {
blinds = null
blinds = null
if ( cgBigBlind == null ) return
if ( cgBigBlind == null ) return
cgBigBlind ?. let { bb ->
cgBigBlind ?. let { bb ->
val sb = cgSmallBlind ?: bb / 2.0
val sb = cgSmallBlind ?: bb / 2.0
blinds = " ${currency.symbol} ${sb.formatted()} / ${bb.round()} "
blinds = " ${currency.symbol} ${sb.formatted()} / ${bb.round()} "
}
}
}
}
// LifeCycle
// LifeCycle
@ -569,7 +571,7 @@ open class Session : RealmObject(), Savable, Editable, StaticRowRepresentableDat
}
}
@Ignore
@Ignore
private var rowRepresentationForCurrentState : List < RowRepresentable > = mutableListOf ( )
private var rowRepresentationForCurrentState : List < RowRepresentable > = mutableListOf ( )
private fun updatedRowRepresentationForCurrentState ( ) : List < RowRepresentable > {
private fun updatedRowRepresentationForCurrentState ( ) : List < RowRepresentable > {
val rows = ArrayList < RowRepresentable > ( )
val rows = ArrayList < RowRepresentable > ( )
@ -669,7 +671,7 @@ open class Session : RealmObject(), Savable, Editable, StaticRowRepresentableDat
}
}
SessionRow . TOURNAMENT _FEATURE -> {
SessionRow . TOURNAMENT _FEATURE -> {
if ( tournamentFeatures . size > 2 ) {
if ( tournamentFeatures . size > 2 ) {
" $ {tournamentFeatures.subList(0,2).joinToString {
" $ {tournamentFeatures.subList(0, 2).joinToString {
it . name
it . name
} } , .. . "
} } , .. . "
} else if ( tournamentFeatures . size > 0 ) {
} else if ( tournamentFeatures . size > 0 ) {
@ -696,56 +698,98 @@ open class Session : RealmObject(), Savable, Editable, StaticRowRepresentableDat
override fun editDescriptors ( row : RowRepresentable ) : ArrayList < RowRepresentableEditDescriptor > ? {
override fun editDescriptors ( row : RowRepresentable ) : ArrayList < RowRepresentableEditDescriptor > ? {
return when ( row ) {
return when ( row ) {
SessionRow . BANKROLL -> row . editingDescriptors ( mapOf (
SessionRow . BANKROLL -> row . editingDescriptors (
" defaultValue " to this . bankroll ,
mapOf (
" data " to LiveData . BANKROLL . items ( realm ) ) )
" defaultValue " to this . bankroll ,
SessionRow . GAME -> row . editingDescriptors ( mapOf (
" data " to LiveData . BANKROLL . items ( realm )
" limit " to this . limit ,
)
" defaultValue " to this . game ,
)
" data " to LiveData . GAME . items ( realm ) ) )
SessionRow . GAME -> row . editingDescriptors (
SessionRow . LOCATION -> row . editingDescriptors ( mapOf (
mapOf (
" defaultValue " to this . location ,
" limit " to this . limit ,
" data " to LiveData . LOCATION . items ( realm ) ) )
" defaultValue " to this . game ,
SessionRow . TOURNAMENT _FEATURE -> row . editingDescriptors ( mapOf (
" data " to LiveData . GAME . items ( realm )
" defaultValue " to this . tournamentFeatures ,
)
" data " to LiveData . TOURNAMENT _FEATURE . items ( realm ) ) )
)
SessionRow . TOURNAMENT _NAME -> row . editingDescriptors ( mapOf (
SessionRow . LOCATION -> row . editingDescriptors (
" defaultValue " to this . tournamentName ,
mapOf (
" data " to LiveData . TOURNAMENT _NAME . items ( realm ) ) )
" defaultValue " to this . location ,
SessionRow . TOURNAMENT _TYPE -> row . editingDescriptors ( mapOf (
" data " to LiveData . LOCATION . items ( realm )
" defaultValue " to this . tournamentType ) )
)
SessionRow . TABLE _SIZE -> row . editingDescriptors ( mapOf (
)
" defaultValue " to this . tableSize ) )
SessionRow . TOURNAMENT _FEATURE -> row . editingDescriptors (
SessionRow . BLINDS -> row . editingDescriptors ( mapOf (
mapOf (
" sb " to cgSmallBlind ?. round ( ) ,
" defaultValue " to this . tournamentFeatures ,
" bb " to cgBigBlind ?. round ( )
" data " to LiveData . TOURNAMENT _FEATURE . items ( realm )
) )
)
SessionRow . BUY _IN -> row . editingDescriptors ( mapOf (
)
" bb " to cgBigBlind ,
SessionRow . TOURNAMENT _NAME -> row . editingDescriptors (
" fee " to this . tournamentEntryFee ,
mapOf (
" ratedBuyin " to result ?. buyin
" defaultValue " to this . tournamentName ,
) )
" data " to LiveData . TOURNAMENT _NAME . items ( realm )
)
)
SessionRow . TOURNAMENT _TYPE -> row . editingDescriptors (
mapOf (
" defaultValue " to this . tournamentType
)
)
SessionRow . TABLE _SIZE -> row . editingDescriptors (
mapOf (
" defaultValue " to this . tableSize
)
)
SessionRow . BLINDS -> row . editingDescriptors (
mapOf (
" sb " to cgSmallBlind ?. round ( ) ,
" bb " to cgBigBlind ?. round ( )
)
)
SessionRow . BUY _IN -> row . editingDescriptors (
mapOf (
" bb " to cgBigBlind ,
" fee " to this . tournamentEntryFee ,
" ratedBuyin " to result ?. buyin
)
)
SessionRow . BREAK _TIME -> row . editingDescriptors ( mapOf ( ) )
SessionRow . BREAK _TIME -> row . editingDescriptors ( mapOf ( ) )
SessionRow . CASHED _OUT , SessionRow . PRIZE -> row . editingDescriptors ( mapOf (
SessionRow . CASHED _OUT , SessionRow . PRIZE -> row . editingDescriptors (
" defaultValue " to result ?. cashout
mapOf (
) )
" defaultValue " to result ?. cashout
SessionRow . NET _RESULT -> row . editingDescriptors ( mapOf (
)
" defaultValue " to result ?. netResult
)
) )
SessionRow . NET _RESULT -> row . editingDescriptors (
SessionRow . COMMENT -> row . editingDescriptors ( mapOf (
mapOf (
" defaultValue " to this . comment ) )
" defaultValue " to result ?. netResult
SessionRow . INITIAL _BUY _IN -> row . editingDescriptors ( mapOf (
)
" defaultValue " to this . tournamentEntryFee
)
) )
SessionRow . COMMENT -> row . editingDescriptors (
SessionRow . PLAYERS -> row . editingDescriptors ( mapOf (
mapOf (
" defaultValue " to this . tournamentNumberOfPlayers ) )
" defaultValue " to this . comment
SessionRow . POSITION -> row . editingDescriptors ( mapOf (
)
" defaultValue " to this . result ?. tournamentFinalPosition ) )
)
SessionRow . TIPS -> row . editingDescriptors ( mapOf (
SessionRow . INITIAL _BUY _IN -> row . editingDescriptors (
" sb " to cgSmallBlind ?. round ( ) ,
mapOf (
" bb " to cgBigBlind ?. round ( ) ,
" defaultValue " to this . tournamentEntryFee
" tips " to result ?. tips
)
) )
)
SessionRow . PLAYERS -> row . editingDescriptors (
mapOf (
" defaultValue " to this . tournamentNumberOfPlayers
)
)
SessionRow . POSITION -> row . editingDescriptors (
mapOf (
" defaultValue " to this . result ?. tournamentFinalPosition
)
)
SessionRow . TIPS -> row . editingDescriptors (
mapOf (
" sb " to cgSmallBlind ?. round ( ) ,
" bb " to cgBigBlind ?. round ( ) ,
" tips " to result ?. tips
)
)
else -> null
else -> null
}
}
}
}
@ -782,13 +826,15 @@ open class Session : RealmObject(), Savable, Editable, StaticRowRepresentableDat
this . breakDuration = ( value as Double ? ?: 0.0 ) . toLong ( ) * 60 * 1000
this . breakDuration = ( value as Double ? ?: 0.0 ) . toLong ( ) * 60 * 1000
}
}
SessionRow . BUY _IN -> {
SessionRow . BUY _IN -> {
val localResult = if ( this . result != null ) this . result as Result else realm . createObject ( Result :: class . java )
val localResult =
if ( this . result != null ) this . result as Result else realm . createObject ( Result :: class . java )
localResult . buyin = value as Double ?
localResult . buyin = value as Double ?
this . result = localResult
this . result = localResult
this . updateRowRepresentation ( )
this . updateRowRepresentation ( )
}
}
SessionRow . CASHED _OUT , SessionRow . PRIZE -> {
SessionRow . CASHED _OUT , SessionRow . PRIZE -> {
val localResult = if ( this . result != null ) this . result as Result else realm . createObject ( Result :: class . java )
val localResult =
if ( this . result != null ) this . result as Result else realm . createObject ( Result :: class . java )
localResult . cashout = value as Double ?
localResult . cashout = value as Double ?
@ -870,7 +916,12 @@ open class Session : RealmObject(), Savable, Editable, StaticRowRepresentableDat
// Stat Base
// Stat Base
override fun formattedValue ( stat : Stat , context : Context ) : TextFormat {
override val entryTitle : String
get ( ) {
return DateFormat . getDateInstance ( DateFormat . SHORT ) . format ( this . startDate )
}
override fun formattedValue ( stat : Stat , context : Context ) : TextFormat {
this . result ?. let { result ->
this . result ?. let { result ->
@ -886,7 +937,10 @@ open class Session : RealmObject(), Savable, Editable, StaticRowRepresentableDat
}
}
}
}
Stat . HOURLY _RATE _BB -> this . bbHourlyRate
Stat . HOURLY _RATE _BB -> this . bbHourlyRate
Stat . NET _BB _PER _100 _HANDS , Stat . STANDARD _DEVIATION _BB _PER _100 _HANDS -> Stat . netBBPer100Hands ( this . bbNet , this . estimatedHands )
Stat . NET _BB _PER _100 _HANDS , Stat . STANDARD _DEVIATION _BB _PER _100 _HANDS -> Stat . netBBPer100Hands (
this . bbNet ,
this . estimatedHands
)
Stat . AVERAGE _NET _BB -> this . bbNet
Stat . AVERAGE _NET _BB -> this . bbNet
Stat . DURATION , Stat . AVERAGE _DURATION -> this . netDuration . toDouble ( )
Stat . DURATION , Stat . AVERAGE _DURATION -> this . netDuration . toDouble ( )
Stat . HOURLY _RATE , Stat . STANDARD _DEVIATION _HOURLY -> this . hourlyRate
Stat . HOURLY _RATE , Stat . STANDARD _DEVIATION _HOURLY -> this . hourlyRate
@ -915,3 +969,57 @@ open class Session : RealmObject(), Savable, Editable, StaticRowRepresentableDat
}
}
val AbstractList < Session > . hourlyDuration : Double
get ( ) {
val intervals = mutableListOf < TimeInterval > ( )
this . forEach {
val interval = TimeInterval ( it . startDate !! , it . endDate !! , it . breakDuration )
intervals . update ( interval )
}
return intervals . sumByDouble { it . hourlyDuration }
}
class TimeInterval ( var start : Date , var end : Date , var breakDuration : Long ) {
val hourlyDuration : Double
get ( ) {
val netDuration = end . time - start . time - breakDuration
return ( netDuration / 3600000 ) . toDouble ( )
}
}
fun MutableList < TimeInterval > . update ( timeInterval : TimeInterval ) : MutableList < TimeInterval > {
val overlapped = this . filter {
( it . start . before ( timeInterval . start ) && it . end . after ( timeInterval . start ) ) ||
( it . start . before ( timeInterval . end ) && it . end . after ( timeInterval . end ) ) ||
( it . start . after ( timeInterval . start ) && it . end . before ( timeInterval . end ) )
}
if ( overlapped . size == 0 ) { // add
this . add ( timeInterval )
} else { // update
var start = timeInterval . start
var end = timeInterval . end
var breakDuration = timeInterval . breakDuration
overlapped . forEach {
if ( it . start . before ( start ) ) {
start = it . start
}
if ( it . end . after ( end ) ) {
end = it . end
}
breakDuration = kotlin . math . max ( it . breakDuration , breakDuration )
}
this . removeAll ( overlapped )
this . add ( TimeInterval ( start , end , breakDuration ) )
}
return this
}