// Decompiled with JetBrains decompiler
// Type: ZuneUI.NowPlayingList
// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217
// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264
// Assembly location: C:\Program Files\Zune\ZuneShell.dll

using Microsoft.Iris;
using Microsoft.Zune.Configuration;
using Microsoft.Zune.Playlist;
using Microsoft.Zune.QuickMix;
using Microsoft.Zune.Shell;
using Microsoft.Zune.Util;
using MicrosoftZuneLibrary;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Runtime.Serialization;
using UIXControls;
using ZuneXml;

namespace ZuneUI
{
    [Serializable]
    internal class NowPlayingList : IDisposable
    {
        private const int s_quickMixCreationTimeoutMilliseconds = 15000;
        private const int s_nearingCompletionThreshold = 3;
        [NonSerialized]
        private ArrayListDataSet _tracks;
        private List<PlaybackTrack> _savedTracks;
        private int[] _shuffleOrder;
        private bool _shuffling;
        private bool _repeating;
        private int _indexShuffleStart;
        private PlaybackContext _playbackContext;
        private int _currentRandomSeed;
        private PlayNavigationOptions _playNavigationOptions;
        private bool _dontPlayMarketplaceTracks;
        private bool _playWhenReady;
        private EQuickMixType _quickMixType = EQuickMixType.eQuickMixTypeInvalid;
        private string _quickMixTitle;
        [NonSerialized]
        private int _transientTracksPlaylistId;
        [NonSerialized]
        private static int _transientPlaylistCount;
        [NonSerialized]
        private PlaybackTrack _trackCurrent;
        [NonSerialized]
        private PlaybackTrack _trackNext;
        private int _indexCurrent;
        [NonSerialized]
        private QuickMixSession _quickMixSession;
        [NonSerialized]
        private QuickMixNotification _quickMixCreatingNotification;
        [NonSerialized]
        private StringId _quickMixNoResultsStringId;
        private static Random s_random = new Random();

        public NowPlayingList(
          IList items,
          int startIndex,
          PlaybackContext context,
          PlayNavigationOptions playNavigationOptions,
          bool shuffling,
          ContainerPlayMarker containerPlayMarker,
          bool dontPlayMarketplaceTracks)
        {
            this._transientTracksPlaylistId = int.MinValue;
            this._playbackContext = context;
            this._playNavigationOptions = playNavigationOptions;
            this._dontPlayMarketplaceTracks = dontPlayMarketplaceTracks;
            if (this._playbackContext == PlaybackContext.QuickMix)
                this.AddQuickMixItemsWorker(items);
            else
                this.AddItemsWorker(items, startIndex, shuffling, containerPlayMarker);
        }

        public void Dispose()
        {
            if (this._quickMixSession != null)
            {
                this._quickMixSession.Dispose();
                this._quickMixSession = null;
            }
            this.CleanupTransientTracks();
        }

        private void CleanupTransientTracks()
        {
            if (this._transientTracksPlaylistId == int.MinValue)
                return;
            ZuneApplication.ZuneLibrary.DeleteMedia(new int[1]
            {
        this._transientTracksPlaylistId
            }, EMediaTypes.eMediaTypePlaylist, false);
            this._transientTracksPlaylistId = int.MinValue;
        }

