package code.name.monkey.retromusic.fragments import androidx.lifecycle.LiveData import androidx.lifecycle.MutableLiveData import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope import code.name.monkey.retromusic.db.PlaylistEntity import code.name.monkey.retromusic.db.PlaylistWithSongs import code.name.monkey.retromusic.db.SongEntity import code.name.monkey.retromusic.fragments.ReloadType.* import code.name.monkey.retromusic.helper.MusicPlayerRemote import code.name.monkey.retromusic.interfaces.MusicServiceEventListener import code.name.monkey.retromusic.model.* import code.name.monkey.retromusic.repository.RealRepository import kotlinx.coroutines.Dispatchers.IO import kotlinx.coroutines.launch class LibraryViewModel( private val repository: RealRepository ) : ViewModel(), MusicServiceEventListener { private val paletteColor = MutableLiveData() private val albums = MutableLiveData>() private val songs = MutableLiveData>() private val artists = MutableLiveData>() private val playlists = MutableLiveData>() private val legacyPlaylists = MutableLiveData>() private val genres = MutableLiveData>() private val home = MutableLiveData>() val paletteColorLiveData: LiveData = paletteColor init { fetchHomeSections() } private fun loadLibraryContent() = viewModelScope.launch(IO) { fetchHomeSections() fetchSongs() fetchAlbums() fetchArtists() fetchGenres() fetchPlaylists() } fun getSongs(): LiveData> { fetchSongs() return songs } fun getAlbums(): LiveData> { fetchAlbums() return albums } fun getArtists(): LiveData> { fetchArtists() return artists } fun getPlaylists(): LiveData> { fetchPlaylists() return playlists } fun getLegacyPlaylist(): LiveData> { fetchLegacyPlaylist() return legacyPlaylists } fun getGenre(): LiveData> { fetchGenres() return genres } fun getHome(): LiveData> { return home } private fun fetchSongs() { viewModelScope.launch(IO) { songs.postValue(repository.allSongs()) } } private fun fetchAlbums() { viewModelScope.launch(IO) { albums.postValue(repository.fetchAlbums()) } } private fun fetchArtists() { viewModelScope.launch(IO) { artists.postValue(repository.fetchArtists()) } } private fun fetchPlaylists() { viewModelScope.launch(IO) { playlists.postValue(repository.fetchPlaylistWithSongs()) } } private fun fetchLegacyPlaylist() { viewModelScope.launch(IO) { legacyPlaylists.postValue(repository.fetchLegacyPlaylist()) } } private fun fetchGenres() { viewModelScope.launch(IO) { genres.postValue(repository.fetchGenres()) } } private fun fetchHomeSections() { viewModelScope.launch(IO) { home.postValue(repository.homeSections()) } } fun forceReload(reloadType: ReloadType) = viewModelScope.launch { when (reloadType) { Songs -> fetchSongs() Albums -> fetchAlbums() Artists -> fetchArtists() HomeSections -> fetchHomeSections() Playlists -> fetchPlaylists() Genres -> fetchGenres() } } fun updateColor(newColor: Int) { paletteColor.postValue(newColor) } override fun onMediaStoreChanged() { println("onMediaStoreChanged") loadLibraryContent() } override fun onServiceConnected() { println("onServiceConnected") } override fun onServiceDisconnected() { println("onServiceDisconnected") } override fun onQueueChanged() { println("onQueueChanged") } override fun onPlayingMetaChanged() { println("onPlayingMetaChanged") } override fun onPlayStateChanged() { println("onPlayStateChanged") } override fun onRepeatModeChanged() { println("onRepeatModeChanged") } override fun onShuffleModeChanged() { println("onShuffleModeChanged") } fun shuffleSongs() = viewModelScope.launch(IO) { val songs = repository.allSongs() MusicPlayerRemote.openAndShuffleQueue( songs, true ) } fun renameRoomPlaylist(playListId: Int, name: String) = viewModelScope.launch(IO) { repository.renameRoomPlaylist(playListId, name) } fun deleteSongsInPlaylist(songs: List) = viewModelScope.launch(IO) { repository.deleteSongsInPlaylist(songs) } fun deleteSongsFromPlaylist(playlists: List) = viewModelScope.launch(IO) { repository.deleteSongsFromPlaylist(playlists) } fun deleteRoomPlaylist(playlists: List) = viewModelScope.launch(IO) { repository.deleteRoomPlaylist(playlists) } suspend fun albumById(id: Int) = repository.albumById(id) suspend fun artistById(id: Int) = repository.artistById(id) suspend fun favoritePlaylist() = repository.favoritePlaylist() suspend fun isFavoriteSong(song: SongEntity) = repository.isFavoriteSong(song) suspend fun insertSongs(songs: List) = repository.insertSongs(songs) suspend fun removeSongFromPlaylist(songEntity: SongEntity) = repository.removeSongFromPlaylist(songEntity) suspend fun checkPlaylistExists(playlistName: String): List = repository.checkPlaylistExists(playlistName) suspend fun createPlaylist(playlistEntity: PlaylistEntity): Long = repository.createPlaylist(playlistEntity) fun importPlaylists() = viewModelScope.launch(IO) { val playlists = repository.fetchLegacyPlaylist() playlists.forEach { playlist -> val playlistEntity = repository.checkPlaylistExists(playlist.name).firstOrNull(); if (playlistEntity != null) { val songEntities = playlist.getSongs().map { it.toSongEntity(playlistEntity.playListId) } repository.insertSongs(songEntities) } else { val playListId = createPlaylist(PlaylistEntity(playlist.name)) val songEntities = playlist.getSongs().map { it.toSongEntity(playListId.toInt()) } repository.insertSongs(songEntities) } forceReload(Playlists) } } fun deleteTracks(songs: List) = viewModelScope.launch(IO) { repository.deleteSongs(songs) } } enum class ReloadType { Songs, Albums, Artists, HomeSections, Playlists, Genres, }