public AudioFileTag(Release release, Track track)
        {
            this.AlbumArtists = release.JoinedAlbumArtists;
            if (string.IsNullOrEmpty(track.JoinedArtists))
            {
                this.Artists = release.JoinedAlbumArtists;
            }
            else
            {
                this.Artists = track.JoinedArtists;
            }
            this.Album = release.Title;
            this.Title = track.Title;
            this.Track = track.Position;
            this.TrackCount = release.Tracklist.Count(t => t.Disc == track.Disc);
            this.Disc = track.Disc;
            this.DiscCount = release.DiscCount;
            if (release.OriginalReleaseDate != null && release.OriginalReleaseDate.IsValid)
            {
                this.Year = release.OriginalReleaseDate.Date.Year;
            }
            else
            {
                this.Year = release.ReleaseDate.IsValid ? release.ReleaseDate.Date.Year : 0;
            }
            this.Genre = release.Genre;

            Image mainImage = release.Images.Where(i => i.IsMain == true).FirstOrDefault();
            if (release.Thumbnail != null && mainImage != null)
            {
                this.Images = new AudioFileImage[]
                {
                    new AudioFileImage() {
                        Data = release.Thumbnail,
                        MimeType = Release.ThumbnailMimeType,
                        Description = mainImage.Description,
                        Type = mainImage.Type
                    }
                };
            }
        }
        private void AddItem(IImportSourceItem importSourceItem)
        {
            Track track = new Track()
            {
                Disc = this.Disc,
                Position = this.Tracks.Count + 1,
                Title = importSourceItem.Tag.Title
            };
            ImportTrackItem importTrackItem = new ImportTrackItem(track, importSourceItem);

            this.OnItemAdding(importTrackItem);

            this.Tracks.Add(importTrackItem);
            int index = this.Release.Tracklist.LastIndexWhere(t => t.Disc <= this.Disc);
            this.Release.Tracklist.Insert(index + 1, track); // Will be inserted at 0 if there are no matching tracks.
        }
        public static string PatternToFilename(string pattern, Release release, Track track)
        {
            if (release.DiscCount <= 1)
            {
                while (true)
                {
                    int start = pattern.IndexOf(IfDiscsStartPattern);
                    if (start == -1)
                    {
                        break;
                    }

                    int end = pattern.IndexOf(IfDiscsEndPattern, start);
                    if (end == -1)
                    {
                        break;
                    }

                    pattern = pattern.Substring(0, start) + pattern.Substring(end + IfDiscsEndPattern.Length);
                }

            }

            string actualTrackArtists = string.IsNullOrEmpty(track.JoinedArtists) ? release.JoinedAlbumArtists : track.JoinedArtists;

            return pattern
                .Replace(ArtistPattern, actualTrackArtists)
                .Replace(AlbumArtistPattern, FixFilename(release.JoinedAlbumArtists))
                .Replace(AlbumPattern, FixFilename(release.Title))
                .Replace(TitlePattern, FixFilename(track.Title))
                .Replace(TrackPattern, FixFilename(track.Position.ToString("00")))
                .Replace(DiscPattern, FixFilename(track.Disc.ToString()))

                .Replace(TextPattern, "")
                .Replace(NumberPattern, "")
                .Replace(IfDiscsStartPattern, "")
                .Replace(IfDiscsEndPattern, "")
                ;
        }
 public ImportTrackItem(Track track, IImportSourceItem sourceItem)
 {
     this.Track = track;
     this.SourceItem = sourceItem;
 }
 public void AddItem(Track track, FileEncodeTask task)
 {
     this.TrackTasks.Add(new Item(track, task));
 }
 public Item(Track track, FileEncodeTask task)
 {
     this.Track = track;
     this.Task = task;
 }
        private void ExportTrackArtists(XmlWriter writer, Track track)
        {
            if (!string.IsNullOrEmpty(track.JoinedArtists))
            {
                writer.WriteStartElement(Keys.Artists);

                TrackArtist[] artists = null;
                try
                {
                    artists = track.Artists.ToArray();
                    track.Artists.Select(a => a.Artist.Name).ToArray(); // get names to verify
                }
                catch
                {
                    artists = new TrackArtist[]
                    {
                        new TrackArtist()
                        {
                            Artist = new Artist()
                                     {
                                         Name = track.JoinedArtists
                                     }
                        }
                    };
                }

                if (artists != null)
                {
                    foreach (TrackArtist artist in artists)
                    {
                        this.ExportTrackArtist(writer, artist);
                    }
                }

                writer.WriteEndElement();
            }
        }
        private void ExportTrack(XmlWriter writer, Track track)
        {
            writer.WriteStartElement(Keys.Track);

            writer.WriteAttributeString(Keys.Disc, track.Disc.ToString());
            writer.WriteAttributeString(Keys.Position, track.Position.ToString());
            writer.WriteAttributeString(Keys.Title, track.Title);
            if (!string.IsNullOrEmpty(track.JoinedArtists))
            {
                writer.WriteAttributeString(Keys.JoinedArtists, track.JoinedArtists);
            }
            writer.WriteAttributeString(Keys.RelativeFilename, track.RelativeFilename);
            writer.WriteAttributeString(Keys.DynamicRange, track.DynamicRange.ToString());
            writer.WriteAttributeString(Keys.TrackGain, track.ReplayGainTrackGain.ToString());
            writer.WriteAttributeString(Keys.TrackPeak, track.ReplayGainTrackPeak.ToString());

            this.ExportTrackArtists(writer, track);

            writer.WriteEndElement();
        }
        private void ReadTrackArtists(XmlReader reader, Track track)
        {
            reader.AssertElementStart(Keys.Artists);

            if (reader.IsEmptyElement)
            {
                throw new FormatException(InvalidXmlDatabase);
            }

            while (reader.Read())
            {
                if (reader.IsElementEnd(Keys.Artists))
                {
                    break;
                }

                reader.AssertElementStart(Keys.Artist);
                track.Artists.Add(new TrackArtist()
                {
                    Artist = this.collectionManager.GetOrCreateArtist(reader.GetAttributeOrNull(Keys.Name)),
                    JoinString = reader.GetAttributeOrNull(Keys.JoinString)
                });
            }
        }
        private Track ReadTrack(XmlReader reader)
        {
            reader.AssertElementStart(Keys.Track);

            Track track = new Track()
            {
                Disc = reader.GetAttributeInt32(Keys.Disc, 0),
                Position = reader.GetAttributeInt32(Keys.Position, 0),
                Title = reader.GetAttributeOrNull(Keys.Title),
                JoinedArtists = reader.GetAttributeOrNull(Keys.JoinedArtists),
                RelativeFilename = reader.GetAttributeOrNull(Keys.RelativeFilename),
                DynamicRange = reader.GetAttributeDouble(Keys.DynamicRange, double.NaN),
                ReplayGainTrackGain = reader.GetAttributeDouble(Keys.TrackGain, double.NaN),
                ReplayGainTrackPeak = reader.GetAttributeDouble(Keys.TrackPeak, double.NaN),
            };

            if (reader.IsEmptyElement)
            {
                return track;
            }

            while (reader.Read())
            {
                if (reader.IsElementEnd(Keys.Track))
                {
                    break;
                }

                if (reader.IsElementStart(Keys.Artists))
                {
                    this.ReadTrackArtists(reader, track);
                }
                else
                {
                    throw new FormatException(InvalidXmlDatabase);
                }
            }

            return track;
        }
        public List<Track> GenerateTracklistForLocalAlbum(ICollectionManager collectionManager, LocalAlbum album, Release release)
        {
            List<Track> list = new List<Track>();
            foreach (LocalDisc disc in album.Discs)
            {
                bool hasTrackArtists = disc.Tracks.Any(t => t.Artist != disc.Tracks[0].Artist);

                foreach (TrackInfoCache localTrack in disc.Tracks)
                {
                    Track track = new Track()
                    {
                        Disc = localTrack.Disc,
                        Position = localTrack.Track,
                        Title = localTrack.Title,
                        RelativeFilename = localTrack.RelativeFilename
                    };
                    if (hasTrackArtists)
                    {
                        track.Artists.Add(new TrackArtist()
                        {
                            Artist = collectionManager.GetOrCreateArtist(localTrack.Artist),
                        });
                        track.JoinedArtists = localTrack.Artist;
                    }

                    list.Add(track);
                }
            }
            return list;
        }