        private void AddQuickMixItemsWorker(IList items)
        {
            QuickMix instance = QuickMix.Instance;
            HRESULT hresult = HRESULT._S_OK;
            EMediaTypes eMediaType = EMediaTypes.eMediaTypeInvalid;
            this._quickMixNoResultsStringId = StringId.IDS_QUICKMIX_ITEM_CREATION_UNAVAILABLE_TEXT;
            if (this._quickMixSession != null)
            {
                this._quickMixSession.Dispose();
                this._quickMixSession = null;
            }
            NotificationArea.Instance.RemoveAll(NotificationTask.QuickMix, NotificationState.OneShot);
            if (items[0] is Artist artist)
            {
                this._quickMixNoResultsStringId = StringId.IDS_QUICKMIX_ARTIST_CREATION_UNAVAILABLE_TEXT;
                hresult = instance.CreateSession(EQuickMixMode.eQuickMixModeNowPlaying, artist.Id, EMediaTypes.eMediaTypePersonArtist, artist.Title, out this._quickMixSession);
                if (hresult.IsSuccess)
                {
                    string text = string.Format(Shell.LoadString(StringId.IDS_QUICKMIX_NOTIFICATION_CREATION_BUSY_ONE_PARAM_TEXT), artist.Title);
                    this._quickMixCreatingNotification = new QuickMixNotification(Shell.LoadString(StringId.IDS_QUICKMIX_NOTIFICATION_CREATION_BUSY_TITLE), text, NotificationState.OneShot, false, 15000);
                    SQMLog.Log(SQMDataId.QuickMixRadioPlays, 1);
                }
            }
            if (hresult.IsSuccess && items[0] is LibraryDataProviderItemBase providerItemBase)
            {
                if (providerItemBase.TypeName == "Artist")
                {
                    eMediaType = EMediaTypes.eMediaTypePersonArtist;
                    this._quickMixNoResultsStringId = StringId.IDS_QUICKMIX_ARTIST_CREATION_UNAVAILABLE_TEXT;
                    string property = (string)providerItemBase.GetProperty("Title");
                    string text = string.Format(Shell.LoadString(StringId.IDS_QUICKMIX_NOTIFICATION_CREATION_BUSY_ONE_PARAM_TEXT), property);
                    this._quickMixCreatingNotification = new QuickMixNotification(Shell.LoadString(StringId.IDS_QUICKMIX_NOTIFICATION_CREATION_BUSY_TITLE), text, NotificationState.OneShot, false, 15000);
                }
                else if (providerItemBase.TypeName == "Album")
                {
                    eMediaType = EMediaTypes.eMediaTypeAudioAlbum;
                    this._quickMixNoResultsStringId = StringId.IDS_QUICKMIX_ALBUM_CREATION_UNAVAILABLE_TEXT;
                    string property1 = (string)providerItemBase.GetProperty("ArtistName");
                    string property2 = (string)providerItemBase.GetProperty("Title");
                    string text = string.Format(Shell.LoadString(StringId.IDS_QUICKMIX_NOTIFICATION_CREATION_BUSY_TWO_PARAM_TEXT), property1, property2);
                    this._quickMixCreatingNotification = new QuickMixNotification(Shell.LoadString(StringId.IDS_QUICKMIX_NOTIFICATION_CREATION_BUSY_TITLE), text, NotificationState.OneShot, false, 15000);
                }
                else if (providerItemBase.TypeName == "Track")
                {
                    eMediaType = EMediaTypes.eMediaTypeAudio;
                    this._quickMixNoResultsStringId = StringId.IDS_QUICKMIX_SONG_CREATION_UNAVAILABLE_TEXT;
                    string property1 = (string)providerItemBase.GetProperty("ArtistName");
                    string property2 = (string)providerItemBase.GetProperty("Title");
                    string text = string.Format(Shell.LoadString(StringId.IDS_QUICKMIX_NOTIFICATION_CREATION_BUSY_TWO_PARAM_TEXT), property1, property2);
                    this._quickMixCreatingNotification = new QuickMixNotification(Shell.LoadString(StringId.IDS_QUICKMIX_NOTIFICATION_CREATION_BUSY_TITLE), text, NotificationState.OneShot, false, 15000);
                }
                int[] seedMediaIds = new int[1]
                {
          (int) providerItemBase.GetProperty("LibraryId")
                };
                hresult = instance.CreateSession(EQuickMixMode.eQuickMixModeNowPlaying, seedMediaIds, eMediaType, out this._quickMixSession);
                SQMLog.Log(SQMDataId.QuickMixLocalPlays, 1);
            }
            if (hresult.IsSuccess)
            {
                if (this._quickMixSession != null)
                {
                    hresult = this._quickMixSession.GetSimilarMedia((uint)ClientConfiguration.QuickMix.DefaultPlaylistLength, TimeSpan.FromMilliseconds(15000.0), new SimilarMediaBatchHandler(this.SimilarBatchHandler), new BatchEndHandler(this.BatchEndHandler));
                    this._quickMixType = this._quickMixSession.GetQuickMixType();
                    this._quickMixSession.GetPlaylistTitle(out this._quickMixTitle);
                }
                else
                    hresult = HRESULT._E_UNEXPECTED;
            }
            if (hresult.IsSuccess)
            {
                NotificationArea.Instance.Add(_quickMixCreatingNotification);
            }
            else
            {
                if (this._quickMixSession != null)
                {
                    this._quickMixSession.Dispose();
                    this._quickMixSession = null;
                }
                if (hresult.Int == HRESULT._ZUNE_E_QUICKMIX_MEDIA_NOT_FOUND)
                    MessageBox.Show(Shell.LoadString(StringId.IDS_QUICKMIX_CREATION_UNAVAILABLE_NO_RESULTS_TITLE), Shell.LoadString(this._quickMixNoResultsStringId), null);
                else
                    ErrorDialogInfo.Show(hresult.Int, Shell.LoadString(StringId.IDS_QUICKMIX_CREATION_UNAVAILABLE_NO_RESULTS_TITLE));
            }
        }

