/** * Copyright 2013 (c) Anna Schumaker. */ #include #include class PlaylistQueue : public Queue { public: PlaylistQueue() : Queue(Q_ENABLED | Q_REPEAT) { sort(SORT_ARTIST, true); sort(SORT_YEAR, false); sort(SORT_TRACK, false); set_flag(Q_NO_SORT); } void clear() { while (size() > 0) del((unsigned)0); } void fill(index_entry *ent) { struct set_iter it; clear(); set_for_each(&ent->ie_set, &it) add(track_get(it.it_val)); } unsigned int find_average_count() { struct db_entry *track, *next; unsigned int total = 0, count = 0; db_for_each(track, next, track_db_get()) { total += TRACK(track)->tr_count; count++; } if (count > 0) return total / count; return 0; } void dynamic_add(const std::string &name, struct track *track, unsigned int avg) { if ((name == "Unplayed") && (track->tr_count == 0)) add(track); if ((name == "Most Played") && (track->tr_count > avg)) add(track); if ((name == "Least Played") && (track->tr_count < avg)) add(track); } void dynamic_fill(const std::string &name) { struct db_entry *track, *next; unsigned int avg = 0; if ((name == "Most Played") || (name == "Least Played")) avg = find_average_count(); clear(); db_for_each(track, next, track_db_get()) dynamic_add(name, TRACK(track), avg); } }; static struct database playlist_db; static PlaylistQueue playlist_q; static std::string cur_plist; void playlist :: init() { struct set_iter it; index_init(&playlist_db, "playlist.db", true); db_load(&playlist_db); index_entry *ent = get_tracks("Banned"); if (!ent) return; set_for_each(&ent->ie_set, &it) collection :: get_queue()->del(track_get(it.it_val)); } bool playlist :: has(struct track *track, const std::string &name) { return index_has(&playlist_db, name.c_str(), track->dbe_index); } void playlist :: add(struct track *track, const std::string &name) { if (!( (name == "Banned") || (name == "Favorites") )) return; if (!has(track, name)) { index_insert(&playlist_db, name.c_str(), track->dbe_index); if (cur_plist == name) playlist_q.add(track); if (name == "Banned") collection :: get_queue()->del(track); } } void playlist :: del(struct track *track, const std::string &name) { index_remove(&playlist_db, name.c_str(), track->dbe_index); if (cur_plist == name) playlist_q.del(track); if (name == "Banned") collection :: get_queue()->add(track); } void playlist :: select(const std::string &name) { index_entry *ent = INDEX_ENTRY(db_get(&playlist_db, name.c_str())); if (ent != NULL) playlist_q.fill(ent); else playlist_q.dynamic_fill(name); cur_plist = name; } index_entry *playlist :: get_tracks(const std::string &name) { return INDEX_ENTRY(db_get(&playlist_db, name.c_str())); } Queue *playlist :: get_queue() { return &playlist_q; }