using System;
using System.ComponentModel;
using System.Xml.Serialization;
using MusicMetaTagger.Core.Queries;
using MusicMetaTagger.Core.Utility;

namespace MusicMetaTagger.UI
{
	public class LibraryQuery
	{
		[Category("Name Searches")]
		[Browsable(true)]
		[Description("Search by Artist Name")]
		[XmlAttribute]
		public string ArtistName { get; set; }

		[Category("Name Searches")]
		[Browsable(true)]
		[Description("Search by Album Title")]
		[XmlAttribute]
		public string AlbumTitle { get; set; }

		[Category("Name Searches")]
		[Browsable(true)]
		[Description("Search by Track Title")]
		[XmlAttribute]
		public string TrackTitle { get; set; }

		[Category("Date")]
		[Browsable(true)]
		[Description("Search by the Most Recently Added Entries")]
		[XmlAttribute]
		public DateTime AddedAfter { get; set; }

		[Category("Blank Fields")]
		[Browsable(true)]
		[Description("Search by those with Blank Rating field")]
		[DefaultValue(false)]
		[XmlAttribute]
		public bool BlankRating { get; set; }

		[Category("Blank Fields")]
		[Browsable(true)]
		[Description("Search by those with Blank Genre field")]
		[DefaultValue(false)]
		[XmlAttribute]
		public bool BlankGenre { get; set; }

		[Category("Blank Fields")]
		[Browsable(true)]
		[Description("Search by those with Blank Year field")]
		[DefaultValue(false)]
		[XmlAttribute]
		public bool BlankYear { get; set; }

		[Category("General")]
		[Browsable(true)]
		[Description("Limit the number of tracks scanned in the library - use this for a trial run")]
		[DefaultValue(0)]
		[XmlAttribute]
		public int ScanLimit { get; set; }

		/// <summary>
		///   Returns true if the given track query matches this library query
		/// </summary>
		public bool MatchTrackQuery(TrackQuery trackQuery)
		{
			Func<string, string, bool> isMatch =
				(s1, s2) => string.IsNullOrEmpty(s1)
							|| string.IsNullOrEmpty(s2)
							|| StringUtility.Similarity(s1, s2) > .5
							|| StringUtility.ContainsString(s1, s2);

			return isMatch(trackQuery.ArtistName, ArtistName)
			       && isMatch(trackQuery.AlbumTitle, AlbumTitle)
			       && isMatch(trackQuery.TrackTitle, TrackTitle);
		}

		public override string ToString()
		{
			var description = "";
			if (!string.IsNullOrEmpty(ArtistName))
				description = StringUtility.ConcatToString(description, "Artist:[" + ArtistName + "]");
			if (!string.IsNullOrEmpty(AlbumTitle))
				description = StringUtility.ConcatToString(description, "Album:[" + AlbumTitle + "]");
			if (!string.IsNullOrEmpty(TrackTitle))
				description = StringUtility.ConcatToString(description, "Track:[" + TrackTitle + "]");
			if (AddedAfter != DateTime.MinValue)
				description = StringUtility.ConcatToString(description, "Added After:" + AddedAfter.ToShortDateString());
			if (BlankRating)
				description = StringUtility.ConcatToString(description, "Blank Rating");
			if (BlankGenre)
				description = StringUtility.ConcatToString(description, "Blank Genre");
			if (BlankYear)
				description = StringUtility.ConcatToString(description, "Blank Year");
			if (ScanLimit > 0)
				description = StringUtility.ConcatToString(description, "Scan Limit:" + ScanLimit);
			return description;
		}
	}
}