        private void SimilarBatchHandler(IList itemList) => Application.DeferredInvoke(delegate
       {
           if (this._quickMixSession == null)
               return;
           this.AddItems(itemList, new ContainerPlayMarker()
           {
               LibraryId = -1,
               MediaType = MediaType.Playlist,
               PlaylistType = PlaylistType.QuickMix,
               PlaylistSubType = (int)this._quickMixSession.GetQuickMixType()
           });
           if (!this.PlayWhenReady)
               return;
           this.PlayWhenReady = false;
           SingletonModelItem<TransportControls>.Instance.PlayPendingList();
       }, null);

        private void BatchEndHandler(HRESULT hrAsync) => Application.DeferredInvoke(delegate
       {
           NotificationArea.Instance.Remove(_quickMixCreatingNotification);
           this._quickMixCreatingNotification = null;
           if (this._quickMixSession == null || !hrAsync.IsError)
               return;
           if (hrAsync.Int == HRESULT._ZUNE_E_QUICKMIX_MEDIA_NOT_FOUND)
               MessageBox.Show(Shell.LoadString(StringId.IDS_QUICKMIX_CREATION_UNAVAILABLE_NO_RESULTS_TITLE), Shell.LoadString(this._quickMixNoResultsStringId), null);
           else
               ErrorDialogInfo.Show(hrAsync.Int, Shell.LoadString(StringId.IDS_QUICKMIX_CREATION_UNAVAILABLE_NO_RESULTS_TITLE));
       }, null);

        public ArrayListDataSet TrackList => this._tracks;

        public int Count => this._tracks == null ? 0 : this._tracks.Count;

        public PlaybackContext PlaybackContext => this._playbackContext;

        public PlayNavigationOptions PlayNavigationOptions
        {
            get => this._playNavigationOptions;
            set => this._playNavigationOptions = value;
        }

        public string QuickMixTitle
        {
            get
            {
                string playlistTitle = this._quickMixTitle;
                if (this._quickMixSession != null)
                    this._quickMixSession.GetPlaylistTitle(out playlistTitle);
                return playlistTitle;
            }
        }

        public bool DontPlayMarketplaceTracks
        {
            get => this._dontPlayMarketplaceTracks;
            set
            {
                if (value == this._dontPlayMarketplaceTracks)
                    return;
                this._dontPlayMarketplaceTracks = value;
                this.UpdateTracks();
            }
        }

        public bool PlayWhenReady
        {
            get => this._playWhenReady;
            set
            {
                if (value == this._playWhenReady)
                    return;
                this._playWhenReady = value;
            }
        }

        public QuickMixSession QuickMixSession => this._quickMixSession;

        public EQuickMixType QuickMixType => this._quickMixType;

        public PlaybackTrack CurrentTrack => this._trackCurrent;

        public PlaybackTrack NextTrack => this._trackNext;

        public int ListIndexOfCurrentTrack
        {
            get
            {
                int indexCurrent = this._indexCurrent;
                if (indexCurrent != -1 && this._shuffling)
                    indexCurrent = this._shuffleOrder[indexCurrent];
                return indexCurrent;
            }
        }

        public void SetShuffling(bool shuffling)
        {
            if (this._quickMixSession != null)
                return;
            if (this._tracks == null || this._tracks.Count == 0)
            {
                this._shuffling = shuffling;
            }
            else
            {
                if (shuffling == this._shuffling)
                    return;
                int index = !this._shuffling ? this._indexCurrent : this._shuffleOrder[this._indexCurrent];
                if (shuffling)
                    this.RebuildShuffleOrder();
                else
                    this._shuffleOrder = null;
                this._indexCurrent = !shuffling ? index : this.FindShuffleIndexFromListIndex(index);
                this._shuffling = shuffling;
                this.UpdateTracks();
            }
        }

