using System; using System.Collections.Generic; using System.Linq; using FireSharp.Interfaces; using FireSharp.Config; using FireSharp; using Newtonsoft.Json; using System.Configuration; using Herse.Models; namespace KaraokePlayer.Classes { public class FirebaseController { private IFirebaseConfig config = new FirebaseConfig { AuthSecret = ConfigurationManager.AppSettings["Firebase.Secret"], BasePath = ConfigurationManager.AppSettings["Firebase.Path"] }; private PlayerState _state = PlayerState.Playing; private IFirebaseClient _client; private ControllerStateChangedEventHandler _stateChanged; private ControllerSongChangedEventHandler _songChanged; public Settings Settings { get; set; } private string SettingsPath { get { return string.Format("controllers/{0}/player/settings", this.Id); } } private string QueuePath { get { return string.Format("controllers/{0}/player/queue", this.Id); } } private string StatePath { get { return string.Format("controllers/{0}/player/state/", this.Id); } } private string CurrentSongPath { get { return string.Format("controllers/{0}/player/queue/0/", this.Id); } } private string FavoritesPath { get { return string.Format("controllers/{0}/favorites/", this.Id); } } public string Id { get; set; } public Song CurrentSong { get; set; } public FirebaseController(string clientId, ControllerStateChangedEventHandler stateChanged, ControllerSongChangedEventHandler songChanged) { Id = clientId; _stateChanged = stateChanged; _songChanged = songChanged; _client = new FirebaseClient(config); SetupListener(); Settings = _client.Get(SettingsPath).ResultAs(); } private void SetupListener() { _client.OnAsync(CurrentSongPath, added: (s, args, obj) => { Console.WriteLine("added " + args.Path + " " + args.Data); CurrentSongDidChange(); }, removed: (s, args, obj) => { //TODO: the current song was removed from the queue } ); _client.OnAsync(StatePath, added: (s, args, obj) => { // do we need this? don't think so }, changed: (s, args, obj) => { Console.WriteLine("state changed " + args.Data); PlayerState newstate = (PlayerState)Enum.Parse(typeof(PlayerState), args.Data, true); StateDidChange(newstate); }, removed: null ); } /// /// called by the player to end the current song in firebase /// public void EndSong() { SetState(PlayerState.Stopped); List queue = _client.Get(QueuePath).ResultAs>(); queue.RemoveAt(0); _client.Set(QueuePath, queue); } /// /// called by the player to set the state in firebase /// /// public void SetState(PlayerState state) { _state = state; _client.SetAsync(StatePath, "Playing"); } /// /// called by firebase to change the current song /// private void CurrentSongDidChange() { var response = _client.Get(CurrentSongPath); var item = response.ResultAs(); if (item == null) return; if (CurrentSong == null || CurrentSong.Path != item.Song.Path) { CurrentSong = item.Song; _songChanged(new ControllerSongChangedEventArgs(item.Song)); UpdateFavorites(item.Song); } } /// /// called by firebase to change the current state /// /// private void StateDidChange(PlayerState newstate) { if (newstate == _state) return; _state = newstate; _stateChanged(new ControllerStateChangedEventArgs(newstate)); } private void UpdateFavorites(Song song) { //get favorites FavoriteSong favorite = null; List favorites = _client.Get(FavoritesPath).ResultAs>(); if (favorites == null) favorites = new List(); //unique song is based on the path favorite = favorites.SingleOrDefault(f => f.Path == song.Path); if (favorite == null) { favorite = new FavoriteSong(); favorite.Artist = song.Artist; favorite.Title = song.Title; favorite.Genre = song.Genre; favorite.Path = song.Path; favorite.Year = song.Year; favorite.Count = 1; favorites.Add(favorite); } else { favorite.Count += 1; } //take the top 100 songs var top100 = favorites.OrderByDescending(f => f.Count).Take(100); _client.Set(FavoritesPath, top100); } } }