package Ġcom . jer em iah zu cker . p android . player Ċ Ċ import Ġandroid . media . MediaPlayer Ċ import Ġandroid . util . Log Ċ import Ġcom . jer em iah zu cker . p android . request . P and ora Ċ import Ġcom . jer em iah zu cker . p android . request . json . v 5 . method . station . Get Playlist Ċ import Ġcom . jer em iah zu cker . p android . request . json . v 5 . method . station . Get Station Ċ import Ġcom . jer em iah zu cker . p android . request . json . v 5 . model . Expanded Station Model Ċ import Ġcom . jer em iah zu cker . p android . request . json . v 5 . model . Feedback Model Ċ import Ġcom . jer em iah zu cker . p android . request . json . v 5 . model . Track Model Ċ import Ġkotlin . reflect . K Property Ċ Ċ /** Ċ Ġ* ĠCreated Ġby Ġs ugar man z Ġon Ġ 9 / 1 0 / 1 7 . Ċ Ġ*/ Ċ internal Ġobject ĠPlayer Ġ: ĠPlayer Interface , ĠMedia Player . On Completion Listener Ġ{ ĊĊĠĠĠ Ġprivate Ġval ĠTAG : ĠString Ġ= ĠPlayer :: class . java . simple Name ĊĠĠĠ Ġ// ĠTODO : ĠConsider Ġfaster Ġalternatives Ġto ĠMedia Player ĊĠĠĠ Ġ// ĠAt Ġthe Ġmoment , ĠI Ġam Ġconsidering Ġsimply Ġdownloading Ġthe Ġmp 3 Ġfiles ĊĠĠĠ Ġ// Ġand Ġusing Ġthe ĠMedia Player Ġto Ġplay Ġthem . ĠThis Ġwill Ġhopefully Ġsolve ĊĠĠĠ Ġ// Ġthe Ġissues Ġwith Ġprepare Async Ġbeing Ġsuper Ġslow Ġand Ġwill Ġallow Ġfor ĊĠĠĠ Ġ// Ġoffline Ġuse . ĊĠĠĠ Ġprivate Ġvar Ġmedia Player Ġ= ĠMedia Player () ĊĠĠĠ Ġprivate Ġval Ġcallbacks Ġ= ĠArrayList < Player Interface . Callback >() ĊĠĠĠ Ġprivate Ġval Ġtracks Ġ= ĠArrayList < Track Model >() ĊĠĠĠ Ġprivate Ġval Ġfeedback s Ġ= Ġmutable Map Of < String , ĠFeedback Model >() ĊĠĠĠ Ġprivate Ġvar Ġindex Ġ= Ġ 0 ĊĠĠĠ Ġprivate Ġval Ġhas Next Ġget () Ġ= Ġindex Ġ< Ġtracks . size Ġ- Ġ 1 ĊĠĠĠ Ġprivate Ġval Ġhas Last Ġget () Ġ= Ġtracks . isNotEmpty () ĊĠĠĠ Ġprivate Ġval Ġnext Track Ġget () Ġ= Ġtracks [++ index ] ĊĠĠĠ Ġprivate Ġval Ġlast Track Ġget () Ġ= Ġtracks [ if Ġ( index Ġ- Ġ 1 Ġ< Ġ 0 ) Ġindex Ġelse Ġ-- index ] ĊĠĠĠ Ġprivate Ġvar Ġis Paused Ġ= Ġfalse ĊĊĠĠĠ Ġoverride Ġvar Ġplay Mode : ĠPlay Mode Ġ= ĠPlay Mode . default ĊĊĠĠĠ Ġoverride Ġvar Ġstation : ĠEx pan ded Station Model ? Ġ= Ġnull ĊĠĠĠĠĠĠĠ Ġset ( value ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠOnly Ġbother Ġsetting Ġif Ġchanging Ġstations ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( field ?. st ationToken Ġ!= Ġvalue ?. st ationToken ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġfield Ġ= Ġvalue ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠReset Ġplaylist ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġclear Playlist () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠLoad Ġfeedback s Ġfirst ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġload Feedback () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠLoad Ġinitial Ġplaylist ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġload Playlist () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġvar Ġcurrent Track : ĠTrack Model ? Ġ= Ġnull ĊĠĠĠĠĠĠĠ Ġprivate Ġset ĊĊĠĠĠ Ġoverride Ġval Ġis Playing : ĠBoolean Ġby ĠHandle Illegal State Delegate ( false ) Ġ{ Ġmedia Player . is Playing Ġ} ĊĠĠĠ Ġoverride Ġval Ġprogress : ĠInt Ġby ĠHandle Illegal State Delegate ( 0 ) Ġ{ Ġmedia Player . current Position Ġ} ĊĠĠĠ Ġoverride Ġval Ġduration : ĠInt Ġby ĠHandle Illegal State Delegate ( 0 ) Ġ{ Ġmedia Player . duration Ġ} ĊĊĠĠĠ Ġinternal Ġclass ĠHandle Illegal State Delegate < out ĠT >( private Ġval ĠdefaultValue : ĠT , Ġprivate Ġval Ġgetter : Ġ() Ġ-> ĠT ) Ġ{ ĊĠĠĠĠĠĠĠ Ġoperator Ġfun ĠgetValue ( this Ref : ĠAny ?, Ġproperty : ĠK Property < *> ): ĠT Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġgetter () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġcatch Ġ( e : ĠIllegalStateException ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġmedia Player . release () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġmedia Player Ġ= ĠMedia Player () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠdefaultValue ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġinit Ġ{ ĊĠĠĠĠĠĠĠ Ġmedia Player . setOn Completion Listener ( this ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ// ĠIMPORT ANT : ĠAss umes Ġthat Ġcurrent Track Ġhas Ġbeen Ġset Ġalready ĊĠĠĠ Ġoverride Ġfun Ġplay (): ĠBoolean Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ( is Paused ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġis Paused Ġ= Ġfalse ĊĠĠĠĠĠĠĠĠĠĠĠ Ġmedia Player . start () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġnotify Play Status Changed ( true ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġtrue ĊĠĠĠĠĠĠĠ Ġ} Ġelse Ġif Ġ( current Track Ġ!= Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġmedia Player . reset () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġmedia Player . set DataSource ( current Track ?. audio Url Map ?. high Quality ?. audio Url ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġmedia Player . prepare () Ġ// ĠTODO : ĠPrepare Async ???? ? ĊĠĠĠĠĠĠĠĠĠĠĠ Ġmedia Player . start () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġnotify Play Status Changed ( true ) ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ(! hasNext ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġload Playlist () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġtrue ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġreturn Ġfalse ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġplay ( station : ĠEx pan ded Station Model ): ĠBoolean Ġ{ ĊĠĠĠĠĠĠĠ Ġis Paused Ġ= Ġfalse ĊĠĠĠĠĠĠĠ Ġthis . station Ġ= Ġstation ĊĠĠĠĠĠĠĠ Ġreturn Ġtrue Ġ// ĠNot Ġreally , Ġlo l ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ// ĠWill Ġadd Ġthe Ġtrack Ġas Ġthe Ġnext Ġtrack Ġand Ġthen Ġplay Ġit ĊĠĠĠ Ġoverride Ġfun Ġplay ( track : ĠTrack Model ): ĠBoolean Ġ{ ĊĠĠĠĠĠĠĠ Ġis Paused Ġ= Ġfalse ĊĠĠĠĠĠĠĠ Ġreturn Ġif Ġ( tracks . isNotEmpty ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġtracks . add ( index Ġ+ Ġ 1 , Ġtrack ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġplay Next () ĊĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġtracks . add ( track ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġplay () ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġplay Last (): ĠBoolean Ġ{ ĊĠĠĠĠĠĠĠ Ġis Paused Ġ= Ġfalse ĊĠĠĠĠĠĠĠ Ġif Ġ( has Last ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġcurrent Track Ġ= Ġlast Track ĊĠĠĠĠĠĠĠĠĠĠĠ Ġplay () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġnotify Play Last ( current Track Ġas ĠTrack Model ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġtrue ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġreturn Ġfalse ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġplay Next (): ĠBoolean Ġ{ ĊĠĠĠĠĠĠĠ Ġis Paused Ġ= Ġfalse ĊĠĠĠĠĠĠĠ Ġif Ġ( hasNext ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġcurrent Track Ġ= Ġnext Track ĊĠĠĠĠĠĠĠĠĠĠĠ Ġplay () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġnotify Play Next ( current Track Ġas ĠTrack Model ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġtrue ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġreturn Ġfalse ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġpause (): ĠBoolean Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ( is Playing ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġmedia Player . pause () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġis Paused Ġ= Ġtrue ĊĠĠĠĠĠĠĠĠĠĠĠ Ġnotify Play Status Changed ( false ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġtrue ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġreturn Ġfalse ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġseek To ( progress : ĠInt ): ĠBoolean Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ( current Track Ġ!= Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( duration Ġ<= Ġprogress ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġon Completion ( media Player ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġmedia Player . seek To ( progress ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġtrue ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġreturn Ġfalse ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġregister Callback ( callback : ĠPlayer Interface . Callback ) Ġ{ ĊĠĠĠĠĠĠĠ Ġcallbacks . add ( callback ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġunregister Callback ( callback : ĠPlayer Interface . Callback ) Ġ{ ĊĠĠĠĠĠĠĠ Ġcallbacks . remove ( callback ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġremove Callbacks () Ġ{ ĊĠĠĠĠĠĠĠ Ġcallbacks . clear () ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġrelease Player () Ġ{ ĊĠĠĠĠĠĠĠ Ġmedia Player . release () ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġnotify Play Status Changed ( is Playing : ĠBoolean ) Ġ{ ĊĠĠĠĠĠĠĠ Ġcallbacks . forEach Ġ{ Ġit . on Play Status Changed ( is Playing ) Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġnotify Play Last ( track : ĠTrack Model ) Ġ{ ĊĠĠĠĠĠĠĠ Ġcallbacks . forEach Ġ{ Ġit . on Switch Last ( track ) Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġnotify Play Next ( track : ĠTrack Model ) Ġ{ ĊĠĠĠĠĠĠĠ Ġcallbacks . forEach Ġ{ Ġit . on Switch Next ( track ) Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġnotify Complete ( track : ĠTrack Model ?) Ġ{ ĊĠĠĠĠĠĠĠ Ġcallbacks . forEach Ġ{ Ġit . onComplete ( track ) Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġon Completion ( media Player : ĠMedia Player ?) Ġ{ ĊĠĠĠĠĠĠĠ Ġvar Ġnext : ĠTrack Model ? Ġ= Ġnull ĊĠĠĠĠĠĠĠ Ġ// ĠThere Ġis Ġonly Ġone Ġlimited Ġplay Ġmode Ġwhich Ġis Ġlist , Ġplayer Ġshould Ġbe Ġstopped Ġwhen Ġhitting Ġthe Ġlist Ġend ĊĠĠĠĠĠĠĠ Ġif Ġ( play Mode Ġ=== ĠPlay Mode . LIST Ġ&& Ġindex Ġ== Ġtracks . size Ġ- Ġ 1 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠIn Ġthe Ġend Ġof Ġthe Ġlist ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠDo Ġnothing , Ġjust Ġdeliver Ġthe Ġcallback ĊĠĠĠĠĠĠĠ Ġ} Ġelse Ġif Ġ( play Mode Ġ=== ĠPlay Mode . SINGLE ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġcurrent Track Ġ= Ġcurrent Track ĊĠĠĠĠĠĠĠĠĠĠĠ Ġplay () ĊĠĠĠĠĠĠĠ Ġ} Ġelse Ġif Ġ( hasNext ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġcurrent Track Ġ= Ġnext Track ĊĠĠĠĠĠĠĠĠĠĠĠ Ġplay () ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġnotify Complete ( current Track ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġclear Playlist () Ġ{ ĊĠĠĠĠĠĠĠ Ġmedia Player . reset () ĊĠĠĠĠĠĠĠ Ġindex Ġ= Ġ 0 ĊĠĠĠĠĠĠĠ Ġtracks . clear () ĊĠĠĠĠĠĠĠ Ġfeedback s . clear () ĊĠĠĠĠĠĠĠ Ġcurrent Track Ġ= Ġnull ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġload Playlist () Ġ= ĠP and ora . HTTP ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. RequestBuilder ( Get Playlist ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. body ( Get Playlist . RequestBody ( station ?. st ationToken Ġ?: Ġ"")) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. build < Get Playlist . ResponseBody >() ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. subscribe ( this :: load Playlist Success , Ġthis :: load Playlist Error ) ĊĊĠĠĠ Ġprivate Ġfun Ġload Playlist Success ( response : ĠGet Playlist . ResponseBody ) Ġ{ ĊĠĠĠĠĠĠĠ Ġ// ĠAdd Ġfeedback Ġid Ġif Ġit Ġexists ĊĠĠĠĠĠĠĠ Ġresponse . items . forEach Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġit . feedback Id Ġ= Ġfeedback s [ it . track Token ]?. feedback Id ĊĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġ// ĠAdd Ġthe Ġtracks Ġto Ġthe Ġqueue ĊĠĠĠĠĠĠĠ Ġtracks . addAll ( response . items . filter Ġ{ Ġit . track Token Ġ!= Ġnull Ġ}) ĊĠĠĠĠĠĠĠ Ġif Ġ( current Track Ġ== Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġindex Ġ= Ġ 0 ĊĠĠĠĠĠĠĠĠĠĠĠ Ġcurrent Track Ġ= Ġtracks [ 0 ] ĊĠĠĠĠĠĠĠĠĠĠĠ Ġplay () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġnotify Complete ( current Track ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĠĠĠ Ġprivate Ġfun Ġload Playlist Error ( throwable : ĠThrowable ) Ġ{ ĊĠĠĠĠĠĠĠ Ġthrowable . printStackTrace () ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġload Feedback () Ġ= ĠP and ora . HTTPS ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. RequestBuilder ( Get Station ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. body ( Get Station . RequestBody ( station ?. st ationToken Ġ?: Ġ"", Ġtrue )) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. build < Get Station . ResponseBody >() ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. subscribe ( this :: load Feedback Success , Ġthis :: load Feedback Error ) ĊĊĠĠĠ Ġprivate Ġfun Ġload Feedback Success ( response : ĠGet Station . ResponseBody ) Ġ{ ĊĠĠĠĠĠĠĠ Ġresponse . feedback . thumbs Up . associate By Ġ{ Ġit . music Token Ġ} ĊĠĠĠ Ġ} ĊĠĠĠ Ġprivate Ġfun Ġload Feedback Error ( throwable : ĠThrowable ) Ġ{ ĊĠĠĠĠĠĠĠ Ġthrowable . printStackTrace () ĊĠĠĠ Ġ} ĊĊ Ċ }