<commit_before>﻿using Crystal3;
using Neptunium.Media;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Windows.Devices.Bluetooth;
using Windows.Devices.Enumeration;
using Windows.Media.SpeechSynthesis;
using Windows.Storage;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;

namespace Neptunium.Managers
{
    public static class CarModeManager
    {
        public const string SelectedCarDevice = "SelectedCarDevice";
        public const string CarModeAnnounceSongs = "CarModeAnnounceSongs";

        public static bool IsInitialized { get; private set; }

        public static bool IsInCarMode { get; private set; }

        public static ReadOnlyObservableCollection<DeviceInformation> DetectedBluetoothDevices { get; private set; }
        public static DeviceInformation SelectedDevice { get; private set; }
        public static bool ShouldAnnounceSongs { get; private set; }

        private static DeviceWatcher watcher = null;
        private static ObservableCollection<DeviceInformation> detectedDevices = new ObservableCollection<DeviceInformation>();
        private static SpeechSynthesizer speechSynth = new SpeechSynthesizer();
        private static VoiceInformation japaneseFemaleVoice = null;

        public static async void Initialize()
        {
            if (IsInitialized) return;

#if RELESE
            if (Crystal3.CrystalApplication.GetDevicePlatform() != Crystal3.Core.Platform.Mobile) return;
#endif

            //creates a AQS filter string for watching for PAIRED bluetooth devices.
            var selector = BluetoothDevice.GetDeviceSelectorFromPairingState(true);
            //creates a device watcher which will detect paired bluetooth devices and watches their connection status,
            watcher = DeviceInformation.CreateWatcher(selector, new List<string> { "System.Devices.Aep.IsConnected" }, DeviceInformationKind.Device);

            watcher.Added += Watcher_Added;
            watcher.Removed += Watcher_Removed;
            watcher.EnumerationCompleted += Watcher_EnumerationCompleted;
            watcher.Updated += Watcher_Updated;

            DetectedBluetoothDevices = new ReadOnlyObservableCollection<DeviceInformation>(detectedDevices);

            //Pull the selected bluetooth device from settings if it exists
            if (ApplicationData.Current.LocalSettings.Values.ContainsKey(SelectedCarDevice))
            {
                var deviceID = ApplicationData.Current.LocalSettings.Values[SelectedCarDevice] as string;

                if (!string.IsNullOrWhiteSpace(deviceID))
                    SelectedDevice = await DeviceInformation.CreateFromIdAsync(deviceID);
            }
            //Create a settings entry for the selected bluetooth device if it doesn't exist
            if (!ApplicationData.Current.LocalSettings.Values.ContainsKey(CarModeAnnounceSongs))
                ApplicationData.Current.LocalSettings.Values.Add(CarModeAnnounceSongs, false);

            ShouldAnnounceSongs = (bool)ApplicationData.Current.LocalSettings.Values[CarModeAnnounceSongs];

            StationMediaPlayer.MetadataChanged += StationMediaPlayer_MetadataChanged;

            japaneseFemaleVoice = SpeechSynthesizer.AllVoices.FirstOrDefault(x => 
                x.Language.ToLower().StartsWith("ja") && x.Gender == VoiceGender.Female);


            watcher.Start();

            IsInitialized = true;
        }

