1 using System; 2 using System.Globalization; 3 using System.Reactive.Linq; 4 using Reactive.Bindings; 5 using Reactive.Bindings.Extensions; 6 using TrainEditor2.Extensions; 7 using TrainEditor2.Models.Trains; 8 9 namespace TrainEditor2.ViewModels.Trains 10 { 11 internal class PressureViewModel : BaseViewModel 12 { 13 internal ReactiveProperty<string> BrakeCylinderServiceMaximumPressure 14 { 15 get; 16 } 17 18 internal ReactiveProperty<string> BrakeCylinderEmergencyMaximumPressure 19 { 20 get; 21 } 22 23 internal ReactiveProperty<string> MainReservoirMinimumPressure 24 { 25 get; 26 } 27 28 internal ReactiveProperty<string> MainReservoirMaximumPressure 29 { 30 get; 31 } 32 33 internal ReactiveProperty<string> BrakePipeNormalPressure 34 { 35 get; 36 } 37 PressureViewModel(Pressure pressure)38 internal PressureViewModel(Pressure pressure) 39 { 40 CultureInfo culture = CultureInfo.InvariantCulture; 41 42 BrakeCylinderServiceMaximumPressure = pressure 43 .ToReactivePropertyAsSynchronized( 44 x => x.BrakeCylinderServiceMaximumPressure, 45 x => x.ToString(culture), 46 x => double.Parse(x, NumberStyles.Float, culture), 47 ignoreValidationErrorValue: true 48 ) 49 .AddTo(disposable); 50 51 BrakeCylinderEmergencyMaximumPressure = pressure 52 .ToReactivePropertyAsSynchronized( 53 x => x.BrakeCylinderEmergencyMaximumPressure, 54 x => x.ToString(culture), 55 x => double.Parse(x, NumberStyles.Float, culture), 56 ignoreValidationErrorValue: true 57 ) 58 .AddTo(disposable); 59 60 MainReservoirMinimumPressure = pressure 61 .ToReactivePropertyAsSynchronized( 62 x => x.MainReservoirMinimumPressure, 63 x => x.ToString(culture), 64 x => double.Parse(x, NumberStyles.Float, culture), 65 ignoreValidationErrorValue: true 66 ) 67 .SetValidateNotifyError(x => 68 { 69 double result; 70 string message; 71 72 Utilities.TryParse(x, NumberRange.Positive, out result, out message); 73 74 return message; 75 }) 76 .AddTo(disposable); 77 78 MainReservoirMaximumPressure = pressure 79 .ToReactivePropertyAsSynchronized( 80 x => x.MainReservoirMaximumPressure, 81 x => x.ToString(culture), 82 x => double.Parse(x, NumberStyles.Float, culture), 83 ignoreValidationErrorValue: true 84 ) 85 .SetValidateNotifyError(x => 86 { 87 double result; 88 string message; 89 90 Utilities.TryParse(x, NumberRange.Positive, out result, out message); 91 92 return message; 93 }) 94 .AddTo(disposable); 95 96 BrakePipeNormalPressure = pressure 97 .ToReactivePropertyAsSynchronized( 98 x => x.BrakePipeNormalPressure, 99 x => x.ToString(culture), 100 x => double.Parse(x, NumberStyles.Float, culture), 101 ignoreValidationErrorValue: true 102 ) 103 .SetValidateNotifyError(x => 104 { 105 double result; 106 string message; 107 108 Utilities.TryParse(x, NumberRange.Positive, out result, out message); 109 110 return message; 111 }) 112 .AddTo(disposable); 113 114 BrakeCylinderServiceMaximumPressure 115 .SetValidateNotifyError(x => 116 { 117 double service; 118 string message; 119 120 if (Utilities.TryParse(x, NumberRange.Positive, out service, out message)) 121 { 122 double emergency; 123 124 if (Utilities.TryParse(BrakeCylinderEmergencyMaximumPressure.Value, NumberRange.Positive, out emergency) && service > emergency) 125 { 126 return "The BrakeCylinderEmergencyMaximumPressure is required to be greater than or equal to BrakeCylinderServiceMaximumPressure."; 127 } 128 } 129 130 return message; 131 }) 132 .Subscribe(_ => BrakeCylinderEmergencyMaximumPressure.ForceValidate()) 133 .AddTo(disposable); 134 135 BrakeCylinderServiceMaximumPressure.ObserveHasErrors 136 .ToReadOnlyReactivePropertySlim(mode: ReactivePropertyMode.DistinctUntilChanged) 137 .Where(x => !x) 138 .Subscribe(_ => BrakeCylinderServiceMaximumPressure.ForceNotify()) 139 .AddTo(disposable); 140 141 BrakeCylinderEmergencyMaximumPressure 142 .SetValidateNotifyError(x => 143 { 144 double emergency; 145 string message; 146 147 if (Utilities.TryParse(x, NumberRange.Positive, out emergency, out message)) 148 { 149 double service; 150 151 if (Utilities.TryParse(BrakeCylinderServiceMaximumPressure.Value, NumberRange.Positive, out service) && emergency < service) 152 { 153 return "The BrakeCylinderEmergencyMaximumPressure is required to be greater than or equal to BrakeCylinderServiceMaximumPressure."; 154 } 155 } 156 157 return message; 158 }) 159 .Subscribe(_ => BrakeCylinderServiceMaximumPressure.ForceValidate()) 160 .AddTo(disposable); 161 162 BrakeCylinderEmergencyMaximumPressure.ObserveHasErrors 163 .ToReadOnlyReactivePropertySlim(mode: ReactivePropertyMode.DistinctUntilChanged) 164 .Where(x => !x) 165 .Subscribe(_ => BrakeCylinderEmergencyMaximumPressure.ForceNotify()) 166 .AddTo(disposable); 167 } 168 } 169 } 170