/* Ċ Ġ* ĠCopyright Ġ( C ) Ġ 2 0 2 1 ĠX iz hi ĠZ hu Ċ Ġ* Ċ Ġ* ĠLicensed Ġunder Ġthe ĠApache ĠLicense , ĠVersion Ġ 2 . 0 Ġ( the Ġ" License "); Ċ Ġ* Ġyou Ġmay Ġnot Ġuse Ġthis Ġfile Ġexcept Ġin Ġcompliance Ġwith Ġthe ĠLicense . Ċ Ġ* ĠYou Ġmay Ġobtain Ġa Ġcopy Ġof Ġthe ĠLicense Ġat Ċ Ġ* Ċ Ġ* ĠĠĠĠĠ Ġhttp :// www . apache . org / licenses / LICENSE - 2 . 0 Ċ Ġ* Ċ Ġ* ĠUnless Ġrequired Ġby Ġapplicable Ġlaw Ġor Ġagreed Ġto Ġin Ġwriting , Ġsoftware Ċ Ġ* Ġdistributed Ġunder Ġthe ĠLicense Ġis Ġdistributed Ġon Ġan Ġ" AS ĠIS " ĠBASIS , Ċ Ġ* ĠWITHOUT ĠWARRANTIES ĠOR ĠCONDITIONS ĠOF ĠANY ĠKIND , Ġeither Ġexpress Ġor Ġimplied . Ċ Ġ* ĠSee Ġthe ĠLicense Ġfor Ġthe Ġspecific Ġlanguage Ġgoverning Ġpermissions Ġand Ċ Ġ* Ġlimitations Ġunder Ġthe ĠLicense . Ċ Ġ*/ Ċ Ċ package Ġme . x iz zh u . android . j osh ua . annotated Ċ Ċ import Ġandroid . app . Application Ċ import Ġandroidx . annotation . String Res Ċ import Ġandroidx . annotation . Visible ForTesting Ċ import Ġandroidx . lifecycle . viewModel Scope Ċ import Ġkotlinx . coroutines . flow . Flow Ċ import Ġkotlinx . coroutines . flow . Mutable State Flow Ċ import Ġkotlinx . coroutines . flow . combine Ċ import Ġkotlinx . coroutines . flow . filter Ċ import Ġkotlinx . coroutines . flow . filter NotNull Ċ import Ġkotlinx . coroutines . flow . first Ċ import Ġkotlinx . coroutines . flow . launch In Ċ import Ġkotlinx . coroutines . launch Ċ import Ġme . x iz zh u . android . j osh ua . R Ċ import Ġme . x iz zh u . android . j osh ua . core . Bible Reading Manager Ċ import Ġme . x iz zh u . android . j osh ua . core . Constants Ċ import Ġme . x iz zh u . android . j osh ua . core . Settings Ċ import Ġme . x iz zh u . android . j osh ua . core . Settings Manager Ċ import Ġme . x iz zh u . android . j osh ua . core . Ver se Ċ import Ġme . x iz zh u . android . j osh ua . core . Ver se Annotation Ċ import Ġme . x iz zh u . android . j osh ua . core . Ver se Annotation Manager Ċ import Ġme . x iz zh u . android . j osh ua . core . Ver se Index Ċ import Ġme . x iz zh u . android . j osh ua . infra . Base ViewModel Ċ import Ġme . x iz zh u . android . j osh ua . infra . on Failure Ċ import Ġme . x iz zh u . android . j osh ua . infra . view Data Ċ import Ġme . x iz zh u . android . j osh ua . ui . recyclerview . Base Item Ċ import Ġme . x iz zh u . android . j osh ua . ui . recyclerview . Text Item Ċ import Ġme . x iz zh u . android . j osh ua . ui . recyclerview . Title Item Ċ import Ġme . x iz zh u . android . j osh ua . ui . recyclerview . to Ver se Preview Items Ċ import Ġme . x iz zh u . android . j osh ua . utils . currentTimeMillis Ċ import Ġme . x iz zh u . android . j osh ua . utils . first NotEmpty Ċ import Ġme . x iz zh u . android . logger . Log Ċ import Ġjava . util .* Ċ import Ġkotlin . collections . ArrayList Ċ Ċ class ĠAnnot ated Ver ses ViewData ( val Ġitems : ĠList < Base Item >) Ċ Ċ class ĠPreview ViewData ( val Ġsettings : ĠSettings , Ġval Ġtitle : ĠString , Ġval Ġitems : ĠList < Base Item >, Ġval Ġcurrent Position : ĠInt ) Ċ Ċ abstract Ġclass ĠAnnot ated Ver ses ViewModel < V Ġ: ĠVer se Annotation >( ĊĠĠĠĠĠĠĠ Ġprivate Ġval Ġb ible Reading Manager : ĠBible Reading Manager , ĊĠĠĠĠĠĠĠ Ġprivate Ġval Ġver se Annotation Manager : ĠVer se Annotation Manager < V >, ĊĠĠĠĠĠĠĠ Ġ@ String Res Ġprivate Ġval Ġno Item Text : ĠInt , ĊĠĠĠĠĠĠĠ Ġsettings Manager : ĠSettings Manager , ĊĠĠĠĠĠĠĠ Ġapplication : ĠApplication Ċ ) Ġ: ĠBase ViewModel ( settings Manager , Ġapplication ) Ġ{ ĊĠĠĠ Ġprivate Ġval Ġannotated Ver ses : ĠMutable State Flow < ViewData < Annotated Ver ses ViewData > ?> Ġ= ĠMutable State Flow ( null ) ĊĊĠĠĠ Ġinit Ġ{ ĊĠĠĠĠĠĠĠ Ġcombine ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġb ible Reading Manager . current Translation (). filter Ġ{ Ġit . isNotEmpty () Ġ}, ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġver se Annotation Manager . sort Order () ĊĠĠĠĠĠĠĠ Ġ) Ġ{ Ġcurrent Translation , Ġsort Order Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠ Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġannotated Ver ses . value Ġ= ĠView Data . Loading () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġannotated Ver ses . value Ġ= ĠView Data . Success ( load Annotated Ver ses ( current Translation , Ġsort Order )) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġcatch Ġ( e : ĠException ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠLog . e ( tag , Ġ" Error Ġoccurred Ġwhile Ġloading Ġannotated Ġver ses ", Ġe ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġannotated Ver ses . value Ġ= ĠView Data . Failure ( e ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġload Annotated Ver ses ( current Translation , Ġsort Order ) ĊĠĠĠĠĠĠĠ Ġ}. launch In ( viewModel Scope ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġfun Ġsort Order (): ĠFlow < Int > Ġ= Ġver se Annotation Manager . sort Order () ĊĊĠĠĠ Ġfun Ġsave SortOrder (@ Constants . SortOrder Ġsort Order : ĠInt ): ĠFlow < ViewData < Unit >> Ġ= Ġview Data Ġ{ ĊĠĠĠĠĠĠĠ Ġver se Annotation Manager . save SortOrder ( sort Order ) ĊĠĠĠ Ġ}. on Failure Ġ{ ĠLog . e ( tag , Ġ" Failed Ġto Ġsave Ġsort Ġorder ", Ġit ) Ġ} ĊĊĠĠĠ Ġfun Ġannotated Ver ses (): ĠFlow < ViewData < Annotated Ver ses ViewData >> Ġ= Ġannotated Ver ses . filter NotNull () ĊĊĠĠĠ Ġfun Ġload Annotated Ver ses () Ġ{ ĊĠĠĠĠĠĠĠ ĠviewModel Scope . launch Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġannotated Ver ses . value Ġ= ĠView Data . Loading () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġannotated Ver ses . value Ġ= ĠView Data . Success ( load Annotated Ver ses ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcurrent Translation Ġ= Ġb ible Reading Manager . current Translation (). first NotEmpty (), ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġsort Order Ġ= Ġver se Annotation Manager . sort Order (). first () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ)) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġcatch Ġ( e : ĠException ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠLog . e ( tag , Ġ" Error Ġoccurred Ġwhile Ġloading Ġannotated Ġver ses ", Ġe ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġannotated Ver ses . value Ġ= ĠView Data . Failure ( e ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġsuspend Ġfun Ġload Annotated Ver ses ( current Translation : ĠString , Ġ@ Constants . SortOrder Ġsort Order : ĠInt ): ĠAnnot ated Ver ses ViewData Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġannotations Ġ= Ġver se Annotation Manager . read ( sort Order ) ĊĠĠĠĠĠĠĠ Ġval Ġver ses Ġ= Ġb ible Reading Manager . read Ver ses ( current Translation , Ġannotations . map Ġ{ Ġit . verse Index Ġ}) ĊĠĠĠĠĠĠĠ Ġreturn ĠAnnot ated Ver ses ViewData ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġitems Ġ= Ġbuild Annotated Ver ses Items ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġsort Order Ġ= Ġsort Order , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġver ses Ġ= Ġannotations . map NotNull Ġ{ Ġannotation Ġ-> Ġver ses [ annotation . verse Index ]?. let Ġ{ ĠPair ( annotation , Ġit ) Ġ} Ġ}, ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġbook Names Ġ= Ġb ible Reading Manager . read Book Names ( current Translation ), ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġbook Short Names Ġ= Ġb ible Reading Manager . read Book Short Names ( current Translation ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠ Ġ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġbuild Annotated Ver ses Items ( ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ@ Constants . SortOrder Ġsort Order : ĠInt , Ġver ses : ĠList < Pair < V , ĠVer se >>, Ġbook Names : ĠList < String >, Ġbook Short Names : ĠList < String > ĊĠĠĠ Ġ): ĠList < Base Item > Ġ= Ġif Ġ( ver ses . isEmpty ()) Ġ{ ĊĠĠĠĠĠĠĠ ĠlistOf ( Text Item ( application . getString ( no Item Text ))) ĊĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠ Ġwhen Ġ( sort Order ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠConstants . SORT _ BY _ DATE Ġ-> Ġbuild Items By Date ( ver ses , Ġbook Names , Ġbook Short Names ) ĊĠĠĠĠĠĠĠĠĠĠĠ ĠConstants . SORT _ BY _ BOOK Ġ-> Ġbuild Items By Book ( ver ses , Ġbook Names , Ġbook Short Names ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġelse Ġ-> Ġthrow ĠIllegalArgumentException (" Unsupported Ġsort Ġorder Ġ- Ġ$ sort Order ") ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġbuild Items By Date ( ver ses : ĠList < Pair < V , ĠVer se >>, Ġbook Names : ĠList < String >, Ġbook Short Names : ĠList < String >): ĠList < Base Item > Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġcalendar Ġ= ĠCalendar . getInstance () ĊĠĠĠĠĠĠĠ Ġvar Ġprevious Year Ġ= Ġ- 1 ĊĠĠĠĠĠĠĠ Ġvar Ġprevious Day OfYear Ġ= Ġ- 1 ĊĊĠĠĠĠĠĠĠ Ġval Ġitems : ĠArrayList < Base Item > Ġ= ĠArrayList () ĊĠĠĠĠĠĠĠ Ġver ses . forEach Ġ{ Ġ( verse Annotation , Ġver se ) Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠ Ġcalendar . time In Millis Ġ= Ġver se Annotation . timestamp ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġcurrent Year Ġ= Ġcalendar . get ( Calendar . YEAR ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġcurrent Day OfYear Ġ= Ġcalendar . get ( Calendar . DAY _ OF _ YEAR ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( current Year Ġ!= Ġprevious Year Ġ|| Ġcurrent Day OfYear Ġ!= Ġprevious Day OfYear ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġitems . add ( Title Item ( format Date ( calendar , Ġver se Annotation . timestamp ), Ġfalse )) ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġprevious Year Ġ= Ġcurrent Year ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġprevious Day OfYear Ġ= Ġcurrent Day OfYear ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġitems . add ( build Base Item ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġver se Annotation , Ġbook Names [ verse Annotation . verse Index . book Index ], ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġbook Short Names [ verse Annotation . verse Index . book Index ], Ġver se . text . text , ĠConstants . SORT _ BY _ DATE ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ)) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġreturn Ġitems ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ@ Visible ForTesting ( otherwise Ġ= ĠVis ible ForTesting . PRIVATE ) ĊĠĠĠ Ġinternal Ġfun Ġformat Date ( calendar : ĠCalendar , Ġtimestamp : ĠLong ): ĠString Ġ{ ĊĠĠĠĠĠĠĠ Ġcalendar . time In Millis Ġ= ĠcurrentTime Millis () ĊĠĠĠĠĠĠĠ Ġval Ġcurrent Year Ġ= Ġcalendar . get ( Calendar . YEAR ) ĊĊĠĠĠĠĠĠĠ Ġcalendar . time In Millis Ġ= Ġtimestamp ĊĠĠĠĠĠĠĠ Ġval Ġyear Ġ= Ġcalendar . get ( Calendar . YEAR ) ĊĠĠĠĠĠĠĠ Ġreturn Ġif Ġ( year Ġ== Ġcurrent Year ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġapplication . getString ( R . string . text _ date _ without _ year , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġapplication . resources . getString Array ( R . array . text _ months )[ calendar . get ( Calendar . MONTH )], ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcalendar . get ( Calendar . DATE )) ĊĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġapplication . getString ( R . string . text _ date , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġapplication . resources . getString Array ( R . array . text _ months )[ calendar . get ( Calendar . MONTH )], ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcalendar . get ( Calendar . DATE ), Ġyear ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprotected Ġabstract Ġfun Ġbuild Base Item ( ĊĠĠĠĠĠĠĠĠĠĠĠ Ġannotated Ver se : ĠV , Ġbook Name : ĠString , Ġbook ShortName : ĠString , Ġver se Text : ĠString , Ġ@ Constants . SortOrder Ġsort Order : ĠInt ĊĠĠĠ Ġ): ĠBase Item ĊĊĠĠĠ Ġprivate Ġfun Ġbuild Items By Book ( ver ses : ĠList < Pair < V , ĠVer se >>, Ġbook Names : ĠList < String >, Ġbook Short Names : ĠList < String >): ĠList < Base Item > Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġitems : ĠArrayList < Base Item > Ġ= ĠArrayList () ĊĠĠĠĠĠĠĠ Ġvar Ġcurrent Book Index Ġ= Ġ- 1 ĊĠĠĠĠĠĠĠ Ġver ses . forEach Ġ{ Ġ( verse Annotation , Ġver se ) Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġbook Name Ġ= Ġbook Names [ verse Annotation . verse Index . book Index ] ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( verse Annotation . verse Index . book Index Ġ!= Ġcurrent Book Index ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġitems . add ( Title Item ( book Name , Ġfalse )) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcurrent Book Index Ġ= Ġver se Annotation . verse Index . book Index ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġitems . add ( build Base Item ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġver se Annotation , Ġbook Names [ verse Annotation . verse Index . book Index ], ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġbook Short Names [ verse Annotation . verse Index . book Index ], Ġver se . text . text , ĠConstants . SORT _ BY _ BOOK ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ)) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġreturn Ġitems ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġfun Ġsave Current Ver se Index ( verse To Open : ĠVer se Index ): ĠFlow < ViewData < Unit >> Ġ= Ġview Data Ġ{ ĊĠĠĠĠĠĠĠ Ġb ible Reading Manager . save Current Ver se Index ( verse To Open ) ĊĠĠĠ Ġ}. on Failure Ġ{ ĠLog . e ( tag , Ġ" Failed Ġto Ġsave Ġcurrent Ġver se ", Ġit ) Ġ} ĊĊĠĠĠ Ġfun Ġload Ver ses For Preview ( verse Index : ĠVer se Index ): ĠFlow < ViewData < Preview ViewData >> Ġ= Ġview Data Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġcurrent Translation Ġ= Ġb ible Reading Manager . current Translation (). first NotEmpty () ĊĠĠĠĠĠĠĠ Ġval Ġitems Ġ= Ġb ible Reading Manager . read Ver ses ( current Translation , Ġver se Index . book Index , Ġver se Index . chapter Index ). to Ver se Preview Items () ĊĠĠĠĠĠĠĠ ĠPreview ViewData ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġsettings Ġ= Ġsettings (). first (), ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġtitle Ġ= Ġ"${ bible Reading Manager . read Book Short Names ( current Translation )[ verse Index . book Index ]}, Ġ${ verse Index . chapter Index Ġ+ Ġ 1 }", ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġitems Ġ= Ġitems , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcurrent Position Ġ= Ġver se Index . verse Index ĊĠĠĠĠĠĠĠ Ġ) ĊĠĠĠ Ġ}. on Failure Ġ{ ĠLog . e ( tag , Ġ" Failed Ġto Ġload Ġver ses Ġfor Ġpreview ", Ġit ) Ġ} Ċ } Ċ