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 SpeechController(SongPlayer player, Playlist playlist, AppSettings settings)
        {
            Player = player;
            Playlist = playlist;
            Settings = settings;

            LastInputTime = Environment.TickCount;
            Sentence = new List<string>();
        }
        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 TransitionManager(SongPlayer player, Playlist trackList, AppSettings settings)
        {
            Player = player;
            TrackList = trackList;
            Settings = settings;

            if(Player != null && Player.CurrentSong == null) {
                Player.CurrentSong = TrackList?.CurrentSong;
            }

            Init();
        }
        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 SmallPlayerViewModel(AppSettings settings, SongPlayer player, Playlist playlist)
        {
            Settings = settings;
            SongPlayer = player;
            Playlist = playlist;

            SetupCommands();

            SongPlayer.SongChanged += (s, a) => RaisePropertiesChanged(nameof(ElapsedFraction), nameof(ElapsedStr));
            SongPlayer.PlayingStopped += Player_PlayingStopped;
            SongPlayer.PlaybackStateChanged += PlaybackStateChanged;
            Settings.Changed += Settings_Changed;

            UpdateTimer = new Timer() {
                AutoReset = true,
                Enabled = true,
                Interval = 1000
            };
            UpdateTimer.Elapsed += (s, a) => RaisePropertiesChanged(nameof(ElapsedStr), nameof(ElapsedFraction));
        }
        private void SetupContextMenu(SongPlayer player)
        {
            var tivm = new TrayIconViewModel() {
                SmallPlayer = new RelayCommand((o) => ShowSmallWindow()),
                FullPlayer = new RelayCommand((o) => ShowFullWindow()),
                Quit = new RelayCommand((o) => Application.Current.Shutdown())
            };

            player.SongChanged += (s, a) => {
                tivm.ToolTipText = player?.CurrentSong?.Title;
            };

            TrayIcon.DataContext = tivm;

            TrayIcon.TrayMouseDoubleClick += (s, a) => ShowFullWindow();
            TrayIcon.TrayLeftMouseUp += (s, a) => {
                if(!(Full?.IsVisible ?? false)) {
                    ShowSmallWindow();
                } else if(Full?.IsVisible ?? false) {
                    ShowFullWindow();
                }
            };
        }
        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
            });
        }