/* Ċ Ġ* ĠCopyright Ġ 2 0 2 1 ĠThe ĠAndroid ĠOpen ĠSource ĠProject Ċ Ġ* Ċ Ġ* Ġ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 Ċ Ġ* Ċ Ġ* ĠĠĠĠ Ġhttps :// 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 Ġcom . example . android dev challenge Ċ Ċ import Ġandroid . os . Count Down Timer Ċ import Ġandroidx . compose . runtime . getValue Ċ import Ġandroidx . compose . runtime . mutable State Of Ċ import Ġandroidx . compose . runtime . setValue Ċ import Ġandroidx . lifecycle . ViewModel Ċ import Ġjava . util . concurrent . TimeUnit Ċ Ċ class ĠMain ViewModel Ġ: ĠViewModel () Ġ{ ĊĠĠĠ Ġcompanion Ġobject Ġ{ ĊĠĠĠĠĠĠĠ Ġconst Ġval ĠTIME _ FORMAT : ĠString Ġ= Ġ"% 0 2 d " ĊĠĠĠĠĠĠĠ Ġval ĠCOUNT _ DOWN _ INTERVAL : ĠLong Ġ= ĠTimeUnit . SECONDS . to Millis ( 1 ) ĊĠĠĠĠĠĠĠ Ġval ĠEND ING _ ANIM ATION _ DURATION Ġ= ĠTimeUnit . SECONDS . to Millis ( 2 ). toInt () ĊĠĠĠĠĠĠĠ Ġval ĠTIME _ PLACE HOLDER : ĠString Ġ= ĠString . format ( TIME _ FORMAT , Ġ 0 ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġlateinit Ġvar Ġcount Down Timer : ĠCount Down Timer ĊĊĠĠĠ Ġvar Ġhours : ĠString Ġby Ġmutable State Of ( TIME _ PLACE HOLDER ) ĊĠĠĠĠĠĠĠ Ġprivate Ġset ĊĠĠĠ Ġvar Ġminutes : ĠString Ġby Ġmutable State Of ( TIME _ PLACE HOLDER ) ĊĠĠĠĠĠĠĠ Ġprivate Ġset ĊĠĠĠ Ġvar Ġseconds : ĠString Ġby Ġmutable State Of ( TIME _ PLACE HOLDER ) ĊĠĠĠĠĠĠĠ Ġprivate Ġset ĊĊĠĠĠ Ġvar Ġis Edit State Enabled : ĠBoolean Ġby Ġmutable State Of ( true ) ĊĠĠĠĠĠĠĠ Ġprivate Ġset ĊĊĠĠĠ Ġvar Ġis Play Button Visible : ĠBoolean Ġby Ġmutable State Of ( true ) ĊĠĠĠĠĠĠĠ Ġprivate Ġset ĊĠĠĠ Ġvar Ġis Pause Button Visible : ĠBoolean Ġby Ġmutable State Of ( false ) ĊĠĠĠĠĠĠĠ Ġprivate Ġset ĊĠĠĠ Ġvar Ġis Stop Button Visible : ĠBoolean Ġby Ġmutable State Of ( false ) ĊĠĠĠĠĠĠĠ Ġprivate Ġset ĊĊĠĠĠ Ġvar Ġis Ending : ĠBoolean Ġby Ġmutable State Of ( false ) ĊĠĠĠĠĠĠĠ Ġprivate Ġset ĊĊĠĠĠ Ġfun Ġon Play Button Click () Ġ{ ĊĠĠĠĠĠĠĠ Ġupdate ViewState ( Count Down State . PLAY ) ĊĊĠĠĠĠĠĠĠ Ġval Ġmillis Ġ= Ġconvert TimeTo Millis ( ĊĠĠĠĠĠĠĠĠĠĠĠ Ġhours . toInt OrNull () Ġ?: Ġ 0 , ĊĠĠĠĠĠĠĠĠĠĠĠ Ġminutes . toInt OrNull () Ġ?: Ġ 0 , ĊĠĠĠĠĠĠĠĠĠĠĠ Ġseconds . toInt OrNull () Ġ?: Ġ 0 ĊĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠ Ġstart Count Down ( millis ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġfun Ġon Pause Button Click () Ġ{ ĊĠĠĠĠĠĠĠ Ġupdate ViewState ( Count Down State . PAUSE ) ĊĠĠĠĠĠĠĠ Ġcount Down Timer . cancel () ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġfun Ġon Stop Button Click () Ġ{ ĊĠĠĠĠĠĠĠ Ġupdate ViewState ( Count Down State . STOP ) ĊĠĠĠĠĠĠĠ Ġcount Down Timer . cancel () ĊĊĠĠĠĠĠĠĠ Ġhours Ġ= ĠTIME _ PLACE HOLDER ĊĠĠĠĠĠĠĠ Ġminutes Ġ= ĠTIME _ PLACE HOLDER ĊĠĠĠĠĠĠĠ Ġseconds Ġ= ĠTIME _ PLACE HOLDER ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġfun Ġon Hours Value Change ( value : ĠString ) Ġ{ ĊĠĠĠĠĠĠĠ Ġhours Ġ= Ġget Valid Input ( value , Ġ 9 9 ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġfun Ġon Minutes Value Change ( value : ĠString ) Ġ{ ĊĠĠĠĠĠĠĠ Ġminutes Ġ= Ġget Valid Input ( value , Ġ 5 9 ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġfun Ġon Seconds Value Change ( value : ĠString ) Ġ{ ĊĠĠĠĠĠĠĠ Ġseconds Ġ= Ġget Valid Input ( value , Ġ 5 9 ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġfun Ġon Hours Focused () Ġ{ ĊĠĠĠĠĠĠĠ Ġhours Ġ= Ġ"" ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġfun Ġon Minutes Focused () Ġ{ ĊĠĠĠĠĠĠĠ Ġminutes Ġ= Ġ"" ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġfun Ġon Seconds Focused () Ġ{ ĊĠĠĠĠĠĠĠ Ġseconds Ġ= Ġ"" ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġfun Ġon Edit Done () Ġ{ ĊĠĠĠĠĠĠĠ Ġhours Ġ= Ġif Ġ( hours . isNotEmpty ()) Ġformat Time ( hours . to Long ()) Ġelse ĠTIME _ PLACE HOLDER ĊĠĠĠĠĠĠĠ Ġminutes Ġ= Ġif Ġ( minutes . isNotEmpty ()) Ġformat Time ( minutes . to Long ()) Ġelse ĠTIME _ PLACE HOLDER ĊĠĠĠĠĠĠĠ Ġseconds Ġ= Ġif Ġ( seconds . isNotEmpty ()) Ġformat Time ( seconds . to Long ()) Ġelse ĠTIME _ PLACE HOLDER ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġstart Count Down ( millis : ĠLong ) Ġ{ ĊĠĠĠĠĠĠĠ Ġcount Down Timer Ġ= Ġobject Ġ: ĠCount Down Timer ( millis , ĠCOUNT _ DOWN _ INTERVAL ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġoverride Ġfun Ġon Tick ( millis Until Finished : ĠLong ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġhours Ġ= Ġformat Time ( getHours ( millis Until Finished )) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġminutes Ġ= Ġformat Time ( get Minutes ( millis Until Finished )) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġseconds Ġ= Ġformat Time ( get Seconds ( millis Until Finished )) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġis Ending Ġ= Ġmillis Until Finished Ġ<= ĠEND ING _ ANIM ATION _ DURATION ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġoverride Ġfun Ġon Finish () Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġupdate ViewState ( Count Down State . STOP ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ}. start () ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġupdate ViewState ( state : ĠCount Down State ) Ġ{ ĊĠĠĠĠĠĠĠ Ġwhen Ġ( state ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠCount Down State . PLAY Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġis Play Button Visible Ġ= Ġfalse ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġis Pause Button Visible Ġ= Ġtrue ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġis Stop Button Visible Ġ= Ġtrue ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġis Edit State Enabled Ġ= Ġfalse ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ ĠCount Down State . PAUSE Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġis Play Button Visible Ġ= Ġtrue ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġis Pause Button Visible Ġ= Ġfalse ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġis Stop Button Visible Ġ= Ġtrue ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġis Edit State Enabled Ġ= Ġtrue ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ ĠCount Down State . STOP Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġis Play Button Visible Ġ= Ġtrue ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġis Pause Button Visible Ġ= Ġfalse ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġis Stop Button Visible Ġ= Ġfalse ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġis Edit State Enabled Ġ= Ġtrue ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġget Valid Input ( value : ĠString , Ġmax : ĠInt ): ĠString Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn Ġvalue ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. replace ("\\ D ". to Regex (), Ġ"") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. take Last ( 2 ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. toInt OrNull ()?. run Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġco erce In ( 0 .. max ). toString () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġ?: Ġ"" ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġget Hours ( millis : ĠLong ): ĠLong Ġ= ĊĠĠĠĠĠĠĠ ĠTimeUnit . MILLISECONDS . to Hours ( millis ) ĊĊĠĠĠ Ġprivate Ġfun Ġget Minutes ( millis : ĠLong ): ĠLong Ġ= ĊĠĠĠĠĠĠĠ ĠTimeUnit . MILLISECONDS . to Minutes ( millis ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. minus ( TimeUnit . HOUR S . to Minutes ( TimeUnit . MILLISECONDS . to Hours ( millis ))) ĊĊĠĠĠ Ġprivate Ġfun Ġget Seconds ( millis : ĠLong ) Ġ= ĊĠĠĠĠĠĠĠ ĠTimeUnit . MILLISECONDS . to Seconds ( millis ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. minus ( TimeUnit . MIN UTES . to Seconds ( TimeUnit . MILLISECONDS . to Minutes ( millis ))) ĊĊĠĠĠ Ġprivate Ġfun Ġformat Time ( time : ĠLong ) Ġ= ĠString . format ( TIME _ FORMAT , Ġtime ) ĊĊĠĠĠ Ġprivate Ġfun Ġconvert TimeTo Millis ( hours : ĠInt , Ġminutes : ĠInt , Ġseconds : ĠInt ): ĠLong Ġ= ĊĠĠĠĠĠĠĠ ĠTimeUnit . HOUR S . to Millis ( hours . to Long ()) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. plus ( TimeUnit . MIN UTES . to Millis ( minutes . to Long ())) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. plus ( TimeUnit . SECONDS . to Millis ( seconds . to Long ())) Ċ } Ċ