public ScreenOverlay(AppSettings settings)
        {
            InitializeComponent();
            Settings = settings;

            SetupSize();
            DataContext = new ScreenOverlayViewModel();
        }
        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 AppSettingsViewModel(AppSettings settings)
        {
            Settings = settings;
            Settings.Changed += Settings_Changed;
            LoadPaths = new ObservableCollection<ExplorerItem>();

            InitLoadPaths();

            SaveToDiskCommand = new AsyncCommand(
                (o) => Settings.WriteToDisc(),
                (o) => Settings.HasUnsavedChanges,
                (t) => {
                    if(t.IsFaulted)
                        Application.Current.Dispatcher.Invoke(() => new ExceptionWindow(t.Exception).Show());
                });
            Settings.Changed += (s, a) => ((AsyncCommand)SaveToDiskCommand).RaiseCanExecuteChanged();

            OpenFileLocationCommand = new RelayCommand(o => System.Diagnostics.Process.Start("explorer.exe", $"/select, {Settings.FullFilePath}"));
        }
        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 InitSettings() {
            if(!File.Exists(AppSettingsFileName)) {
                var set = new AppSettings(AppSettingsFileName);
                set.WriteToDisc();
            }

            ApplicationSettings = SettingsFile.ReadSettingFile<AppSettings>(AppSettingsFileName);

            ApplicationSettings.Changed += (sender, args) => {
                if(args.ChangedPropertyName == nameof(AppSettings.Volume)) {
                    SongPlayer.Volume = ((AppSettings)sender).Volume;
                }
            };
        }
        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
            });
        }