using System; using System.Collections.Generic; using System.Text.RegularExpressions; namespace SabreTools.Library.DatFiles { /// /// Represents a single filter within the overall filter /// /// Generic type representing the filtered object public class FilterItem { /// /// Single positive value for this filter /// public T Positive { get; set; } /// /// List of positive values for this filter /// public List PositiveSet { get; set; } = new List(); /// /// Single negative value for this filter /// public T Negative { get; set; } /// /// List of negative values for this filter /// public List NegativeSet { get; set; } = new List(); /// /// Single neutral value for this filter /// public T Neutral { get; set; } /// /// List of neutral values for this filter /// public List NeutralSet { get; set; } = new List(); /// /// Check if a value matches the positive filter /// /// Default value to check filter value /// Value to check /// True if the value was found in the positive filter, false otherwise public bool MatchesPositive(T def, T value) { return Matches(this.Positive, def, value); } /// /// Check if a value matches the negative filter /// /// Default value to check filter value /// Value to check /// True if the value was found in the negative filter, false otherwise public bool MatchesNegative(T def, T value) { return Matches(this.Negative, def, value); } /// /// Check if a value matches the neutral filter /// /// Default value to check filter value /// Value to check /// True if the value was found in the neutral filter, false otherwise public bool MatchesNeutral(T def, T value) { return Matches(this.Neutral, def, value); } /// /// Check if the given value matches any of the positive filters /// /// Value to check /// True if the value was found in a positive filter, false otherwise public bool MatchesPositiveSet(T value) { return MatchesSet(this.PositiveSet, value); } /// /// Check if the given value matches any of the negative filters /// /// Value to check /// True if the value was found in a negative filter, false otherwise public bool MatchesNegativeSet(T value) { return MatchesSet(this.NegativeSet, value); } /// /// Check if the given value matches any of the neutral filters /// /// Value to check /// True if the value was found in a neutral filter, false otherwise public bool MatchesNeutralSet(T value) { return MatchesSet(this.NeutralSet, value); } /// /// Check if a value matches the supplied filter /// /// Value to check against /// Default value to check filter value /// Value to check /// True if the value was found in the supplied filter, false otherwise private bool Matches(T single, T def, T value) { // If the filter is default, we ignore if (single.Equals(def)) return true; // If we have a flag if (typeof(T).IsEnum && (single as Enum).HasFlag(value as Enum)) return true; return single.Equals(value); } /// /// Check if a value matches the supplied filter /// /// Set to check against /// Value to check /// True if the value was found in the supplied filter, false otherwise private bool MatchesSet(List set, T value) { if (set.Count > 0) { if (this.FindValueInList(set, value)) return true; } return false; } /// /// Generic code to check if a specific value is in the list given /// /// List to search for the value in /// Value to search the list for /// True if the value could be found, false otherwise private bool FindValueInList(List haystack, T needle) { bool found = false; foreach (T straw in haystack) { if (straw is string) { string needleString = needle as string; string strawString = straw as string; if (!String.IsNullOrWhiteSpace(strawString)) { string regexStraw = strawString; // If the straw has no special characters at all, treat it as an exact match if (regexStraw == Regex.Escape(regexStraw)) { regexStraw = "^" + regexStraw + "$"; } // Check if a match is found with the regex found |= Regex.IsMatch(needleString, regexStraw, RegexOptions.IgnoreCase | RegexOptions.CultureInvariant); } } else { found |= (needle.Equals(straw)); } } return found; } } }