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