/** * Copyright 2013 (c) Anna Schumaker. */ extern "C" { #include } #include class PlaylistQueue : public queue { public: void clear() { queue_clear(this); } void fill(index_entry *ent) { struct set_iter it; clear(); queue_set_flag(this, Q_ADD_FRONT); set_for_each(&ent->ie_set, &it) queue_add(this, track_get(it.it_val)); queue_unset_flag(this, Q_ADD_FRONT); queue_resort(this); } 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)) queue_add(this, track); if ((name == "Most Played") && (track->tr_count > avg)) queue_add(this, track); if ((name == "Least Played") && (track->tr_count < avg)) queue_add(this, 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(); queue_set_flag(this, Q_ADD_FRONT); db_for_each(track, next, track_db_get()) dynamic_add(name, TRACK(track), avg); queue_unset_flag(this, Q_ADD_FRONT); queue_resort(this); } }; static struct database playlist_db; static PlaylistQueue playlist_q; static std::string cur_plist; void playlist :: init(struct queue_ops *ops) { struct set_iter it; 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(&playlist_db); index_entry *ent = get_tracks("Banned"); if (!ent) return; set_for_each(&ent->ie_set, &it) queue_remove_all(collection_get_queue(), track_get(it.it_val)); } bool playlist :: has(struct track *track, const std::string &name) { if (playlist_db.db_size == 0) return false; return index_has(&playlist_db, name.c_str(), track->tr_dbe.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->tr_dbe.dbe_index); if (cur_plist == name) queue_add(&playlist_q, track); if (name == "Banned") queue_remove_all(collection_get_queue(), track); } } void playlist :: del(struct track *track, const std::string &name) { index_remove(&playlist_db, name.c_str(), track->tr_dbe.dbe_index); if (cur_plist == name) queue_remove_all(&playlist_q, track); if (name == "Banned") queue_add(collection_get_queue(), 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; }