package Ġaz . s if to sh ka . habit ube . presentation . screens . movie Ċ Ċ import Ġandroidx . compose . runtime . State Ċ import Ġandroidx . compose . runtime . mutable State Of Ċ import Ġandroidx . lifecycle . Saved State Handle Ċ import Ġandroidx . lifecycle . ViewModel Ċ import Ġandroidx . lifecycle . viewModel Scope Ċ import Ġaz . s if to sh ka . habit ube . domain . model . Media Lite Ċ import Ġaz . s if to sh ka . habit ube . domain . model . Movie Ċ import Ġaz . s if to sh ka . habit ube . domain . use cases . local . Pl anned Movies UseCase Ċ import Ġaz . s if to sh ka . habit ube . domain . use cases . local . W atched Movies UseCase Ċ import Ġaz . s if to sh ka . habit ube . domain . use cases . remote .* Ċ import Ġaz . s if to sh ka . habit ube . domain . util . Constants Ċ import Ġaz . s if to sh ka . habit ube . domain . util . MediaType Ċ import Ġaz . s if to sh ka . habit ube . domain . util . Resource Ċ import Ġaz . s if to sh ka . habit ube . presentation . util . Navigation Constants . PARAM _ MOV IE _ ID Ċ import Ġdagger . h ilt . android . lifecycle . H ilt ViewModel Ċ import Ġkotlinx . coroutines . flow . launch In Ċ import Ġkotlinx . coroutines . flow . on Each Ċ import Ġkotlinx . coroutines . launch Ċ import Ġjavax . inject . Inject Ċ Ċ /** Ċ Ġ* Ġ[ ViewModel ] Ġof Ġthe ĠMovie ĠScreen . Ċ Ġ*/ Ċ @ H ilt ViewModel Ċ class ĠMovie ViewModel Ġ@ Inject Ġconstructor ( ĊĠĠĠ Ġprivate Ġval Ġget Movie UseCase : ĠGet Movie UseCase , ĊĠĠĠ Ġprivate Ġval Ġget Videos UseCase : ĠGet Videos UseCase , ĊĠĠĠ Ġprivate Ġval Ġget Credits UseCase : ĠGet Credits UseCase , ĊĠĠĠ Ġprivate Ġval Ġget Similar UseCase : ĠGet Similar UseCase , ĊĠĠĠ Ġprivate Ġval Ġget Movie Ratings UseCase : ĠGet O mdb Data UseCase , ĊĠĠĠ Ġprivate Ġval Ġplanned Movies UseCase : ĠPl anned Movies UseCase , ĊĠĠĠ Ġprivate Ġval Ġw atched Movies UseCase : ĠW atched Movies UseCase , ĊĠĠĠ Ġsaved State Handle : ĠSaved State Handle Ċ ) Ġ: ĠViewModel () Ġ{ ĊĊĠĠĠ Ġprivate Ġval Ġ_ movie State Ġ= Ġmutable State Of ( Movie State ()) ĊĠĠĠ Ġval Ġmovie State : ĠState < Movie State > Ġ= Ġ_ movie State ĊĊĠĠĠ Ġprivate Ġval Ġ_ videos State Ġ= Ġmutable State Of ( Movie Videos State ()) ĊĠĠĠ Ġval Ġvideos State : ĠState < Movie Videos State > Ġ= Ġ_ videos State ĊĊĠĠĠ Ġprivate Ġval Ġ_ om db State Ġ= Ġmutable State Of ( O mdb Data State ()) ĊĠĠĠ Ġval Ġo mdb State : ĠState < O mdb Data State > Ġ= Ġ_ om db State ĊĊĠĠĠ Ġprivate Ġval Ġ_ credits State Ġ= Ġmutable State Of ( Movie Credits State ()) ĊĠĠĠ Ġval Ġcredits State : ĠState < Movie Credits State > Ġ= Ġ_ credits State ĊĊĠĠĠ Ġprivate Ġval Ġ_ similar State Ġ= Ġmutable State Of ( Similar Movies State ()) ĊĠĠĠ Ġval Ġsimilar State : ĠState < Similar Movies State > Ġ= Ġ_ similar State ĊĠĠĠ Ġval Ġsimilar Movies Page Ġ= Ġmutable State Of ( 1 ) ĊĠĠĠ Ġprivate Ġvar Ġsimilar Movies Position Ġ= Ġ 0 ĊĊĠĠĠ Ġvar Ġrating Ġ= Ġmutable State Of ( 0 f ) ĊĠĠĠ Ġvar Ġis W atched Ġ= Ġmutable State Of ( false ) ĊĠĠĠ Ġvar Ġis Pl anned Ġ= Ġmutable State Of ( false ) ĊĊĠĠĠ Ġvar Ġmovie Id Ġ= Ġ 0 ĊĠĠĠ Ġvar Ġmovie : ĠMovie ? Ġ= Ġnull ĊĊĠĠĠ Ġinit Ġ{ ĊĠĠĠĠĠĠĠ Ġsaved State Handle . get < String >( PARAM _ MOV IE _ ID )?. let Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġmovie Id Ġ= Ġit . toInt () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġget Movie ( movie Id ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġget Videos ( movie Id ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġget Credits ( movie Id ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġget Similar Movies ( movie Id ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġis Local Exists ( movie Id ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġget Movie ( movie Id : ĠInt ) Ġ{ ĊĠĠĠĠĠĠĠ Ġget Movie UseCase ( movie Id ). on Each Ġ{ Ġresult Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠ Ġwhen Ġ( result ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠResource . Loading Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ_ movie State . value Ġ= ĠMovie State ( isLoading Ġ= Ġtrue ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠResource . Success Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ_ movie State . value Ġ= ĠMovie State ( movie Ġ= Ġresult . data ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġget O mdb Data ( result . data ?. imdb Id Ġ?: Ġ"") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġmovie Ġ= Ġresult . data ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠResource . Error Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ_ movie State . value Ġ= ĠMovie State ( error Ġ= Ġresult . message Ġ?: Ġ" Error ") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ}. launch In ( viewModel Scope ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġis Local Exists ( movie Id : ĠInt ) Ġ{ ĊĠĠĠĠĠĠĠ ĠviewModel Scope . launch Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġw atched Movies UseCase . get Movie ( movie Id ). also Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġis W atched . value Ġ= Ġit . id Ġ== Ġmovie Id ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġrating . value Ġ= Ġit . my Rating Ġ?: Ġ 0 f ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġplanned Movies UseCase . get Movie ( movie Id ). also Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġis Pl anned . value Ġ= Ġit . id Ġ== Ġmovie Id ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġfun Ġadd W atched ( rating : ĠFloat ?) Ġ{ ĊĠĠĠĠĠĠĠ ĠviewModel Scope . launch Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġmovie ?. let Ġ{ Ġw atched Movies UseCase . add Movie ( it , Ġrating ) Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġfun Ġdelete W atched () Ġ{ ĊĠĠĠĠĠĠĠ ĠviewModel Scope . launch Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġmovie ?. let Ġ{ Ġw atched Movies UseCase . delete Movie ( it ) Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġis W atched . value Ġ= Ġfalse ĊĠĠĠĠĠĠĠĠĠĠĠ Ġrating . value Ġ= Ġ 0 f ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġfun Ġadd Pl anned () Ġ{ ĊĠĠĠĠĠĠĠ ĠviewModel Scope . launch Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġmovie ?. let Ġ{ Ġplanned Movies UseCase . add Movie ( it ) Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġfun Ġdelete Pl anned () Ġ{ ĊĠĠĠĠĠĠĠ ĠviewModel Scope . launch Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġmovie ?. let Ġ{ Ġplanned Movies UseCase . delete Movie ( it ) Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġget Videos ( movie Id : ĠInt ) Ġ{ ĊĠĠĠĠĠĠĠ Ġget Videos UseCase ( movie Id , ĠMediaType . Movie ). on Each Ġ{ Ġresult Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠ Ġwhen Ġ( result ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠResource . Loading Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ_ videos State . value Ġ= ĠMovie Videos State ( isLoading Ġ= Ġtrue ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠResource . Success Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ_ videos State . value Ġ= ĠMovie Videos State ( videos Ġ= Ġresult . data Ġ?: Ġempty List ()) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠResource . Error Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ_ videos State . value Ġ= ĠMovie Videos State ( error Ġ= Ġresult . message Ġ?: Ġ" Error ") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ}. launch In ( viewModel Scope ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġget O mdb Data ( imdb Id : ĠString ) Ġ{ ĊĠĠĠĠĠĠĠ Ġget Movie Ratings UseCase ( imdb Id ). on Each Ġ{ Ġresult Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠ Ġwhen Ġ( result ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠResource . Loading Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ_ om db State . value Ġ= ĠO mdb Data State ( isLoading Ġ= Ġtrue ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠResource . Success Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ_ om db State . value Ġ= ĠO mdb Data State ( data Ġ= Ġresult . data ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠResource . Error Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ_ om db State . value Ġ= ĠO mdb Data State ( error Ġ= Ġresult . message Ġ?: Ġ" Error ") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ}. launch In ( viewModel Scope ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġget Credits ( movie Id : ĠInt ) Ġ{ ĊĠĠĠĠĠĠĠ Ġget Credits UseCase ( movie Id , ĠMediaType . Movie ). on Each Ġ{ Ġresult Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠ Ġwhen Ġ( result ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠResource . Loading Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ_ credits State . value Ġ= ĠMovie Credits State ( isLoading Ġ= Ġtrue ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠResource . Success Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ_ credits State . value Ġ= ĠMovie Credits State ( credits Ġ= Ġresult . data ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠResource . Error Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ_ credits State . value Ġ= ĠMovie Credits State ( error Ġ= Ġresult . message Ġ?: Ġ" Error ") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ}. launch In ( viewModel Scope ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġget Similar Movies ( movie Id : ĠInt ) Ġ{ ĊĠĠĠĠĠĠĠ Ġget Similar UseCase ( movie Id , Ġpage Ġ= Ġ 1 , ĠMediaType . Movie ). on Each Ġ{ Ġresult Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠ Ġwhen Ġ( result ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠResource . Loading Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ_ similar State . value Ġ= ĠSimilar Movies State ( isLoading Ġ= Ġtrue ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠResource . Success Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġresult . data ?. forEach Ġ{ Ġit . vote Average Ġ= Ġw atched Movies UseCase . get Movie Rating ( it . id Ġ?: Ġ 0 ). toDouble () Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ_ similar State . value Ġ= ĠSimilar Movies State ( movies Ġ= Ġresult . data Ġ?: Ġempty List ()) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠResource . Error Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ_ similar State . value Ġ= ĠSimilar Movies State ( error Ġ= Ġresult . message Ġ?: Ġ" Error ") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ}. launch In ( viewModel Scope ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġfun Ġget More Similar Movies () Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ(( similar Movies Position Ġ+ Ġ 1 ) Ġ>= Ġ( similar Movies Page . value Ġ* ĠConstants . PAGE _ SIZE )) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġsimilar Movies Page . value Ġ= Ġsimilar Movies Page . value Ġ+ Ġ 1 ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( similar Movies Page . value Ġ> Ġ 1 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġget Similar UseCase ( movie Id , Ġsimilar Movies Page . value , ĠMediaType . Movie ). on Each Ġ{ Ġresult Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġwhen Ġ( result ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠResource . Success Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġresult . data ?. forEach Ġ{ Ġit . vote Average Ġ= Ġw atched Movies UseCase . get Movie Rating ( it . id Ġ?: Ġ 0 ). toDouble () Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ_ similar State . value Ġ= ĠSimilar Movies State ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġmovies Ġ= Ġ_ similar State . value . movies . plus ( result . data . or Empty ()) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġelse Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ_ similar State . value Ġ= ĠSimilar Movies State ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġmovies Ġ= Ġ_ similar State . value . movies . plus ( emptyList ()) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ}. launch In ( viewModel Scope ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġfun ĠonChange Position ( position : ĠInt ) Ġ{ ĊĠĠĠĠĠĠĠ Ġsimilar Movies Position Ġ= Ġposition ĊĠĠĠ Ġ} Ċ }