/* * Copyright 2013 (c) Anna Schumaker. */ #include #include #include static const gchar *SETTINGS_CUR_TYPE = "core.playlist.cur.type"; static const gchar *SETTINGS_CUR_ID = "core.playlist.cur.id"; static const gchar *SETTINGS_PREV_TYPE = "core.playlist.prev.type"; static const gchar *SETTINGS_PREV_ID = "core.playlist.prev.id"; struct playlist_type *playlist_types[] = { [PL_SYSTEM] = &pl_system, [PL_ARTIST] = &pl_artist, [PL_LIBRARY] = &pl_library, [PL_USER] = &pl_user, }; void playlist_init(struct queue_ops *ops) { pl_system_init(ops); pl_artist_init(ops); pl_user_init(ops); pl_library_init(ops); if (!settings_has(SETTINGS_CUR_TYPE) || !settings_has(SETTINGS_CUR_ID)) { playlist_select(PL_SYSTEM, "Collection"); if (playlist_size(playlist_get(PL_SYSTEM, "Queued Tracks")) > 0) playlist_select(PL_SYSTEM, "Queued Tracks"); } } void playlist_deinit() { pl_system_deinit(); pl_artist_deinit(); pl_user_deinit(); pl_library_deinit(); } void playlist_save() { unsigned int i; for (i = 0; i < PL_MAX_TYPE; i++) playlist_types[i]->pl_save(); } bool playlist_select(enum playlist_type_t type, const gchar *name) { if (!playlist_types[type]->pl_can_select(name)) return false; if ((settings_get(SETTINGS_CUR_TYPE) == type) && settings_get(SETTINGS_CUR_ID) == playlist_get_id(type, name)) return true; settings_set(SETTINGS_PREV_TYPE, settings_get(SETTINGS_CUR_TYPE)); settings_set(SETTINGS_PREV_ID, settings_get(SETTINGS_CUR_ID)); settings_set(SETTINGS_CUR_TYPE, type); settings_set(SETTINGS_CUR_ID, playlist_get_id(type, name)); return true; } struct playlist *playlist_new(enum playlist_type_t type, const gchar *name) { if (type < PL_MAX_TYPE && playlist_types[type]->pl_new) return playlist_types[type]->pl_new(name); return NULL; } bool playlist_delete(struct playlist *playlist) { enum playlist_type_t type; bool ret; if (!playlist || !playlist->pl_ops->pl_delete) return false; type = playlist->pl_type; ret = playlist->pl_ops->pl_delete(playlist); if (ret) playlist_types[type]->pl_save(); return ret; } bool playlist_add(struct playlist *playlist, struct track *track) { bool ret; if (!track || !playlist || !playlist->pl_ops->pl_add) return false; ret = playlist->pl_ops->pl_add(playlist, track); if (ret) playlist_types[playlist->pl_type]->pl_save(); if (playlist == playlist_get(PL_SYSTEM, "Queued Tracks")) playlist_select(PL_SYSTEM, "Queued Tracks"); return ret; } bool playlist_remove(struct playlist *playlist, struct track *track) { bool ret; if (!track || !playlist || !playlist->pl_ops->pl_remove) return false; ret = playlist->pl_ops->pl_remove(playlist, track); if (ret) playlist_types[playlist->pl_type]->pl_save(); return ret; } void playlist_update(enum playlist_type_t type, const gchar *name) { playlist_types[type]->pl_update(name); } bool playlist_has(struct playlist *playlist, struct track *track) { if (!playlist || !track) return false; return queue_has(&playlist->pl_queue, track); } unsigned int playlist_size(struct playlist *playlist) { return playlist ? queue_size(&playlist->pl_queue) : 0; } void playlist_set_random(struct playlist *playlist, bool enabled) { if (playlist && playlist->pl_ops->pl_set_flag) { playlist->pl_ops->pl_set_flag(playlist, Q_RANDOM, enabled); playlist_types[playlist->pl_type]->pl_save(); } } bool playlist_get_random(struct playlist *playlist) { return playlist ? queue_has_flag(&playlist->pl_queue, Q_RANDOM) : false; } void playlist_sort(enum playlist_type_t type, const gchar *name, enum compare_t sort, bool reset) { playlist_types[type]->pl_sort(name, sort, reset); } struct track *playlist_next(void) { enum playlist_type_t type = settings_get(SETTINGS_CUR_TYPE); unsigned int id = settings_get(SETTINGS_CUR_ID); gchar *name = playlist_get_name(type, id); struct track *track = playlist_types[type]->pl_next(name); if (playlist_size(playlist_get(type, name)) == 0) { settings_set(SETTINGS_CUR_ID, settings_get(SETTINGS_PREV_ID)); settings_set(SETTINGS_CUR_TYPE, settings_get(SETTINGS_PREV_TYPE)); } g_free(name); return track; } struct track *playlist_prev(void) { return playlist_types[PL_SYSTEM]->pl_next("History"); } struct playlist *playlist_get(enum playlist_type_t type, const gchar *name) { return playlist_types[type]->pl_get_playlist(name); } struct playlist *playlist_cur(void) { enum playlist_type_t type = settings_get(SETTINGS_CUR_TYPE); unsigned int id = settings_get(SETTINGS_CUR_ID); gchar *name = playlist_get_name(type, id); struct playlist *ret = playlist_get(type, name); g_free(name); return ret; } struct queue *playlist_get_queue(enum playlist_type_t type, const gchar *name) { struct playlist *playlist = playlist_get(type, name); return playlist ? &playlist->pl_queue : NULL; } unsigned int playlist_get_id(enum playlist_type_t type, const gchar *name) { return playlist_types[type]->pl_get_id(name); } gchar *playlist_get_name(enum playlist_type_t type, unsigned int id) { return playlist_types[type]->pl_get_name(id); }