        private static async void StationMediaPlayer_MetadataChanged(object sender, MediaSourceStream.ShoutcastMediaSourceStreamMetadataChangedEventArgs e)
        {
            if (ShouldAnnounceSongs && IsInCarMode)
            {
                double initialVolume = StationMediaPlayer.Volume;
                await FadeVolumeDownToAsync(.1); //lower the volume of the song so that the announcement can be heard.

                if (japaneseFemaleVoice != null)
                    speechSynth.Voice = japaneseFemaleVoice;

                var nowPlayingSpeech = string.Format(GetRandomNowPlayingText(), e.Artist, e.Title);
                var stream = await speechSynth.SynthesizeTextToStreamAsync(nowPlayingSpeech);<commit_msg>Car Mode should auto activate when you launch the app and the bluetooth device is already connected. /should/. Its untested.<commit_after>﻿using Crystal3;
using Neptunium.Media;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Windows.Devices.Bluetooth;
using Windows.Devices.Enumeration;
using Windows.Media.SpeechSynthesis;
using Windows.Storage;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;

namespace Neptunium.Managers
{
    public static class CarModeManager
    {
        public const string SelectedCarDevice = "SelectedCarDevice";
        public const string CarModeAnnounceSongs = "CarModeAnnounceSongs";

        public static bool IsInitialized { get; private set; }

        public static bool IsInCarMode { get; private set; }

        public static ReadOnlyObservableCollection<DeviceInformation> DetectedBluetoothDevices { get; private set; }
        public static DeviceInformation SelectedDevice { get; private set; }
        public static bool ShouldAnnounceSongs { get; private set; }

        private static DeviceWatcher watcher = null;
        private static ObservableCollection<DeviceInformation> detectedDevices = new ObservableCollection<DeviceInformation>();
        private static SpeechSynthesizer speechSynth = new SpeechSynthesizer();
        private static VoiceInformation japaneseFemaleVoice = null;

        public static async void Initialize()
        {
            if (IsInitialized) return;

#if RELESE
            if (Crystal3.CrystalApplication.GetDevicePlatform() != Crystal3.Core.Platform.Mobile) return;
#endif

            //creates a AQS filter string for watching for PAIRED bluetooth devices.
            var selector = BluetoothDevice.GetDeviceSelectorFromPairingState(true);
            //creates a device watcher which will detect paired bluetooth devices and watches their connection status,
            watcher = DeviceInformation.CreateWatcher(selector, new List<string> { "System.Devices.Aep.IsConnected" }, DeviceInformationKind.Device);

            watcher.Added += Watcher_Added;
            watcher.Removed += Watcher_Removed;
            watcher.EnumerationCompleted += Watcher_EnumerationCompleted;
            watcher.Updated += Watcher_Updated;

            DetectedBluetoothDevices = new ReadOnlyObservableCollection<DeviceInformation>(detectedDevices);

            //Pull the selected bluetooth device from settings if it exists
            if (ApplicationData.Current.LocalSettings.Values.ContainsKey(SelectedCarDevice))
            {
                var deviceID = ApplicationData.Current.LocalSettings.Values[SelectedCarDevice] as string;

                if (!string.IsNullOrWhiteSpace(deviceID))
                {
                    SelectedDevice = await DeviceInformation.CreateFromIdAsync(deviceID, new List<string> { "System.Devices.Aep.IsConnected" }, DeviceInformationKind.Device);

                    if (SelectedDevice != null)
                    {
                        try
                        {
                            bool isConnected = (bool)SelectedDevice.Properties.FirstOrDefault(p => p.Key == "System.Devices.Aep.IsConnected").Value;
                            SetCarModeStatus(isConnected);
                        }
                        catch (Exception) { }
                    }
                }
            }
            //Create a settings entry for the selected bluetooth device if it doesn't exist
            if (!ApplicationData.Current.LocalSettings.Values.ContainsKey(CarModeAnnounceSongs))
                ApplicationData.Current.LocalSettings.Values.Add(CarModeAnnounceSongs, false);

            ShouldAnnounceSongs = (bool)ApplicationData.Current.LocalSettings.Values[CarModeAnnounceSongs];

            StationMediaPlayer.MetadataChanged += StationMediaPlayer_MetadataChanged;

            japaneseFemaleVoice = SpeechSynthesizer.AllVoices.FirstOrDefault(x => 
                x.Language.ToLower().StartsWith("ja") && x.Gender == VoiceGender.Female);


            watcher.Start();

            IsInitialized = true;
        }

        private static async void StationMediaPlayer_MetadataChanged(object sender, MediaSourceStream.ShoutcastMediaSourceStreamMetadataChangedEventArgs e)
        {
            if (ShouldAnnounceSongs && IsInCarMode)
            {
                double initialVolume = StationMediaPlayer.Volume;
                await FadeVolumeDownToAsync(.1); //lower the volume of the song so that the announcement can be heard.

                if (japaneseFemaleVoice != null)
                    speechSynth.Voice = japaneseFemaleVoice;

                var nowPlayingSpeech = string.Format(GetRandomNowPlayingText(), e.Artist, e.Title);
                var stream = await speechSynth.SynthesizeTextToStreamAsync(nowPlayingSpeech);
{'fraction_non_alphanumeric': 0.07020041616471362, 'fraction_numerical': 0.0008761362391851933, 'mean_word_length': 2.884304551254785, 'pattern_counts': {'":': 0, '<': 14, '<?xml version=': 0, '>': 17, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '513796', 'n_tokens_mistral': 2304, 'n_tokens_neox': 2145, 'n_words': 546}