        public void SetRepeating(bool repeating)
        {
            if (this._repeating == repeating)
                return;
            this._repeating = repeating;
            this.UpdateTracks();
        }

        public void SyncCurrentTrackTo(PlaybackTrack track)
        {
            if (track == this._trackCurrent)
                return;
            int num;
            if (track == this._trackNext)
            {
                num = this.ComputeNextIndex(MovingMode.Advancing);
            }
            else
            {
                num = this._tracks.IndexOf(track);
                if (num != -1 && this._shuffling)
                    num = this.FindShuffleIndexFromListIndex(num);
            }
            if (num == -1)
                return;
            this.MoveToWorker(num, MovingMode.Advancing);
        }

        public void MoveToTrackIndex(int indexNew)
        {
            if (this._shuffling)
                indexNew = this.FindShuffleIndexFromListIndex(indexNew);
            this.MoveToWorker(indexNew, MovingMode.Jumping);
        }

        public void Advance() => this.MoveToWorker(this.ComputeNextIndex(MovingMode.Advancing), MovingMode.Advancing);

        public bool CanAdvance => this._trackNext != null;

        public void Retreat()
        {
            if (this._shuffling && this._repeating && this._indexCurrent == this._indexShuffleStart)
                this.RebuildShuffleOrder(new int?(this._currentRandomSeed - 1));
            this.MoveToWorker(this.ComputeNextIndex(MovingMode.Retreating), MovingMode.Retreating);
        }

        public bool CanRetreat => this._repeating || (!this._shuffling ? this._indexCurrent > 0 : this._indexCurrent != this._indexShuffleStart);

        public int AddItems(IList items) => this.AddItems(items, null);

        public int AddItems(IList items, ContainerPlayMarker playMarker) => this.AddItemsWorker(items, -1, false, playMarker);

        public void ResetForReplay()
        {
            this._indexCurrent = !this._shuffling ? 0 : s_random.Next(this._tracks.Count);
            if (this._shuffling)
                this.RebuildShuffleOrder();
            this.UpdateTracks();
        }

        private void MoveToWorker(int indexNew, MovingMode mode)
        {
            this._indexCurrent = indexNew;
            if (this._shuffling)
            {
                if (mode == MovingMode.Advancing && indexNew == this._indexShuffleStart)
                    this.RebuildShuffleOrder(new int?(this._currentRandomSeed + 1));
                else if (mode == MovingMode.Jumping)
                    this.RebuildShuffleOrder();
            }
            this.UpdateTracks();
            if (!this.CanGetMoreQuickMixTracks() || !this.ListNearingCompletion())
                return;
            HRESULT similarMedia = this._quickMixSession.GetSimilarMedia((uint)ClientConfiguration.QuickMix.DefaultPlaylistLength, TimeSpan.FromMilliseconds(15000.0), new SimilarMediaBatchHandler(this.SimilarBatchHandler), new BatchEndHandler(this.BatchEndHandler));
            if (!similarMedia.IsError || similarMedia.Int == HRESULT._ZUNE_E_QUICKMIX_SESSION_IN_USE)
                return;
            ErrorDialogInfo.Show(similarMedia.Int, Shell.LoadString(StringId.IDS_QUICKMIX_CREATION_UNAVAILABLE_NO_RESULTS_TITLE));
        }

        private bool CanGetMoreQuickMixTracks()
        {
            bool flag = false;
            if (this._quickMixSession != null)
                flag = this._quickMixSession.GetQuickMixType() != EQuickMixType.eQuickMixTypeRadio || SignIn.Instance.SignedIn;
            return flag;
        }

        private int ComputeNextIndex(MovingMode mode) => this.ComputeNextIndex(mode, this._indexCurrent, true);

