using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using System.Windows; using System.Diagnostics; using System.Text.RegularExpressions; using System.IO.Ports; using System.Net.Sockets; using Elwig.Dialogs; namespace Elwig.Helpers { public static partial class Utils { public static int CurrentYear => DateTime.Now.Year; public static int CurrentNextSeason => DateTime.Now.Year - (DateTime.Now.Month <= 3 ? 1 : 0); public static int CurrentLastSeason => DateTime.Now.Year - (DateTime.Now.Month <= 7 ? 1 : 0); public static DateTime Today => (DateTime.Now.Hour >= 3) ? DateTime.Today : DateTime.Today.AddDays(-1); public static readonly Regex SerialRegex = GeneratedSerialRegex(); public static readonly Regex TcpRegex = GeneratedTcpRegex(); [GeneratedRegex("^serial://([A-Za-z0-9]+):([0-9]+)(,([5-9]),([NOEMSnoems]),(0|1|1\\.5|2|))?$", RegexOptions.Compiled)] private static partial Regex GeneratedSerialRegex(); [GeneratedRegex("^tcp://([A-Za-z0-9._-]+):([0-9]+)$", RegexOptions.Compiled)] private static partial Regex GeneratedTcpRegex(); public static SerialPort OpenSerialConnection(string connection) { var m = SerialRegex.Match(connection); if (!m.Success) throw new ArgumentException("Invalid connection string for scheme \"serial\""); var stop = m.Groups[6].Value; var parity = m.Groups[5].Value.ToUpper(); var data = m.Groups[4].Value; var port = new SerialPort() { PortName = m.Groups[1].Value, BaudRate = int.Parse(m.Groups[2].Value), Parity = parity == "E" ? Parity.Even : parity == "O" ? Parity.Odd : parity == "M" ? Parity.Mark : parity == "S" ? Parity.Space : Parity.None, DataBits = data == "" ? 8 : int.Parse(data), StopBits = (StopBits)(stop == "" ? 1 : stop == "1.5" ? 3 : stop[0] - '0'), Handshake = Handshake.None, ReadTimeout = 1000, WriteTimeout = 1000, }; port.Open(); return port; } public static TcpClient OpenTcpConnection(string connection) { var m = TcpRegex.Match(connection); if (!m.Success) throw new ArgumentException("Invalid connection string for scheme \"tcp\""); var client = new TcpClient() { SendTimeout = 1000, ReceiveTimeout = 1000, }; client.Connect(m.Groups[1].Value, int.Parse(m.Groups[2].Value)); return client; } public static int Modulo(string a, int b) { if (a.Length == 0 || !a.All(char.IsAsciiDigit)) { throw new ArgumentException("First argument has to be a decimal string"); } else if (b < 2) { throw new ArgumentException("Second argument has to be greater than 1"); } return a.Select(ch => ch - '0').Aggregate((sum, n) => (sum * 10 + n) % b); } public static void RunBackground(string title, Func a) { Task.Run(async () => { try { await a(); } catch (Exception e) { MessageBox.Show(e.ToString(), title, MessageBoxButton.OK, MessageBoxImage.Error); } }); } public static void MailTo(string emailAddress) { Process.Start(new ProcessStartInfo() { FileName = $"mailto:{emailAddress}", UseShellExecute = true, }); } public static double KmwToOe(double kmw) { return Math.Round(kmw * (4.54 + 0.022 * kmw), 0); } public static double OeToKmw(double oe) { return Math.Round((-4.54 + Math.Sqrt(4.54 * 4.54 - 4 * 0.022 * -oe)) / (2 * 0.022), 1); } public static decimal DecFromDb(long value, byte precision) { bool neg = value < 0; if (neg) value = -value; return new((int)(value & 0xFFFFFFFF), (int)((value >> 32) & 0x7FFFFFFF), 0, neg, precision); } public static long DecToDb(decimal value, byte precision) { return (long)decimal.Round(value * (decimal)Math.Pow(10, precision), 0); } public static int GetAge(DateOnly birthday) { var today = DateTime.Today; var a = (today.Year * 100 + today.Month) * 100 + today.Day; var b = (birthday.Year * 100 + birthday.Month) * 100 + birthday.Day; return (a - b) / 10000; } public static int GetSearchScore(IEnumerable words, IEnumerable searchKeywords) { searchKeywords = searchKeywords.Where(s => s.Length >= 2 || (s.Length > 0 && s.All(c => char.IsAsciiDigit(c)))); if (!searchKeywords.Any()) return 0; words = words.Select(w => w?.ToLower()); int i = 0; foreach (string? c in words) { if (c == null) continue; var parts = c.Split(" "); if (searchKeywords.Any(f => c == f)) { i += 100; } else if (searchKeywords.Any(f => parts.Any(a => a == f))) { i += 90; } else if (searchKeywords.Any(f => parts.Any(a => a.StartsWith(f)))) { i += 50; } else if (searchKeywords.Any(f => f != null && c.Contains(f))) { i += 1; } } return i; } public static (int, string?)? ShowManualWeighingDialog() { var d = new ManualWeighingDialog(); return d.ShowDialog() == true ? (d.Weight, d.Reason) : null; } } }