async void Reset()
 {
     LibVM.Dispose();
     await Player.Stop();
     ShellVM.Dispose();
     AlbumArtistVM.Dispose();
     LibraryFoldersCollection.Clear();
     await ApplicationData.Current.ClearAsync();
     LibVM.Database = new Database.DatabaseQueryMethods();
     AlbumArtistVM.InitDB();
    // GC.Collect();
     LibVM.SongCount = 0;
     ResetCommand.IsEnabled = false;
     await Task.Delay(200);
     ResetCommand.IsEnabled = true;
 }
        public async Task AddFolderToLibraryAsync(StorageFileQueryResult queryResult)
        {
            if (queryResult != null)
            {
                var stop = System.Diagnostics.Stopwatch.StartNew();
                //we create two uints. 'index' for the index of current block/batch of files and 'stepSize' for the size of the block. This optimizes the loading operation tremendously.
                uint index = 0, stepSize = 100;
                //a list containing the files we recieved after querying using the two uints we created above.
                IReadOnlyList<StorageFile> files = await queryResult.GetFilesAsync(index, stepSize);

                //we move forward the index 100 steps because first 50 files are loaded when we called the above method.
                index += 100;
             
                //this is a temporary list to collect all the processed Mediafiles. We use List because it is fast. Faster than using ObservableCollection directly because of the events firing on every add.
                var tempList = new List<Mediafile>();
                //'i' is a variable for the index of currently processing file
                double i = 0;
                //'count' is for total files got after querying.
                var count = await queryResult.GetItemCountAsync();
                if(count == 0)
                {
                    string error = "No songs found!";
                    await NotificationManager.ShowAsync(error);
                }
                int failedCount = 0;
                //using while loop until number of files become 0. This is to confirm that we process all files without leaving anything out.
                while (files.Count != 0)
                {
                    try
                    {                        
                        //Since the no. of files in 'files' list is 100, only 100 files will be loaded after which we will step out of while loop.
                        //To avoid this, we create a task that loads the next 100 files. Stepping forward 100 steps without increasing the index.
                        var fileTask = queryResult.GetFilesAsync(index, stepSize).AsTask();

                        //A null Mediafile which we will use afterwards.
                        Mediafile mp3file = null;

                        //A foreach loop to process each StorageFile
                        foreach (StorageFile file in files)
                        {
                            try
                            {
                                //we use 'if' conditional so that we don't add any duplicates
                                if (LibVM.TracksCollection.Elements.All(t => t.Path != file.Path))
                                {

                                    i++; //Notice here that we are increasing the 'i' variable by one for each file.
                                    LibVM.SongCount++; //we also increase the total no. of songs by one.
                                    await Task.Run(async () =>
                                    {
                                        //here we load into 'mp3file' variable our processed Song. This is a long process, loading all the properties and the album art.
                                        mp3file = await CreateMediafile(file, false); //the core of the whole method.
                                        mp3file.FolderPath = Path.GetDirectoryName(file.Path);
                                        await SaveSingleFileAlbumArtAsync(mp3file, file).ConfigureAwait(false);
                                    });
                                    //this methods notifies the Player that one song is loaded. We use both 'count' and 'i' variable here to report current progress.
                                    await NotificationManager.ShowAsync(i.ToString() + "\\" + count.ToString() + " Song(s) Loaded", "Loading...");

                                    //we then add the processed song into 'tempList' very silently without anyone noticing and hence, efficiently.
                                    tempList.Add(mp3file);
                                }
                            }
                            catch (Exception ex)
                            {
                                //we catch and report any exception without distrubing the 'foreach flow'.
                                await NotificationManager.ShowAsync(ex.Message + " || Occured on: " + file.Path);
                                failedCount++;
                            }
                        }
                        //after the first 100 files have been added we enable the play button.
                        ShellVM.PlayPauseCommand.IsEnabled = true;
                        //now we add 100 songs directly into our TracksCollection which is an ObservableCollection. This is faster because only one event is invoked.
                        LibVM.TracksCollection.AddRange(tempList, false, true);
                        //now we load 100 songs into database.
                        LibVM.Database.Insert(tempList);
                        //we clear the 'tempList' so it can come with only 100 songs again.
                        tempList.Clear();
                        //here we reinitialize the 'files' variable (outside the while loop) so that it is never 0 and never contains the old files.
                        files = await fileTask.ConfigureAwait(false);
                        //consequently we have to increase the index by 100 so that songs are not repeated.
                        index += 100;
                    }
                    catch(Exception ex)
                    {
                        string message1 = ex.Message + "||" + ex.InnerException;
                        await NotificationManager.ShowAsync(message1);
                    }
                }
                //After all the songs are processed and loaded, we create albums of all those songs and load them using this method.
                await AlbumArtistVM.AddAlbums().ConfigureAwait(false);
                //we stop the stopwatch.
                stop.Stop();
                //and report the user how long it took.
                string message = string.Format("Library successfully loaded! Total Songs: {0} Failed: {1} Loaded: {2} Total Time Taken: {3} seconds", count, failedCount, i, Convert.ToInt32(stop.Elapsed.TotalSeconds).ToString()); 
                await NotificationManager.ShowAsync(message);
            }
        }
        /// <summary>
        /// Loads songs from a specified folder into the library. <seealso cref="LoadCommand"/>
        /// </summary>
        public async void Load()
        {
            FolderPicker picker = new FolderPicker()
            {
                SuggestedStartLocation = PickerLocationId.MusicLibrary
            };
            CoreMethods Methods = new CoreMethods();

            picker.FileTypeFilter.Add(".mp3");
            StorageFolder folder = await picker.PickSingleFolderAsync();

            LibraryFoldersCollection.Add(folder);
            if (folder != null)
            {
                if (StorageApplicationPermissions.FutureAccessList.Entries.Count <= 999)
                {
                    StorageApplicationPermissions.FutureAccessList.Clear();
                }
                StorageApplicationPermissions.FutureAccessList.Add(folder);
                var filelist = await BreadPlayer.Common.DirectoryWalker.GetFiles(folder.Path); //folder.GetFilesAsync(Windows.Storage.Search.CommonFileQuery.OrderByName); //

                var             tempList = new List <Mediafile>();
                DispatcherTimer timer    = new DispatcherTimer();
                timer.Interval = TimeSpan.FromSeconds(2);
                timer.Start();
                var    stop  = System.Diagnostics.Stopwatch.StartNew();
                double i     = 0;
                var    count = filelist.Count();
                foreach (var x in filelist)
                {
                    i++;
                    double percent = (i / count) * 100;
                    await Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () => { LibVM.Progress = percent; });

                    Mediafile   mp3file = null;
                    StorageFile file    = await StorageFile.GetFileFromPathAsync(x);

                    string path = file.Path;

                    if (LibVM.TracksCollection.Elements.All(t => t.Path != path))
                    {
                        try
                        {
                            mp3file = await CoreMethods.CreateMediafile(file);

                            tempList.Add(mp3file);
                        }
                        catch { }

                        timer.Tick += (sender, e) =>
                        {
                            LibVM.TracksCollection.AddRange(tempList);
                            LibVM.db.Insert(tempList);
                            tempList.Clear();
                        };
                    }
                }
                AlbumArtistVM.AddAlbums();
                stop.Stop();
                ShowMessage(stop.ElapsedMilliseconds.ToString() + "    " + LibVM.TracksCollection.Elements.Count.ToString());
            }
        }