        private int ComputeNextIndex(MovingMode mode, int fromIndex, bool allowLooping)
        {
            if (mode != MovingMode.Advancing && mode != MovingMode.Retreating)
                return fromIndex;
            int index1;
            if (!this._dontPlayMarketplaceTracks)
            {
                index1 = this.ComputeNextIndexUnfiltered(mode, fromIndex, allowLooping);
            }
            else
            {
                index1 = fromIndex;
                bool flag = false;
                for (int index2 = 0; index2 < this._tracks.Count; ++index2)
                {
                    index1 = this.ComputeNextIndexUnfiltered(mode, index1, allowLooping);
                    if (index1 != -1)
                    {
                        PlaybackTrack playbackTrack = !this._shuffling ? this._tracks[index1] as PlaybackTrack : this._tracks[this._shuffleOrder[index1]] as PlaybackTrack;
                        if (playbackTrack != null && playbackTrack.IsInVisibleCollection)
                        {
                            flag = true;
                            break;
                        }
                    }
                    else
                        break;
                }
                if (!flag)
                    index1 = -1;
            }
            return index1;
        }

        private int ComputeNextIndexUnfiltered(
          MovingMode mode,
          int indexCurrent,
          bool allowLooping)
        {
            int num = mode != MovingMode.Advancing ? indexCurrent - 1 : indexCurrent + 1;
            if (this._shuffling)
            {
                if (num == this._tracks.Count)
                    num = 0;
                else if (num == -1)
                    num = this._tracks.Count - 1;
                if ((mode == MovingMode.Advancing && num == this._indexShuffleStart || mode == MovingMode.Retreating && num == this._indexShuffleStart - 1) && (!this._repeating || !allowLooping))
                    num = -1;
            }
            else if (num == this._tracks.Count)
                num = !this._repeating || !allowLooping ? -1 : 0;
            else if (num == -1)
                num = !this._repeating || !allowLooping ? -1 : this._tracks.Count - 1;
            return num;
        }

        private bool ListNearingCompletion()
        {
            if (this._tracks.Count == 0)
                return false;
            int fromIndex = this._indexCurrent;
            int count = this._tracks.Count;
            bool flag = false;
            for (int index = 0; index < 3; ++index)
            {
                fromIndex = this.ComputeNextIndex(MovingMode.Advancing, fromIndex, false);
                if (fromIndex == -1)
                {
                    flag = true;
                    break;
                }
            }
            int num = flag ? 1 : 0;
            return flag;
        }

        internal void UpdateTracks()
        {
            object obj1 = null;
            object obj2 = null;
            if (this._tracks != null && this._indexCurrent != -1)
            {
                obj1 = this._tracks[this._shuffling ? this._shuffleOrder[this._indexCurrent] : this._indexCurrent];
                int nextIndex = this.ComputeNextIndex(MovingMode.Advancing);
                if (nextIndex != -1)
                {
                    if (this._shuffling)
                        nextIndex = this._shuffleOrder[nextIndex];
                    obj2 = this._tracks[nextIndex];
                }
            }
            this._trackCurrent = (PlaybackTrack)obj1;
            this._trackNext = (PlaybackTrack)obj2;
        }

        private int FindShuffleIndexFromListIndex(int index)
        {
            int num = -1;
            for (int index1 = 0; index1 < this._tracks.Count; ++index1)
            {
                if (this._shuffleOrder[index1] == index)
                {
                    num = index1;
                    break;
                }
            }
            return num;
        }

        private void RebuildShuffleOrder(int? seed)
        {
            int index1 = !this._shuffling ? this._indexCurrent : this._shuffleOrder[this._indexCurrent];
            if (this._tracks == null)
            {
                this._shuffleOrder = null;
            }
            else
            {
                if (this._shuffleOrder == null || this._shuffleOrder.Length != this._tracks.Count)
                    this._shuffleOrder = new int[this._tracks.Count];
                for (int index2 = 0; index2 < this._tracks.Count; ++index2)
                    this._shuffleOrder[index2] = index2;
                this._currentRandomSeed = !seed.HasValue ? (int)DateTime.Now.Ticks : seed.Value;
                Random random = new Random(this._currentRandomSeed);
                for (int index2 = this._tracks.Count - 1; index2 > 0; --index2)
                {
                    int index3 = random.Next(index2 + 1);
                    int num = this._shuffleOrder[index3];
                    this._shuffleOrder[index3] = this._shuffleOrder[index2];
                    this._shuffleOrder[index2] = num;
                }
            }
            this._indexShuffleStart = this.FindShuffleIndexFromListIndex(index1);
            if (!this._shuffling)
                return;
            this._indexCurrent = this._indexShuffleStart;
        }

