ocarina/core/playlist.c

127 lines
3.1 KiB
C

/*
* Copyright 2013 (c) Anna Schumaker.
*/
#include <core/collection.h>
#include <core/string.h>
#include <core/playlist.h>
static struct database playlist_db;
static struct queue playlist_q;
static enum playlist_t playlist_cur;
static const gchar *playlist_names[2] = { "Favorites", "Banned" };
static inline struct index_entry *__playlist_lookup(enum playlist_t plist)
{
return INDEX_ENTRY(db_get(&playlist_db, playlist_names[plist]));
}
static inline bool __playlist_is_static(enum playlist_t plist)
{
return (plist == PL_FAVORITED) || (plist == PL_HIDDEN);
}
static inline bool __playlist_is_dynamic(enum playlist_t plist)
{
return !__playlist_is_static(plist);
}
static void __playlist_fill_static(enum playlist_t plist)
{
struct index_entry *ent = __playlist_lookup(plist);
struct set_iter it;
if (ent) {
set_for_each(&ent->ie_set, &it)
queue_add(&playlist_q, track_get(it.it_val));
}
}
static void __playlist_fill_dynamic(enum playlist_t plist)
{
unsigned int count = 0, average = 0;
struct db_entry *track, *next;
if (plist == PL_MOST_PLAYED || plist == PL_LEAST_PLAYED)
average = track_db_average_plays();
db_for_each(track, next, track_db_get()) {
count = TRACK(track)->tr_count;
if (plist == PL_UNPLAYED && count == 0)
queue_add(&playlist_q, TRACK(track));
else if (plist == PL_MOST_PLAYED && count > average)
queue_add(&playlist_q, TRACK(track));
else if (plist == PL_LEAST_PLAYED && count <= average && count > 0)
queue_add(&playlist_q, TRACK(track));
}
}
void playlist_init(struct queue_ops *ops)
{
queue_init(&playlist_q, Q_ENABLED | Q_REPEAT, ops);
queue_sort(&playlist_q, COMPARE_ARTIST, true);
queue_sort(&playlist_q, COMPARE_YEAR, false);
queue_sort(&playlist_q, COMPARE_TRACK, false);
queue_set_flag(&playlist_q, Q_NO_SORT);
index_init(&playlist_db, "playlist.db", true);
db_load_idle(&playlist_db);
}
void playlist_deinit()
{
queue_deinit(&playlist_q);
db_deinit(&playlist_db);
}
bool playlist_add(enum playlist_t plist, struct track *track)
{
if (!track || !__playlist_is_static(plist) || playlist_has(plist, track))
return false;
index_insert(&playlist_db, playlist_names[plist],
track->tr_dbe.dbe_index);
if (playlist_cur == plist)
queue_add(&playlist_q, track);
return true;
}
bool playlist_remove(enum playlist_t plist, struct track *track)
{
if (!track || !playlist_has(plist, track))
return false;
index_remove(&playlist_db, playlist_names[plist],
track->tr_dbe.dbe_index);
if (playlist_cur == plist)
queue_remove_all(&playlist_q, track);
return true;
}
bool playlist_has(enum playlist_t plist, struct track *track)
{
if (!track || __playlist_is_dynamic(plist))
return false;
return index_has(&playlist_db, playlist_names[plist], track->tr_dbe.dbe_index);
}
void playlist_select(enum playlist_t plist)
{
queue_clear(&playlist_q);
queue_set_flag(&playlist_q, Q_ADD_FRONT);
if (__playlist_is_static(plist))
__playlist_fill_static(plist);
else
__playlist_fill_dynamic(plist);
queue_unset_flag(&playlist_q, Q_ADD_FRONT);
playlist_cur = plist;
queue_resort(&playlist_q);
}
struct queue *playlist_get_queue()
{
return &playlist_q;
}