public LocalCollectionMatcherResult Match()
        {
            LocalCollectionMatcherResult result = new LocalCollectionMatcherResult();

            foreach (Release release in this.collectionManager.Releases)
            {
                result.DeletedReleases.Add(release);
            }

            this.collectionScanner.Scan();

            int totalAlbums   = this.collectionScanner.LocalCollection.AlbumArtists.Values.Select(r => r.Albums.Count).Sum();
            int scannedAlbums = 0;

            LocalCollection collection = this.collectionScanner.LocalCollection;

            foreach (LocalAlbumArtist lAlbumArtist in collection.AlbumArtists.Values)
            {
                foreach (LocalAlbum lAlbum in lAlbumArtist.Albums.Values)
                {
                    Release release = this.collectionManager.Operations.GetReleaseByLocalAlbumName(lAlbum);

                    if (release == null)
                    {
                        result.NewReleases.Add(lAlbum);
                    }
                    else
                    {
                        result.DeletedReleases.Remove(release);

                        bool filesExist = release.Tracklist.All(t => {
                            string musicDirectory = this.collectionManager.Settings.MusicDirectory;
                            return(File.Exists(Path.Combine(musicDirectory, t.RelativeFilename)));
                        });

                        if (!filesExist && !this.collectionManager.Operations.MatchReleaseWithLocalAlbum(release, lAlbum))
                        {
                            result.ChangedReleases.Add(new Tuple <Release, LocalAlbum>(release, lAlbum));
                        }
                        else
                        {
                            result.UnchangedReleases.Add(release);
                        }
                    }

                    ++scannedAlbums;
                    ProgressChangedEventArgs eventArgs = new ProgressChangedEventArgs((double)scannedAlbums / totalAlbums);
                    this.OnCollectionMatcherProgressChanged(eventArgs);
                    if (eventArgs.Cancel)
                    {
                        return(result);
                    }
                }
            }

            return(result);
        }
        public LocalCollectionMatcherResult Match()
        {
            LocalCollectionMatcherResult result = new LocalCollectionMatcherResult();

            foreach (Release release in this.collectionManager.Releases)
            {
                result.DeletedReleases.Add(release);
            }

            this.collectionScanner.Scan();

            int totalAlbums = this.collectionScanner.LocalCollection.AlbumArtists.Values.Select(r => r.Albums.Count).Sum();
            int scannedAlbums = 0;

            LocalCollection collection = this.collectionScanner.LocalCollection;
            foreach (LocalAlbumArtist lAlbumArtist in collection.AlbumArtists.Values)
            {
                foreach (LocalAlbum lAlbum in lAlbumArtist.Albums.Values)
                {
                    Release release = this.collectionManager.Operations.GetReleaseByLocalAlbumName(lAlbum);

                    if (release == null)
                    {
                        result.NewReleases.Add(lAlbum);
                    }
                    else
                    {
                        result.DeletedReleases.Remove(release);

                        bool filesExist = release.Tracklist.All(t => {
                            string musicDirectory = this.collectionManager.Settings.MusicDirectory;
                            return File.Exists(Path.Combine(musicDirectory, t.RelativeFilename));
                        });

                        if (!filesExist && !this.collectionManager.Operations.MatchReleaseWithLocalAlbum(release, lAlbum))
                        {
                            result.ChangedReleases.Add(new Tuple<Release, LocalAlbum>(release, lAlbum));
                        }
                        else
                        {
                            result.UnchangedReleases.Add(release);
                        }
                    }

                    ++scannedAlbums;
                    ProgressChangedEventArgs eventArgs = new ProgressChangedEventArgs((double)scannedAlbums / totalAlbums);
                    this.OnCollectionMatcherProgressChanged(eventArgs);
                    if (eventArgs.Cancel)
                    {
                        return result;
                    }
                }
            }

            return result;
        }
        public LocalCollectionMerger(ICollectionManager collectionManager, LocalCollectionMatcherResult matcherResult, bool saveToFiles)
        {
            this.collectionManager = collectionManager;
            this.matcherResult = matcherResult;
            this.saveToFiles = saveToFiles;

            this.total =
                this.matcherResult.NewReleases.Count +
                this.matcherResult.ChangedReleases.Count +
                this.matcherResult.DeletedReleases.Count;
        }
        public LocalCollectionMerger(ICollectionManager collectionManager, LocalCollectionMatcherResult matcherResult, bool saveToFiles)
        {
            this.collectionManager = collectionManager;
            this.matcherResult     = matcherResult;
            this.saveToFiles       = saveToFiles;

            this.total =
                this.matcherResult.NewReleases.Count +
                this.matcherResult.ChangedReleases.Count +
                this.matcherResult.DeletedReleases.Count;
        }
        private void ScannerTask()
        {
            LocalCollectionMatcher matcher = new LocalCollectionMatcher(this.CollectionManager);

            matcher.CollectionScannerProgressChanged +=
                ProgressBarUpdater.CreateHandler(this.Dispatcher, this.progressScan,
                () => this.cancelScanning,
                p => { this.labelScanStatus.Text = p == 1 ? "" : "Reading file tags..."; });
            matcher.ProgressChanged +=
                ProgressBarUpdater.CreateHandler(this.Dispatcher, this.progressMatch,
                () => this.cancelScanning,
                p => { this.labelMatchStatus.Text = p == 1 ? "" : "Matching with database contents..."; });

            this.matcherResult = matcher.Match();

            if (this.cancelScanning)
            {
                return;
            }

            List<CollectionChangeItem> changedItems = new List<CollectionChangeItem>();
            changedItems.AddRange(this.matcherResult.NewReleases.Select(r => new CollectionChangeItem()
            {
                Type = CollectionChangeType.Addded,
                LocalAlbum = r
            }));
            changedItems.AddRange(this.matcherResult.ChangedReleases.Select(r => new CollectionChangeItem()
            {
                Type = CollectionChangeType.Changed,
                Release = r.Item1,
                LocalAlbum = r.Item2
            }));
            changedItems.AddRange(this.matcherResult.DeletedReleases.Select(r => new CollectionChangeItem()
            {
                Type = CollectionChangeType.Deleted,
                Release = r
            }));
            changedItems.Sort((a, b) => a.ReleaseDisplayName.CompareTo(b.ReleaseDisplayName));

            List<CollectionChangeItem> unchangedItems = new List<CollectionChangeItem>();
            unchangedItems.AddRange(this.matcherResult.UnchangedReleases.Select(r => new CollectionChangeItem()
            {
                Type = CollectionChangeType.Deleted,
                Release = r
            }));

            this.Dispatcher.BeginInvoke(new Action(() =>
            {
                this.OnScanningCompleted(changedItems, unchangedItems);
            }));
        }