        private void RebuildShuffleOrder() => this.RebuildShuffleOrder(new int?());

        private int AddItemsWorker(
          IList items,
          int startIndex,
          bool shuffling,
          ContainerPlayMarker containerPlayMarker)
        {
            ArrayListDataSet arrayListDataSet = new ArrayListDataSet();
            if (containerPlayMarker != null && containerPlayMarker.MediaType == MediaType.Playlist && containerPlayMarker.PlaylistType == PlaylistType.QuickMix)
            {
                this._playbackContext = PlaybackContext.QuickMix;
                this._quickMixType = (EQuickMixType)containerPlayMarker.PlaylistSubType;
                this._quickMixTitle = PlaylistManager.GetPlaylistName(containerPlayMarker.LibraryId);
                SQMLog.Log(SQMDataId.QuickMixPlaylistPlays, 1);
            }
            else if (items != null && items.Count == 1 && items[0] is LibraryDataProviderItemBase)
            {
                int mediaId = -1;
                EMediaTypes mediaType = EMediaTypes.eMediaTypeInvalid;
                (items[0] as LibraryDataProviderItemBase).GetMediaIdAndType(out mediaId, out mediaType);
                if (mediaType == EMediaTypes.eMediaTypePlaylist && PlaylistManager.GetPlaylistType(mediaId) == 7)
                {
                    this._playbackContext = PlaybackContext.QuickMix;
                    this._quickMixType = (EQuickMixType)PlaylistManager.GetSubType(mediaId);
                    this._quickMixTitle = PlaylistManager.GetPlaylistName(mediaId);
                    SQMLog.Log(SQMDataId.QuickMixPlaylistPlays, 1);
                }
            }
            PlaylistManager.AddItemsToTrackList(items, arrayListDataSet, ref startIndex, true, false, false, containerPlayMarker);
            if (arrayListDataSet.Count != 0)
            {
                bool flag1 = false;
                if (this._tracks == null)
                {
                    this._tracks = new ArrayListDataSet();
                    if (startIndex == -1)
                        startIndex = !shuffling ? 0 : s_random.Next(arrayListDataSet.Count);
                    flag1 = true;
                }
                bool flag2 = false;
                bool flag3 = false;
                if (this._tracks.Count > 0)
                {
                    if (((PlaybackTrack)this._tracks[0]).IsVideo)
                        flag2 = true;
                    else
                        flag3 = true;
                }
                for (int itemIndex = 0; itemIndex < arrayListDataSet.Count; ++itemIndex)
                {
                    PlaybackTrack playbackTrack = (PlaybackTrack)arrayListDataSet[itemIndex];
                    bool flag4 = true;
                    if (playbackTrack.IsVideo)
                    {
                        if (flag2)
                            flag4 = false;
                        else if (flag3)
                            flag4 = false;
                        else
                            flag2 = true;
                    }
                    else if (flag2)
                        flag4 = false;
                    else
                        flag3 = true;
                    if (flag4)
                        this._tracks.Add(arrayListDataSet[itemIndex]);
                    if (flag1 && itemIndex == startIndex)
                        this._indexCurrent = this._tracks.Count <= 0 ? 0 : this._tracks.Count - 1;
                }
                if (this._shuffling)
                    this.RebuildShuffleOrder();
                if (this._quickMixType != EQuickMixType.eQuickMixTypeInvalid)
                    this.AddReferencesToRemoteTracks(arrayListDataSet);
            }
            this.UpdateTracks();
            return arrayListDataSet.Count;
        }

        private void AddReferencesToRemoteTracks(IList tracks)
        {
            if (tracks == null)
                return;
            if (this._transientTracksPlaylistId == int.MinValue)
            {
                PlaylistResult playlist = PlaylistManager.Instance.CreatePlaylist("Now Playing Transient Tracks Playlist [" + _transientPlaylistCount + "]", true);
                ++_transientPlaylistCount;
                this._transientTracksPlaylistId = playlist.PlaylistId;
            }
            List<LibraryPlaybackTrack> libraryPlaybackTrackList = new List<LibraryPlaybackTrack>(tracks.Count);
            foreach (object track in tracks)
            {
                if (track is LibraryPlaybackTrack libraryPlaybackTrack && !libraryPlaybackTrack.IsInVisibleCollection)
                    libraryPlaybackTrackList.Add(libraryPlaybackTrack);
            }
            int playlist1 = (int)PlaylistManager.Instance.AddToPlaylist(this._transientTracksPlaylistId, libraryPlaybackTrackList, false, false);
        }

