using System; using System.Text; using System.Xml.Linq; using System.ComponentModel; using DTS.Common.Utilities.Logging; using DTS.Common.Enums.Sensors; using DTS.Common.Interface.Sensors; using System.Collections.Generic; namespace DTS.Common.Classes.Sensors { public class ZeroMethod : INotifyPropertyChanged { public event PropertyChangedEventHandler PropertyChanged; protected bool SetProperty(ref T storage, T value, String propertyName = null) { if (Equals(storage, value)) return false; storage = value; OnPropertyChanged(propertyName); return true; } protected void OnPropertyChanged(string propertyName = null) { PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); } public override int GetHashCode() { return Method.GetHashCode() + Start.GetHashCode() + End.GetHashCode(); } public ZeroMethodType Method { get; set; } = SensorConstants.DefaultZeroMethodType; // FB12764: Belt-and-suspenders, fetch default from SensorConstants public double Start { get; set; } = SensorConstants.DefaultZeroMethodStart; // FB12764: Belt-and-suspenders, fetch default from SensorConstants public double End { get; set; } = SensorConstants.DefaultZeroMethodEnd; // FB12764: Belt-and-suspenders, fetch default from SensorConstants #region Tags internal const string ZERO_METHOD_TAG = "ZeroMethod"; internal const string METHOD_TAG = "Method"; internal const string START_TAG = "Start"; internal const string END_TAG = "End"; #endregion public ZeroMethod(ZeroMethodType zm, double start, double end) { Method = zm; Start = start; End = end; } public ZeroMethod(string zm, System.Globalization.CultureInfo culture) { Initialize(zm, culture); } public ZeroMethod(string zm) { Initialize(zm, System.Globalization.CultureInfo.InvariantCulture); } /// /// do a deep copy /// /// public ZeroMethod(ZeroMethod copy) { Method = copy.Method; Start = copy.Start; End = copy.End; } private void Initialize(string zm, System.Globalization.CultureInfo culture) { var tokens = zm.Split(','); if (tokens.Length < 3) { return; } Start = Convert.ToDouble(tokens[1], culture); End = Convert.ToDouble(tokens[2], culture); if( tokens[0].Contains("PreCalZero") ) { Method = ZeroMethodType.UsePreEventDiagnosticsZero; } else { Method = (ZeroMethodType) Enum.Parse(typeof(ZeroMethodType), tokens[0]); } } public string ToDbString() { return $"{Method.ToString()},{Start},{End}"; } private readonly string _tableName; public ZeroMethod(XElement elem, string prefix, string tblName, string id) { _tableName = tblName; XElement inner; try { inner = elem.Element(mkTag(prefix)); } catch (ArgumentNullException) { if (!string.IsNullOrEmpty(id)) { throw new Exception($"{_tableName}: Can't find tag {prefix + "-" + ZERO_METHOD_TAG} for entry {id}"); } throw new Exception($"{_tableName}: Can't find tag {prefix + "-" + ZERO_METHOD_TAG} in file"); } try { // this is a special case to remain compatible with older TDM // I moved this to avoid the exception // 6/8/2010 - dtm if (inner.Value == "UsePreCalZero") { Method = ZeroMethodType.UsePreEventDiagnosticsZero; } else if (inner.Value == ZeroMethodType.UsePreEventDiagnosticsZero.ToString()) { inner.Value = "UsePreCalZero"; Method = ZeroMethodType.UsePreEventDiagnosticsZero; } else { Method = (ZeroMethodType) Enum.Parse(typeof(ZeroMethodType), inner.Value); } } catch (ArgumentException ex) { APILogger.Log(ex); throw; } Start = double.Parse(inner.Attribute(START_TAG).Value, System.Globalization.CultureInfo.InvariantCulture); End = double.Parse(inner.Attribute(END_TAG).Value, System.Globalization.CultureInfo.InvariantCulture); } internal XElement ToXElement(string prefix) { string value; switch (Method) { case ZeroMethodType.UsePreEventDiagnosticsZero: value = "UsePreCalZero"; break; default: value = Method.ToString(); break; } var element = new XElement(mkTag(prefix), value); element.SetAttributeValue(START_TAG, Start); element.SetAttributeValue(END_TAG, End); return element; } internal void Update(XElement elem, string prefix) { elem.SetElementValue(mkTag(prefix), Method.ToString()); var element = elem.Element(mkTag(prefix)); element.SetAttributeValue(START_TAG, Start); element.SetAttributeValue(END_TAG, End); } internal static string mkTag(string prefix) { return prefix + "-" + ZERO_METHOD_TAG; } public string ToSerializeString() { return $"{Method.ToString()},{Start.ToString(System.Globalization.CultureInfo.InvariantCulture)},{End.ToString(System.Globalization.CultureInfo.InvariantCulture)}"; } public string ToDisplayString(string averageOverTimeFormatString, string diagnosticLevelFormatString, string absoluteZeroFormatString) { var sb = new StringBuilder(); switch (Method) { case ZeroMethodType.AverageOverTime: sb.AppendFormat("{0} from {1} to {2}", averageOverTimeFormatString, Start, End); break; case ZeroMethodType.UsePreEventDiagnosticsZero: sb.AppendFormat("{0}", diagnosticLevelFormatString); break; case ZeroMethodType.None: sb.AppendFormat("{0}", absoluteZeroFormatString); break; } return sb.ToString(); } public override bool Equals(object obj) { if (obj is ZeroMethod zm) { return zm.Method == Method && zm.Start == Start && zm.End == End; } return base.Equals(obj); } } public class ZeroMethods : IZeroMethods { public ZeroMethod[] Methods { get; set; } = new ZeroMethod[] { }; public ZeroMethods(ZeroMethods copy) : this(copy.Methods) { } public ZeroMethods(ZeroMethod[] copyMethods) { ZeroMethod[] methods = new ZeroMethod[copyMethods.Length]; for (int i = 0; i < copyMethods.Length; i++) { methods[i] = new ZeroMethod(copyMethods[i]); } Methods = methods; } public ZeroMethods() { Methods = new ZeroMethod[] { }; } public ZeroMethods(string methods) { FromSerializedString(methods); } public ZeroMethods(ZeroMethod startingMethod) { Methods = new ZeroMethod[] { startingMethod }; } public override bool Equals(object obj) { if (obj is ZeroMethods r) { if (r.Methods.Length != Methods.Length) { return false; } for (int i = 0; i < r.Methods.Length; i++) { if (!r.Methods[i].Equals(Methods[i])) { return false; } } return true; } return base.Equals(obj); } public void FromSerializedString(string s) { string[] tokens = s.Split(new string[] { MySeparator }, StringSplitOptions.None); for (int i = 0; i < tokens.Length; i++) { tokens[i] = tokens[i].Replace(MySeparatorBackup, MySeparator); } List methods = new List(); foreach (string token in tokens) { methods.Add(new ZeroMethod(token)); } Methods = methods.ToArray(); } private const string MySeparator = "__x__"; private const string MySeparatorBackup = "___xx___"; public string ToSerializedString() { List methods = new List(); foreach (var r in Methods) { methods.Add(r.ToSerializeString()); } for (int i = 0; i < methods.Count; i++) { System.Diagnostics.Trace.Assert(!methods[i].Contains(MySeparatorBackup)); methods[i] = methods[i].Replace(MySeparator, MySeparatorBackup); } return string.Join(MySeparator, methods.ToArray()); } public string ToDisplayString(string averageOverTimeFormatString, string diagnosticLevelFormatString, string absoluteZeroFormatString) { StringBuilder sb = new StringBuilder(); /*foreach (var r in Methods) { if (currentMethod > 1) { sb.AppendLine(); } sb.AppendFormat("{0}: {1}", currentMethod++, r.ToDisplayString(sc)); }*/ for (int i = 0; i < Methods.Length; i++) { if (i > 0) { sb.AppendLine(); } string s = Methods[i].ToDisplayString(averageOverTimeFormatString, diagnosticLevelFormatString, absoluteZeroFormatString); if (!string.IsNullOrEmpty(s)) { sb.Append(s); } } return sb.ToString(); } public override string ToString() { return ToDisplayString(Strings.Strings.SensorFields_InitialOffset_AverageOverTimeFormat, Strings.Strings.SensorFields_InitialOffset_DiagnosticLevelFormat, Strings.Strings.SensorFields_InitialOffset_AbsoluteZeroFormat); } } }