<commit_before>﻿using Neptunium.Data;
using Neptunium.MediaSourceStream;
using Neptunium.Shared;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Windows.Foundation;
using Windows.Foundation.Collections;
using Windows.Media.Playback;
using Windows.Media;
using System.Diagnostics;
using System.Threading;
using Windows.Web.Http;
using Windows.Storage.Streams;

namespace Neptunium.Media
{
    public static class StationMediaPlayer
    {
        private static ShoutcastMediaSourceStream currentStationMSSWrapper = null;
        private static string currentTrack = "Title";
        private static string currentArtist = "Artist";
        private static StationModelStreamServerType currentStationServerType;

        private static StationModel currentStationModel = null;
        private static SystemMediaTransportControls smtc;

        private static SemaphoreSlim playStationResetEvent = new SemaphoreSlim(1);


        public static bool IsInitialized { get; private set; }

        public static async Task InitializeAsync()
        {
            if (IsInitialized) return;

            // BackgroundMediaPlayer.Current.

            smtc = BackgroundMediaPlayer.Current.SystemMediaTransportControls;
            smtc.ButtonPressed += Smtc_ButtonPressed;
            smtc.PropertyChanged += Smtc_PropertyChanged;


            smtc.IsChannelDownEnabled = false;
            smtc.IsChannelUpEnabled = false;
            smtc.IsFastForwardEnabled = false;
            smtc.IsNextEnabled = false;
            smtc.IsPauseEnabled = true;
            smtc.IsPlayEnabled = true;
            smtc.IsPreviousEnabled = false;
            smtc.IsRecordEnabled = false;
            smtc.IsRewindEnabled = false;
            smtc.IsStopEnabled = false;

            IsInitialized = true;

            await Task.CompletedTask;
        }

        public static void Deinitialize()
        {
            if (!IsInitialized) return;

            smtc.ButtonPressed -= Smtc_ButtonPressed;
            smtc.PropertyChanged -= Smtc_PropertyChanged;

            IsInitialized = false;
        }

        private static void Smtc_PropertyChanged(SystemMediaTransportControls sender, SystemMediaTransportControlsPropertyChangedEventArgs args)
        {
            switch (args.Property)
            {
                case SystemMediaTransportControlsProperty.SoundLevel:
                    break;
            }
        }

        private static void Smtc_ButtonPressed(SystemMediaTransportControls sender, SystemMediaTransportControlsButtonPressedEventArgs args)
        {
            switch (args.Button)
            {
                case SystemMediaTransportControlsButton.Play:
                    Debug.WriteLine("UVC play button pressed");
                    try
                    {
                        BackgroundMediaPlayer.Current.Play();
                    }
                    catch (Exception ex)
                    {
                        Debug.WriteLine(ex.ToString());
                    }
                    break;
                case SystemMediaTransportControlsButton.Pause:
                    Debug.WriteLine("UVC pause button pressed");
                    try
                    {
                        BackgroundMediaPlayer.Current.Pause();
                    }
                    catch (Exception ex)
                    {
                        Debug.WriteLine(ex.ToString());
                    }
                    break;
                case SystemMediaTransportControlsButton.Next:
                    Debug.WriteLine("UVC next button pressed");

                    break;
                case SystemMediaTransportControlsButton.Previous:
                    Debug.WriteLine("UVC previous button pressed");

                    break;
            }
        }

        public static ShoutcastSongInfo SongMetadata { get; private set; }

        public static StationModel CurrentStation { get { return currentStationModel; } }

        public static bool IsPlaying
        {
            get
            {
                var state = BackgroundMediaPlayer.Current.PlaybackSession.PlaybackState;

                return state == MediaPlaybackState.Opening || state == MediaPlaybackState.Playing || state == MediaPlaybackState.Buffering;
            }
        }

        //public static ShoutcastStationInfo StationInfoFromStream { get { return currentStationMSSWrapper?.StationInfo; } }

