ocarina/core/playlist.c

204 lines
5.1 KiB
C

/*
* Copyright 2013 (c) Anna Schumaker.
*/
#include <core/playlist.h>
#include <core/settings.h>
#include <core/string.h>
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);
}