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