        public static async Task<bool> PlayStationAsync(StationModel station)
        {
            if (station == currentStationModel && IsPlaying) return true;

            await playStationResetEvent.WaitAsync();

            ShoutcastMediaSourceStream lastStream = null;

            if (IsPlaying)
            {
                if (currentStationMSSWrapper != null && (currentStationServerType == StationModelStreamServerType.Shoutcast || currentStationServerType == StationModelStreamServerType.Icecast))
                {
                    currentStationMSSWrapper.MetadataChanged -= CurrentStationMSSWrapper_MetadataChanged;

                    if (currentStationMSSWrapper.MediaStreamSource != null)
                        currentStationMSSWrapper.MediaStreamSource.Closed -= MediaStreamSource_Closed;

                    BackgroundMediaPlayer.Current.Pause();
                }
            }

            if (ConnectingStatusChanged != null)
                ConnectingStatusChanged(null, new StationMediaPlayerConnectingStatusChangedEventArgs(true));

            currentStationModel = station;

            //TODO use a combo of events+anon-delegates and TaskCompletionSource to detect play back errors here to seperate connection errors from long-running audio errors.
            //handle error when connecting.

            var stream = station.Streams.First();

            currentStationServerType = stream.ServerType;

            if (currentStationServerType == StationModelStreamServerType.Direct)
            {
                try
                {
                    BackgroundMediaPlayer.Current.SetUriSource(new Uri(stream.Url));

                    BackgroundMediaPlayer.Current.Play();

                    currentTrack = "Unknown Song";
                    currentArtist = "Unknown Artist";

                    UpdateNowPlaying(currentTrack, currentArtist);

                    return true;
                }
                catch (Exception)
                {
                    return false;
                }
            }
            else if ((currentStationServerType == StationModelStreamServerType.Shoutcast || currentStationServerType == StationModelStreamServerType.Icecast))
            {
                currentStationMSSWrapper = new ShoutcastMediaSourceStream(new Uri(stream.Url));

                currentStationMSSWrapper.MetadataChanged += CurrentStationMSSWrapper_MetadataChanged;


                try
                {
                    if (await currentStationMSSWrapper.ConnectAsync(stream.SampleRate, stream.RelativePath) != null)
                    {
                        BackgroundMediaPlayer.Current.SetMediaSource(currentStationMSSWrapper.MediaStreamSource);

                        BackgroundMediaPlayer.Current.Play();

                        currentStationMSSWrapper.MediaStreamSource.Closed += MediaStreamSource_Closed;

                        currentTrack = "Unknown Song";
                        currentArtist = "Unknown Artist";<commit_msg>Suppressed a warning. No workaround as of yet.<commit_after>﻿using Neptunium.Data;
using Neptunium.MediaSourceStream;
using Neptunium.Shared;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Windows.Foundation;
using Windows.Foundation.Collections;
using Windows.Media.Playback;
using Windows.Media;
using System.Diagnostics;
using System.Threading;
using Windows.Web.Http;
using Windows.Storage.Streams;

namespace Neptunium.Media
{
    public static class StationMediaPlayer
    {
        private static ShoutcastMediaSourceStream currentStationMSSWrapper = null;
        private static string currentTrack = "Title";
        private static string currentArtist = "Artist";
        private static StationModelStreamServerType currentStationServerType;

        private static StationModel currentStationModel = null;
        private static SystemMediaTransportControls smtc;

        private static SemaphoreSlim playStationResetEvent = new SemaphoreSlim(1);


        public static bool IsInitialized { get; private set; }

        public static async Task InitializeAsync()
        {
            if (IsInitialized) return;

            // BackgroundMediaPlayer.Current.

            smtc = BackgroundMediaPlayer.Current.SystemMediaTransportControls;
            smtc.ButtonPressed += Smtc_ButtonPressed;
            smtc.PropertyChanged += Smtc_PropertyChanged;


            smtc.IsChannelDownEnabled = false;
            smtc.IsChannelUpEnabled = false;
            smtc.IsFastForwardEnabled = false;
            smtc.IsNextEnabled = false;
            smtc.IsPauseEnabled = true;
            smtc.IsPlayEnabled = true;
            smtc.IsPreviousEnabled = false;
            smtc.IsRecordEnabled = false;
            smtc.IsRewindEnabled = false;
            smtc.IsStopEnabled = false;

            IsInitialized = true;

            await Task.CompletedTask;
        }

        public static void Deinitialize()
        {
            if (!IsInitialized) return;

            smtc.ButtonPressed -= Smtc_ButtonPressed;
            smtc.PropertyChanged -= Smtc_PropertyChanged;

            IsInitialized = false;
        }

        private static void Smtc_PropertyChanged(SystemMediaTransportControls sender, SystemMediaTransportControlsPropertyChangedEventArgs args)
        {
            switch (args.Property)
            {
                case SystemMediaTransportControlsProperty.SoundLevel:
                    break;
            }
        }

        private static void Smtc_ButtonPressed(SystemMediaTransportControls sender, SystemMediaTransportControlsButtonPressedEventArgs args)
        {
            switch (args.Button)
            {
                case SystemMediaTransportControlsButton.Play:
                    Debug.WriteLine("UVC play button pressed");
                    try
                    {
                        BackgroundMediaPlayer.Current.Play();
                    }
                    catch (Exception ex)
                    {
                        Debug.WriteLine(ex.ToString());
                    }
                    break;
                case SystemMediaTransportControlsButton.Pause:
                    Debug.WriteLine("UVC pause button pressed");
                    try
                    {
                        BackgroundMediaPlayer.Current.Pause();
                    }
                    catch (Exception ex)
                    {
                        Debug.WriteLine(ex.ToString());
                    }
                    break;
                case SystemMediaTransportControlsButton.Next:
                    Debug.WriteLine("UVC next button pressed");

                    break;
                case SystemMediaTransportControlsButton.Previous:
                    Debug.WriteLine("UVC previous button pressed");

                    break;
            }
        }

        public static ShoutcastSongInfo SongMetadata { get; private set; }

        public static StationModel CurrentStation { get { return currentStationModel; } }

        public static bool IsPlaying
        {
            get
            {
                var state = BackgroundMediaPlayer.Current.PlaybackSession.PlaybackState;

                return state == MediaPlaybackState.Opening || state == MediaPlaybackState.Playing || state == MediaPlaybackState.Buffering;
            }
        }

        //public static ShoutcastStationInfo StationInfoFromStream { get { return currentStationMSSWrapper?.StationInfo; } }

        public static async Task<bool> PlayStationAsync(StationModel station)
        {
            if (station == currentStationModel && IsPlaying) return true;

            await playStationResetEvent.WaitAsync();

            ShoutcastMediaSourceStream lastStream = null;

            if (IsPlaying)
            {
                if (currentStationMSSWrapper != null && (currentStationServerType == StationModelStreamServerType.Shoutcast || currentStationServerType == StationModelStreamServerType.Icecast))
                {
                    currentStationMSSWrapper.MetadataChanged -= CurrentStationMSSWrapper_MetadataChanged;

                    if (currentStationMSSWrapper.MediaStreamSource != null)
                        currentStationMSSWrapper.MediaStreamSource.Closed -= MediaStreamSource_Closed;

                    BackgroundMediaPlayer.Current.Pause();
                }
            }

            if (ConnectingStatusChanged != null)
                ConnectingStatusChanged(null, new StationMediaPlayerConnectingStatusChangedEventArgs(true));

            currentStationModel = station;

            //TODO use a combo of events+anon-delegates and TaskCompletionSource to detect play back errors here to seperate connection errors from long-running audio errors.
            //handle error when connecting.

            var stream = station.Streams.First();

            currentStationServerType = stream.ServerType;

            if (currentStationServerType == StationModelStreamServerType.Direct)
            {
                try
                {
                    BackgroundMediaPlayer.Current.SetUriSource(new Uri(stream.Url));

                    BackgroundMediaPlayer.Current.Play();

                    currentTrack = "Unknown Song";
                    currentArtist = "Unknown Artist";

                    UpdateNowPlaying(currentTrack, currentArtist);

                    return true;
                }
                catch (Exception)
                {
                    return false;
                }
            }
            else if ((currentStationServerType == StationModelStreamServerType.Shoutcast || currentStationServerType == StationModelStreamServerType.Icecast))
            {
                currentStationMSSWrapper = new ShoutcastMediaSourceStream(new Uri(stream.Url));

                currentStationMSSWrapper.MetadataChanged += CurrentStationMSSWrapper_MetadataChanged;


                try
                {
                    if (await currentStationMSSWrapper.ConnectAsync(stream.SampleRate, stream.RelativePath) != null)
                    {
#pragma warning disable CS0618 // Type or member is obsolete
                        BackgroundMediaPlayer.Current.SetMediaSource(currentStationMSSWrapper.MediaStreamSource);
#pragma warning restore CS0618 // Type or member is obsolete

                        BackgroundMediaPlayer.Current.Play();

                        currentStationMSSWrapper.MediaStreamSource.Closed += MediaStreamSource_Closed;

                        currentTrack = "Unknown Song";
                        currentArtist = "Unknown Artist";
{'fraction_non_alphanumeric': 0.06187059830184954, 'fraction_numerical': 0.000658197854274995, 'mean_word_length': 1.8485189351331084, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 5, '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': '920772', 'n_tokens_mistral': 3459, 'n_tokens_neox': 3211, 'n_words': 724}