protected override bool OnStartup(StartupEventArgs eventArgs) {
            InitSettings();

            SongPlayer = new SongPlayer(ApplicationSettings.Volume);
            Playlist = new Playlist();
            TransitionMgr = new TransitionManager(SongPlayer, Playlist, ApplicationSettings);

            if(eventArgs.CommandLine.Count > 0) {
                HandleArgs(eventArgs.CommandLine.ToArray()).Wait();
            } else {
                LoadStartupSongFiles();
            }

            SpeechController = new SpeechController(SongPlayer, Playlist, ApplicationSettings);
            SpeechController.Init();

            Application = new SpeechMusicControllerApp();
            Application.InitializeComponent();

            var windowMgr = new WindowManager((Hardcodet.Wpf.TaskbarNotification.TaskbarIcon)Application.FindResource(TrayIconResourceName));
            windowMgr.Init(ApplicationSettings, SongPlayer, Playlist, SpeechController);

            Application.Exiting += (s, a) => {
                ApplicationSettings.WriteToDisc();
            };

            windowMgr.Overlay.DisplayText("SMC Running...", 2000);
            Application.Run();
            return false;
        }
        public void Init(AppSettings settings, SongPlayer songPlayer, Playlist playlist, SpeechController speechControl)
        {
            ViewModel = new FullPlayerViewModel(settings, songPlayer, playlist, speechControl);

            CreateFullPlayer(!settings.StartMinimized);
            CreateSmallPlayer(settings.StartMinimized);

            SetupContextMenu(songPlayer);

            SetupScreenOverlay(settings, speechControl, songPlayer);
        }
        public FullPlayerViewModel(AppSettings settings, SongPlayer player, Playlist playlist, SpeechController speechController)
            : base(settings, player, playlist)
        {
            SetupCommands();
            SetupSongMenuItems();

            SettingsViewModel = new AppSettingsViewModel(Settings);

            FillPlaylist();

            SetupAboutSpeechCommands(speechController);

            SongPlayer.SongChanged += SongPlayer_SongChanged;
            Playlist.ListContentChanged += PlaylistChanged;
            Playlist.ListOrderChanged += PlaylistChanged;

            SearchText = string.Empty;
            UIEnabled = true;
        }
        public static SpeechCommand[] CreateCommands(SpeechController speechController)
        {
            return new SpeechCommand[] {
                new SpeechCommand() {
                    KeyWords = new List<IEnumerable<string>>() {
                        new string[] { "music" },
                        new string[] { "volume up", "volume down" }
                    },
                    Description = "Music + [Volume up / Volume down]+ : Change volume",
                    Execute = (sentence) => {
                        if(sentence.ElementAt(1) == "volume up") {
                            speechController.Settings.Volume += 0.1f;
                        } else if(sentence.ElementAt(1) == "volume down") {
                            speechController.Settings.Volume -= 0.1f;
                        }
                        return new string[] { "music" };
                    },
                    CanExecute = DefaultCanExecute(speechController)
                },

                new SpeechCommand() {
                    KeyWords = CreateSingleChoiceKeywords("music", "switch"),
                    Description = "Music + Switch : Pause/Unpause",
                    Execute = (sentence) => {
                        speechController.Player.TogglePause(true);
                        return new string[0];
                    },
                    CanExecute = DefaultCanExecute(speechController)
                },

                new SpeechCommand() {
                    KeyWords = new List<IEnumerable<string>>() {
                        new string[] { "music" },
                        new string[] { "next", "previous" }
                    },
                    Description = "Music + [Next / Previous]+ : Step through playlist",
                    Execute = (sentence) => {
                        var dir = sentence.ElementAt(1);
                        int increment = (dir == "next") ? 1 : (dir == "previous") ? -1 : 0;
                        speechController.Playlist.CurrentSongIndex += increment;
                        return new string[] { "music" };
                    },
                    CanExecute = DefaultCanExecute(speechController)
                },

                new SpeechCommand() {
                    KeyWords = new List<IEnumerable<string>>() {
                        new string[] { "music" },
                        new string[] { "random", "shuffle" }
                    },
                    Description = "Music + [Random / Shuffle] : Shuffle the playlist",
                    Execute = (sentence) => {
                        speechController.Playlist.Shuffle();
                        return new string[0];
                    },
                    CanExecute = DefaultCanExecute(speechController)
                },

                new SpeechCommand() {
                    KeyWords = new List<IEnumerable<string>>() {
                        new string[] { "music" },
                        new string[] { "stop listening", "start listening" }
                    },
                    Description = "Music + [Stop listening / Start listening] : Enable or disable speech input",
                    Execute = (sentence) => {
                        speechController.Settings.EnableSpeech = sentence.ElementAt(1) == "start listening";
                        return new string[0];
                    }
                },

                #region play song/album/artist
                new SpeechCommand() {
                    KeyWords = new List<IEnumerable<string>>() {
                        new string[] { "play song" },
                        speechController.Playlist.Select(s => s.Title)
                    },
                    Description = "Play song + <Song Title> : Play songs by name",
                    Execute = (sentence) => {
                        var songName = sentence.ElementAt(1);
                        speechController.Playlist.SelectAllMatches(s => s?.Title?.Equals(songName, StringComparison.CurrentCultureIgnoreCase) ?? false);
                        speechController.Player.PlayerState = PlayerState.Playing;
                        return new string[0];
                    },
                    CanExecute = DefaultCanExecute(speechController)
                },

                new SpeechCommand() {
                    KeyWords = new List<IEnumerable<string>>() {
                        new string[] { "play album" },
                        speechController.Playlist.Select(s => s.Album)
                    },
                    Description = "Play album + <Album Name> : Play songs by album",
                    Execute = (sentence) => {
                        var albumName = sentence.ElementAt(1);
                        speechController.Playlist.SelectAllMatches(s => s?.Album?.Equals(albumName, StringComparison.CurrentCultureIgnoreCase) ?? false);
                        speechController.Player.PlayerState = PlayerState.Playing;
                        return new string[0];
                    },
                    CanExecute = DefaultCanExecute(speechController)
                },

                new SpeechCommand() {
                    KeyWords = new List<IEnumerable<string>>() {
                        new string[] { "play artist" },
                        speechController.Playlist.Select(s => s.Artist)
                    },
                    Description = "Play artist + <Arist Name> : Play songs by artist",
                    Execute = (sentence) => {
                        var artistName = sentence.ElementAt(1);
                        speechController.Playlist.SelectAllMatches(s => s?.Artist?.Equals(artistName, StringComparison.CurrentCultureIgnoreCase) ?? false);
                        speechController.Player.PlayerState = PlayerState.Playing;
                        return new string[0];
                    },
                    CanExecute = DefaultCanExecute(speechController)
                },
                #endregion play song/album/artist
            };
        }
 public static Func<bool> DefaultCanExecute(SpeechController speech, Func<bool> custom = null)
 {
     return () => speech.Settings.EnableSpeech && custom?.Invoke() != false;
 }
 private void SetupAboutSpeechCommands(SpeechController speechController)
 {
     AboutSpeechCommands = new ObservableCollection<string>();
     LoadAboutSpeechCommands(speechController);
     speechController.Commands.CollectionChanged += (s, a) => LoadAboutSpeechCommands(speechController);
 }
 private void LoadAboutSpeechCommands(SpeechController speechController)
 {
     var commandDesc = speechController.Commands.Select(sc => sc.Description);
     AboutSpeechCommands.Clear();
     foreach(var desc in commandDesc) {
         AboutSpeechCommands.Add(desc);
     }
 }
        private void SetupScreenOverlay(AppSettings settings, SpeechController speech, SongPlayer player)
        {
            Overlay = new ScreenOverlay(settings);

            speech.PartialSentenceMatch += (s, a) => {
                if(settings.EnableSpeech) {
                    Application.Current.Dispatcher.Invoke(() => Overlay.DisplayText(a.Sentence.Aggregate((acc, cur) => $"{acc} '{cur}'")));
                }
            };

            speech.FullSentenceMatch += (s, a) => {
                if(settings.EnableSpeech) {
                    Application.Current.Dispatcher.Invoke(() => Overlay.DisplayText($"- {a.Sentence.Aggregate((acc, cur) => $"{acc} {cur}")} -"));
                }
            };

            player.SongChanged += (s, a) => {
                if(player?.CurrentSong != null) {
                    Application.Current.Dispatcher.Invoke(() => Overlay.DisplayText($"{player.CurrentSong.Title} - {player.CurrentSong.Artist}"));
                }
            };

            speech.Commands.Add(new SpeechCommand() {
                KeyWords = new List<IEnumerable<string>>() { new string[] { "current song" } },
                Description = "Current song : Display current song name",
                Execute = (sentence) => {
                    var s = player.CurrentSong;
                    Overlay.DisplayText($"{s.Title} - {s.Artist} ({s.Album})", 5000);
                    return new string[0];
                },
                CanExecute = () => speech.Settings.EnableSpeech && player.CurrentSong != null
            });
        }