namespace View_by_Distance.Shared.Models.Stateless.Methods; internal abstract class Property { internal static (int Season, string seasonName) GetSeason(int dayOfYear) { (int Season, string seasonName) result = dayOfYear switch { < 78 => new(0, "Winter"), < 171 => new(1, "Spring"), < 264 => new(2, "Summer"), < 354 => new(3, "Fall"), _ => new(4, "Winter") }; return result; } internal static (bool?, string[]) IsWrongYear(string[] segments, string year) { bool? result; string[] results = ( from l in segments where l?.Length > 2 && ( l[..2] is "18" or "19" or "20" || (l.Length == 5 && l.Substring(1, 2) is "18" or "19" or "20" && (l[0] is '~' or '=' or '-' or '^' or '#')) || (l.Length == 6 && l[..2] is "18" or "19" or "20" && l[4] == '.') || (l.Length == 7 && l.Substring(1, 2) is "18" or "19" or "20" && l[5] == '.') ) select l ).ToArray(); string[] matches = ( from l in results where l == year || (l.Length == 5 && l.Substring(1, 4) == year && (l[0] is '~' or '=' or '-' or '^' or '#')) || (l.Length == 6 && l[..4] == year && l[4] == '.') || (l.Length == 7 && l.Substring(1, 4) == year && l[5] == '.') select l ).ToArray(); if (results.Length == 0) result = null; else result = matches.Length == 0; return new(result, results); } internal static (bool?, string[]) IsWrongYear(FilePath filePath, DateTime? dateTimeOriginal, List dateTimes) { string[] results = []; bool? result = null; string year; string directoryName; string[] directorySegments; List collection = []; string? check = Path.GetFullPath(filePath.FullName); string? pathRoot = Path.GetPathRoot(filePath.FullName); if (string.IsNullOrEmpty(pathRoot)) throw new Exception(); if (dateTimeOriginal is not null) collection.Add(dateTimeOriginal.Value); else { foreach (DateTime dateTime in dateTimes) collection.Add(dateTime); } foreach (DateTime dateTime in collection) { year = dateTime.ToString("yyyy"); for (int i = 0; i < int.MaxValue; i++) { check = Path.GetDirectoryName(check); if (string.IsNullOrEmpty(check) || check == pathRoot) break; directoryName = Path.GetFileName(check); directorySegments = directoryName.Split(' '); (result, results) = IsWrongYear(directorySegments, year); if (result is not null) break; } if (result is not null && !result.Value) break; } return new(result, results); } internal static List GetDateTimes(DateTime creationTime, DateTime lastWriteTime, DateTime? dateTime, DateTime? dateTimeDigitized, DateTime? dateTimeFromName, DateTime? dateTimeOriginal, DateTime? gpsDateStamp) { List results = [ creationTime, lastWriteTime ]; if (dateTime.HasValue) results.Add(dateTime.Value); if (dateTimeDigitized.HasValue) results.Add(dateTimeDigitized.Value); if (dateTimeFromName.HasValue) results.Add(dateTimeFromName.Value); if (dateTimeOriginal.HasValue) results.Add(dateTimeOriginal.Value); if (gpsDateStamp.HasValue) results.Add(gpsDateStamp.Value); return results; } internal static DateTime GetDateTime(Models.Property? property) { DateTime result; if (property is null) result = DateTime.MinValue; else { List dateTimes = [ property.CreationTime, property.LastWriteTime ]; if (property.DateTime.HasValue) dateTimes.Add(property.DateTime.Value); if (property.DateTimeDigitized.HasValue) dateTimes.Add(property.DateTimeDigitized.Value); if (property.DateTimeFromName.HasValue) dateTimes.Add(property.DateTimeFromName.Value); if (property.DateTimeOriginal.HasValue) dateTimes.Add(property.DateTimeOriginal.Value); if (property.GPSDateStamp.HasValue) dateTimes.Add(property.GPSDateStamp.Value); result = dateTimes.Min(); } return result; } internal static DateTime GetMinimumDateTime(Models.Property? property) { DateTime result; List dateTimes; if (property is null) result = DateTime.MinValue; else { dateTimes = IProperty.GetDateTimes(property); result = dateTimes.Min(); } return result; } internal static string GetDiffRootDirectory(string diffPropertyDirectory) { string result = string.Empty; string results = "-Results"; string? checkDirectory = diffPropertyDirectory; for (int i = 0; i < int.MaxValue; i++) { checkDirectory = Path.GetDirectoryName(checkDirectory); if (string.IsNullOrEmpty(checkDirectory)) break; if (checkDirectory.EndsWith(results)) { result = checkDirectory[..^results.Length]; break; } } return result; } internal static double GetStandardDeviation(List values, double average) { double result = 0; if (values.Count == 0) throw new Exception("Collection must have at least one value!"); double sum = values.Sum(l => (l - average) * (l - average)); result = Math.Sqrt(sum / values.Count); return result; } private static long GetThreeStandardDeviationHigh(ref List ticksCollection, long min) { long result; ticksCollection = (from l in ticksCollection select l - min).ToList(); double sum = ticksCollection.Sum(); double average = sum / ticksCollection.Count; double standardDeviation = GetStandardDeviation(ticksCollection, average); result = (long)Math.Ceiling(average + min + (standardDeviation * 3)); return result; } internal static TimeSpan GetThreeStandardDeviationHigh(int minimum, Models.Container container) { TimeSpan result; DateTime? minimumDateTime; List ticksCollection = []; foreach (Models.Item item in container.Items) { if (item.Property is null) continue; minimumDateTime = GetMinimumDateTime(item.Property); if (minimumDateTime is null) continue; ticksCollection.Add(minimumDateTime.Value.Ticks); } long threeStandardDeviationHigh; long min; if (ticksCollection.Count == 0) min = 0; else min = ticksCollection.Min(); if (ticksCollection.Count < minimum) threeStandardDeviationHigh = long.MaxValue; else threeStandardDeviationHigh = GetThreeStandardDeviationHigh(ref ticksCollection, min); result = new TimeSpan(threeStandardDeviationHigh - min); return result; } internal static (int, List, List) Get(Models.Container container, TimeSpan threeStandardDeviationHigh, int i) { List results = []; int j = i; long? ticks; Models.Item item; TimeSpan timeSpan; Models.Item nextItem; DateTime? minimumDateTime; DateTime? nextMinimumDateTime; List dateTimes = []; for (; j < container.Items.Count; j++) { ticks = null; item = container.Items[j]; if (item.Property is null) continue; minimumDateTime = GetMinimumDateTime(item.Property); if (minimumDateTime is null) continue; for (int k = j + 1; k < container.Items.Count; k++) { nextItem = container.Items[k]; if (nextItem.Property is null) continue; nextMinimumDateTime = GetMinimumDateTime(nextItem.Property); if (nextMinimumDateTime is null) continue; ticks = nextMinimumDateTime.Value.Ticks; break; } results.Add(item); dateTimes.Add(minimumDateTime.Value); if (ticks.HasValue) { timeSpan = new(ticks.Value - minimumDateTime.Value.Ticks); if (timeSpan > threeStandardDeviationHigh) break; } } return new(j, dateTimes, results); } internal static bool Any(Models.Container[] containers) { bool result = false; foreach (Models.Container container in containers) { if (container.Items.Count == 0) continue; if ((from l in container.Items where l.Any() select true).Any()) { result = true; break; } } return result; } }