291 lines
10 KiB
C#

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.Any())
result = null;
else
result = !matches.Any();
return new(result, results);
}
internal static (bool?, string[]) IsWrongYear(Models.FileHolder fileHolder, DateTime? dateTimeOriginal, List<DateTime> dateTimes)
{
string[] results = Array.Empty<string>();
bool? result = null;
string year;
string directoryName;
string[] directorySegments;
List<DateTime> collection = new();
string? check = Path.GetFullPath(fileHolder.FullName);
string? pathRoot = Path.GetPathRoot(fileHolder.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<DateTime> GetDateTimes(DateTime creationTime, DateTime lastWriteTime, DateTime? dateTime, DateTime? dateTimeDigitized, DateTime? dateTimeFromName, DateTime? dateTimeOriginal, DateTime? gpsDateStamp)
{
List<DateTime> results = new()
{
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<DateTime> dateTimes = new()
{
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<DateTime> 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(IEnumerable<long> values, double average)
{
double result = 0;
if (!values.Any())
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<long> 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<long> ticksCollection = new();
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.Any())
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<DateTime>, List<Models.Item>) Get(Models.Container container, TimeSpan threeStandardDeviationHigh, int i)
{
List<Models.Item> results = new();
int j = i;
long? ticks;
Models.Item item;
TimeSpan timeSpan;
Models.Item nextItem;
DateTime? minimumDateTime;
DateTime? nextMinimumDateTime;
List<DateTime> dateTimes = new();
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.Any())
continue;
if ((from l in container.Items where l.Any() select true).Any())
{
result = true;
break;
}
}
return result;
}
internal static bool NameWithoutExtensionIsIdFormat(string fileNameWithoutExtension)
{
bool result;
int intMinValueLength = int.MinValue.ToString().Length;
if (fileNameWithoutExtension.Length < 5 || fileNameWithoutExtension.Length > intMinValueLength)
result = false;
else
{
bool skipOneAllAreNumbers = fileNameWithoutExtension[1..].All(l => char.IsNumber(l));
result = (skipOneAllAreNumbers && fileNameWithoutExtension[0] == '-') || (skipOneAllAreNumbers && char.IsNumber(fileNameWithoutExtension[0]));
}
return result;
}
}