Separate player logic from the playlist logic.
Rename discovery logic to validation as this is more accurate of the
underlying logic.
PlayerPlaylist object handles the playlist and songs validation
logic. Player object acts as a glue for the ui and the underlying
logic (playlist and validation).
Use Gobject Properties.
There are 4 ways to launch a song:
1. Click on a song in the current view. The set_playlist method is
called.
2. At the end of the current song. The next method is automatically called.
3. click on the next buttom from the PlayerToolbar. The next method is called.
4. click on the previous buttom from the PlayerToolbar. The previous
method is called.
Validation is a very expensive operation, so only do it when it's
needed. See commit message from 6f1cb8d4.
The Validation logic brings 3 features:
- display an error icon if a song cannot be played
- do not load a song that cannot be played
- when the song changes, try to load the next possible one: if the
next song cannot be loaded, try the one after, etc.
In "set_playlist" method, if the song has already been played the
validation information is already known, nothing to add. If the song
has never been played, there is no information yet. In that case,
validate_current_song and validate_next_song need to be called to
trigger the validation mechanism.
In "next" method, call validate_next_song to continue the validation
mechanism if there is a next song.
In "previous" method, call validate_previous_song to continue the validation
mechanism if there is a previous song.
Closes: #60, #154