using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.ComponentModel; namespace DTS.Slice.PedestrianAndHeadReports { /// /// this is the base class for all pedestrian and head reports /// it contains all the common items between the reports /// public abstract class ReportBase : INotifyPropertyChanged { /// /// these functions make us WPF/dependency property friendly, and also /// adds a convenient way for us to notify consumers when a property has changed /// public event PropertyChangedEventHandler PropertyChanged; protected bool SetProperty(ref T storage, T value, String propertyName) { if (object.Equals(storage, value)) return false; storage = value; this.OnPropertyChanged(propertyName); return true; } protected void OnPropertyChanged(string propertyName) { var eventHandler = this.PropertyChanged; if (eventHandler != null) { eventHandler(this, new PropertyChangedEventArgs(propertyName)); } } public void SetField(KnownGraphs graph, string channelId, GraphChannel.Fields field, string value) { _graphs[graph.ToString()].GetGraphChannel(channelId).SetValue(field, value); DrawGraph(graph); if (graph == KnownGraphs.HEAD_Acceleration) { DrawGraph(KnownGraphs.HEAD_ResultantAcceleration, GetGraph(KnownGraphs.HEAD_ResultantAcceleration.ToString()).Chart); } } public void SetField(KnownGraphs graph, ReportGraph.Fields field, string value) { _graphs[graph.ToString()].SetValue(field, value); } private Dictionary _graphs = new Dictionary(); protected void AddGraph(ReportGraph graph) { _graphs.Add(graph.Id, graph); graph.PropertyChanged += new PropertyChangedEventHandler(graph_PropertyChanged); } protected ReportGraph GetGraph(string id) { return _graphs[id]; } public string GetValueTrunc2Places(KnownGraphs graph, string id, GraphChannel.Fields field) { return _graphs[graph.ToString()].GetValueTrunc2Places(id, field); } public string GetValue(KnownGraphs graph, string id, GraphChannel.Fields field) { return _graphs[graph.ToString()].GetValue(id, field); } protected void graph_PropertyChanged(object sender, PropertyChangedEventArgs e) { ReportGraph graph = sender as ReportGraph; OnPropertyChanged("Graph-x-"+graph.Id + "-x-" + e.PropertyName); } public string GetValue(KnownGraphs graph, ReportGraph.Fields field) { return _graphs[graph.ToString()].GetValue(field); } public virtual void DrawGraph(KnownGraphs graph, C1.Win.C1Chart.C1Chart chart) { DrawGraph(graph.ToString(), chart); } public void DrawGraph(string id, C1.Win.C1Chart.C1Chart chart) { _graphs[id].Draw(chart); } protected void DrawGraph(KnownGraphs graph) { _graphs[graph.ToString()].Draw(); } public double[] GetXPlot(KnownGraphs graph, string id) { return _graphs[graph.ToString()].GetXPlot(id); } public double[] GetYPlot(KnownGraphs graph, string id) { return _graphs[graph.ToString()].GetYPlot(id); } public enum KnownGraphs { LWR_LEG_TRL_Acceleration, LWR_LEG_TRL_BendingAngle, LWR_LEG_TRL_ShearAngle, HEAD_ResultantAcceleration, HEAD_Acceleration, HEAD_StrokeDisplacement, ARS_ARS, ARS_Acceleration, FLEX_TIBIA, FLEX_MCL, FLEX_ACLPCL, FLEX_LCL, FLEX_FEMUR, UPRLEG_Force, UPRLeg_Moment, FLEX_CALTibia1, FLEX_CALTibia2, FLEX_CALTibia3, FLEX_CALTibia4, FLEX_CALMCL, FLEX_CALACL, FLEX_CALPCL, LWR_LEG_TRL_BendingDisplacement, LWR_LEG_TRL_ShearDisplacement } /// /// we maintain a link to the owning test report /// we do this so we can get access to the Test property, which /// contains the information on what event we are actually operating on /// protected PedestrianAndHeadTest _testParent; public ReportBase(PedestrianAndHeadTest parent) { _testParent = parent; //mostly we just want to be notified if our parent changes tests ... _testParent.PropertyChanged += new PropertyChangedEventHandler(_testParent_PropertyChanged); InitializeProperties(); InitializeGraphs(); } /// /// this is function gets called whenever the parent pedestrian and head report changes tests. /// the default base class does nothing, but our descendants are free to do with it as they please /// /// /// protected virtual void _testParent_PropertyChanged(object sender, PropertyChangedEventArgs e) { switch (e.PropertyName) { case "Test": var enumerator = _graphs.GetEnumerator(); while (enumerator.MoveNext()) { enumerator.Current.Value.Clear(_testParent.Test); } enumerator = _graphs.GetEnumerator(); while (enumerator.MoveNext()) { enumerator.Current.Value.SetDefaults(_testParent.Test); enumerator.Current.Value.SetCFC(ChannelFilterClass, this); } if (null != _testParent.Test) { SetValue(PedestrianAndHeadTest.Fields.TestDate.ToString(), _testParent.Test.CreationTime.Ticks.ToString()); } break; } } /// /// list of all properties for the report /// note it's private, so that it forces descendants through the accessor methods where we have more /// control /// private Dictionary _properties = new Dictionary(); protected virtual void InitializeProperties() { AddProperty(new ReportProperty(PedestrianAndHeadTest.Fields.TestNumber.ToString(), "試験NO", null, typeof(string))); AddProperty(new ReportProperty(PedestrianAndHeadTest.Fields.TestDate.ToString(), "試験実施日", null, typeof(DateTime))); AddProperty(new ReportProperty(PedestrianAndHeadTest.Fields.CarName.ToString(), "車名", null, typeof(string))); AddProperty(new ReportProperty(PedestrianAndHeadTest.Fields.Model.ToString(), "型式", null, typeof(string))); AddProperty(new ReportProperty(PedestrianAndHeadTest.Fields.TestTemperature.ToString(), "試験温度", null, typeof(string))); AddProperty(new ReportProperty(PedestrianAndHeadTest.Fields.MeasurementPoint.ToString(), "測定点", null, typeof(string))); AddProperty(new ReportProperty(PedestrianAndHeadTest.Fields.CollisionSpeed.ToString(), "衝突速度", null, typeof(string))); AddProperty(new ReportProperty(PedestrianAndHeadTest.Fields.ImpactorId.ToString(), "インパクタID", null, typeof(string))); AddProperty(new ReportProperty(PedestrianAndHeadTest.Fields.ImpactorType.ToString(), "インパクタ種類", null, typeof(string))); AddProperty(new ReportProperty(PedestrianAndHeadTest.Fields.ImpactorWeight.ToString(), "インパクタ重量", null, typeof(string))); AddProperty(new ReportProperty(PedestrianAndHeadTest.Fields.StudyPersonnel.ToString(), "試験担当者", null, typeof(string))); AddProperty(new ReportProperty(PedestrianAndHeadTest.Fields.And1.ToString(), "予備1", null, typeof(string))); AddProperty(new ReportProperty(PedestrianAndHeadTest.Fields.And2.ToString(), "予備2", null, typeof(string))); List filters = new List(); SensorDB.FilterClass.FilterClassType[] filtertypes = Enum.GetValues(typeof(SensorDB.FilterClass.FilterClassType)).Cast().ToArray(); foreach (var ft in filtertypes) { switch (ft) { case DTS.SensorDB.FilterClass.FilterClassType.AdHoc: break; default: filters.Add((new SensorDB.FilterClass(ft)).ToString()); break; } } AddProperty(new ReportProperty(PedestrianAndHeadTest.Fields.FrequencyClass.ToString(), "周波数クラス", filters.ToArray(), typeof(string))); AddProperty(new ReportProperty(PedestrianAndHeadTest.Fields.TimeUnits.ToString(), "Time", new string[] { "s", "ms" }, typeof(string))); SetValue(PedestrianAndHeadTest.Fields.TimeUnits.ToString(), "s"); } protected virtual void InitializeGraphs() { ;} /// /// sets a value for a property (and notifies any listeners of the change) /// /// /// public void SetValue(string field, string value) { if (_properties[field].Value == value) { return; } _properties[field].SetValue(value); switch (field) { case "TimeUnits": foreach (var g in _graphs) { g.Value.TimeUnits = value; } break; } OnPropertyChanged(field); } /// /// returns the value for a property /// /// /// public string GetValue(string field) { if (!_properties.ContainsKey(field) || string.IsNullOrEmpty(_properties[field].Value)) { return ""; } else { return _properties[field].Value; } } /// /// returns all possible values for a property (or null if the user must manually enter a value) /// /// /// protected string[] GetPossibleValues(string field) { return _properties[field].GetAvailableValues(); } /// /// sets the possible values for a property /// /// /// protected void SetPossibleValues(string field, string[] values) { _properties[field].SetAvailableValues(values); if (null != values && values.Length == 1) { _properties[field].SetValue(values[0]); } } /// /// adds a new property /// this enables descendants to have their own unique properties /// /// protected void AddProperty(ReportProperty p) { _properties.Add(p.Id, p); } /// /// the known report types, we can make this more generic in the future? /// maybe just a name? /// public enum ReportTypes { Head, UPRLeg, LWRLegTRL, LWRLegFlex, LWRLegARS } public string GetName() { switch (GetReportType()) { case ReportTypes.Head: return "HEAD"; case ReportTypes.LWRLegARS: return "LWR LEG(ARS)"; case ReportTypes.LWRLegFlex: return "LWR LEG(FLEX)"; case ReportTypes.LWRLegTRL: return "LWR LEG(TRL)"; case ReportTypes.UPRLeg: return "UPR LEG"; } throw new Exception("uknown report type: " + GetReportType().ToString()); } public abstract ReportTypes GetReportType(); /// /// indicates whether this report is currently in use in the /// pedestrian and head report (selected to export) /// protected bool _bInUse = false; public bool InUse { get { return _bInUse; } set { SetProperty(ref _bInUse, value, "InUse"); } } /// /// all these properties come directly from the Pedestrian and Head Safety report sample xlsx .. /// public string TestNumber { get { return GetValue(PedestrianAndHeadTest.Fields.TestNumber.ToString()); } set { SetValue(PedestrianAndHeadTest.Fields.TestNumber.ToString(), value); } } /// /// this one is the only one that is a little tricky, /// we move to and from longs to avoid globalization issues ... /// public DateTime TestDate { get { return new DateTime(long.Parse(GetValue(PedestrianAndHeadTest.Fields.TestDate.ToString()))); } set { SetValue(PedestrianAndHeadTest.Fields.TestDate.ToString(), value.Ticks.ToString()); } } public string CarName { get { return GetValue(PedestrianAndHeadTest.Fields.CarName.ToString()); } set { SetValue(PedestrianAndHeadTest.Fields.CarName.ToString(), value); } } public string Model { get { return GetValue(PedestrianAndHeadTest.Fields.Model.ToString()); } set { SetValue(PedestrianAndHeadTest.Fields.Model.ToString(), value); } } public string TestTemperature { get { return GetValue(PedestrianAndHeadTest.Fields.TestTemperature.ToString()); } set { SetValue(PedestrianAndHeadTest.Fields.TestTemperature.ToString(), value); } } public string MeasurementPoint { get { return GetValue(PedestrianAndHeadTest.Fields.MeasurementPoint.ToString()); } set { SetValue(PedestrianAndHeadTest.Fields.MeasurementPoint.ToString(), value); } } public string CollisionSpeed { get { return GetValue(PedestrianAndHeadTest.Fields.CollisionSpeed.ToString()); } set { SetValue(PedestrianAndHeadTest.Fields.CollisionSpeed.ToString(), value); } } public string ImpactorID { get { return GetValue(PedestrianAndHeadTest.Fields.ImpactorId.ToString()); } set { SetValue(PedestrianAndHeadTest.Fields.ImpactorId.ToString(), value); } } public string ImpactorType { get { return GetValue(PedestrianAndHeadTest.Fields.ImpactorType.ToString()); } set { SetValue(PedestrianAndHeadTest.Fields.ImpactorType.ToString(), value); } } public string StudyPersonnel { get { return GetValue(PedestrianAndHeadTest.Fields.StudyPersonnel.ToString()); } set { SetValue(PedestrianAndHeadTest.Fields.StudyPersonnel.ToString(), value); } } public string And1 { get { return GetValue(PedestrianAndHeadTest.Fields.And1.ToString()); } set { SetValue(PedestrianAndHeadTest.Fields.And1.ToString(), value); } } public string And2 { get { return GetValue(PedestrianAndHeadTest.Fields.And2.ToString()); } set { SetValue(PedestrianAndHeadTest.Fields.And2.ToString(), value); } } public string[] GetAvailableTimeUnits() { return _properties[PedestrianAndHeadTest.Fields.TimeUnits.ToString()].GetAvailableValues(); } public string TimeUnits { get { return _properties[PedestrianAndHeadTest.Fields.TimeUnits.ToString()].Value; } set { SetValue(PedestrianAndHeadTest.Fields.TimeUnits.ToString(), value); } } public string ImpactorWeight { get { return GetValue(PedestrianAndHeadTest.Fields.ImpactorWeight.ToString()); } set { SetValue(PedestrianAndHeadTest.Fields.ImpactorWeight.ToString(), value); } } public virtual string ChannelFilterClass { get { return GetValue(PedestrianAndHeadTest.Fields.FrequencyClass.ToString()); } set { SetValue(PedestrianAndHeadTest.Fields.FrequencyClass.ToString(), value); var e = _graphs.GetEnumerator(); while (e.MoveNext()) { e.Current.Value.SetCFC(value,this); } } } public string[] GetImpactorTypes() { return GetPossibleValues(PedestrianAndHeadTest.Fields.ImpactorType.ToString()); } public string[] GetAvailableFilterTypes() { return GetPossibleValues(PedestrianAndHeadTest.Fields.FrequencyClass.ToString()); } public MeasurementUnit GetUnits(KnownGraphs graph) { return GetGraph(graph.ToString()).GetChannelUnit(); } public void SetUnits(KnownGraphs graph, MeasurementUnit units) { GetGraph(graph.ToString()).SetChannelUnit(units); DrawGraph(graph, GetGraph(graph.ToString()).Chart); } public MeasurementUnit[] GetAvailableUnits(KnownGraphs graph) { return GetGraph(graph.ToString()).GetChannelUnits(); } public ReviewTestChannel GetChannel(KnownGraphs graph, string id) { return GetGraph(graph.ToString()).GetReviewTestChannel(id); } public void SetChannel(KnownGraphs graph, string id, ReviewTestChannel channel) { GetGraph(graph.ToString()).SetReviewTestChannel(id, channel); GetGraph(graph.ToString()).SetCFC(ChannelFilterClass, this); } public ReviewTestChannel[] GetAvailableChannels(KnownGraphs graph, string id) { return GetGraph(graph.ToString()).GetAvailableChannels(id, _testParent.Test); } public void ToStringOutput(ref System.Xml.XmlWriter xt) { xt.WriteStartElement("Report"); //xt.WriteStartElement("ReportType"); xt.WriteElementString("ReportType", GetReportType().ToString()); xt.WriteElementString("InUse", InUse.ToString()); var e = _properties.GetEnumerator(); while (e.MoveNext()) { try { PedestrianAndHeadTest.Fields field = (PedestrianAndHeadTest.Fields)Enum.Parse(typeof(PedestrianAndHeadTest.Fields), e.Current.Value.Id); switch (field) { case PedestrianAndHeadTest.Fields.TestNumber: continue; case PedestrianAndHeadTest.Fields.TestDate: continue; case PedestrianAndHeadTest.Fields.TestTemperature: continue; case PedestrianAndHeadTest.Fields.CollisionSpeed: continue; } } catch (System.Exception) { } xt.WriteElementString(e.Current.Value.Id, e.Current.Value.Value); } this.GetReportType(); xt.WriteEndElement(); } } }