        public void Reorder(IList indices, int targetIndex)
        {
            PlaybackTrack currentTrack = this.CurrentTrack;
            this._tracks.Reorder(indices, targetIndex);
            if (this._shuffling)
                this.RebuildShuffleOrder();
            this._indexCurrent = this._tracks.IndexOf(currentTrack);
            if (this._shuffling)
                this._indexCurrent = this.FindShuffleIndexFromListIndex(this._indexCurrent);
            this.UpdateTracks();
        }

        public bool Remove(IList indices)
        {
            bool shuffling = this._shuffling;
            this.SetShuffling(false);
            int num = this._indexCurrent;
            bool flag = false;
            for (int index1 = indices.Count - 1; index1 >= 0; --index1)
            {
                int index2 = (int)indices[index1];
                this._tracks.RemoveAt(index2);
                if (num == index2)
                    flag = true;
                else if (num > index2)
                    --num;
            }
            if (num >= this._tracks.Count)
                num = this._tracks.Count - 1;
            this._indexCurrent = num;
            this.SetShuffling(shuffling);
            this.UpdateTracks();
            return flag;
        }

        public IList GetNextTracks(int count)
        {
            List<PlaybackTrack> playbackTrackList = null;
            if (this._tracks != null && this._tracks.Count > 0)
            {
                playbackTrackList = new List<PlaybackTrack>(count);
                for (int index = 0; index < count; ++index)
                {
                    int itemIndex = this._indexCurrent + index;
                    if (this._repeating || this._shuffling)
                    {
                        while (itemIndex >= this._tracks.Count)
                            itemIndex -= this._tracks.Count;
                    }
                    if (itemIndex >= 0 && (this._shuffling ? (itemIndex != this._indexShuffleStart ? 0 : (index != 0 ? 1 : 0)) : (itemIndex == this._tracks.Count ? 1 : 0)) == 0)
                    {
                        if (this._shuffling)
                            itemIndex = this._shuffleOrder[itemIndex];
                        playbackTrackList.Add((PlaybackTrack)this._tracks[itemIndex]);
                    }
                    else
                        break;
                }
            }
            return playbackTrackList;
        }

        [OnSerializing]
        internal void PrepareForSerialization(StreamingContext context)
        {
            if (this._tracks == null)
                return;
            int num1 = Math.Min(this._indexCurrent + 380, this._tracks.Count);
            int num2 = Math.Max(this._indexCurrent - (400 - (num1 - this._indexCurrent)), 0);
            this._savedTracks = new List<PlaybackTrack>(num1 - num2);
            for (int index = num2; index < num1; ++index)
                this._savedTracks.Add((PlaybackTrack)this._tracks[!this._shuffling ? index : this._shuffleOrder[index]]);
            int num3 = this._indexCurrent - num2;
            if (this._shuffling)
            {
                this._indexCurrent = 0;
                this._shuffleOrder[0] = num3;
            }
            else
                this._indexCurrent = num3;
        }

        [OnDeserialized]
        internal void HandleDeserialization(StreamingContext context)
        {
            this._transientTracksPlaylistId = int.MinValue;
            if (this._savedTracks != null)
            {
                this._tracks = new ArrayListDataSet();
                foreach (object savedTrack in this._savedTracks)
                    this._tracks.Add(savedTrack);
                this._savedTracks = null;
                if (this._shuffling)
                    this.RebuildShuffleOrder();
                this.UpdateTracks();
            }
            Application.DeferredInvoke(delegate
           {
               SingletonModelItem<TransportControls>.Instance.Shuffling.Value = this._shuffling;
           }, null);
        }

        [Conditional("DEBUG_NOW_PLAYING_LIST")]
        private static void _DEBUG_Trace(string message, params object[] args)
        {
        }

        private enum MovingMode
        {
            Advancing,
            Retreating,
            Jumping,
        }
    }
}
