1 using System;
2 using System.Reactive.Linq;
3 using Reactive.Bindings;
4 using Reactive.Bindings.Extensions;
5 using TrainEditor2.Models.Trains;
6 using TrainManager.Handles;
7 
8 namespace TrainEditor2.ViewModels.Trains
9 {
10 	internal class HandleViewModel : BaseViewModel
11 	{
12 		internal ReactiveProperty<HandleType> HandleType
13 		{
14 			get;
15 		}
16 
17 		internal ReactiveProperty<int> PowerNotches
18 		{
19 			get;
20 		}
21 
22 		internal ReactiveProperty<int> BrakeNotches
23 		{
24 			get;
25 		}
26 
27 		internal ReactiveProperty<int> PowerNotchReduceSteps
28 		{
29 			get;
30 		}
31 
32 		internal ReactiveProperty<EbHandleBehaviour> HandleBehaviour
33 		{
34 			get;
35 		}
36 
37 		internal ReactiveProperty<LocoBrakeType> LocoBrake
38 		{
39 			get;
40 		}
41 
42 		internal ReactiveProperty<int> LocoBrakeNotches
43 		{
44 			get;
45 		}
46 
47 		internal ReactiveProperty<int> DriverPowerNotches
48 		{
49 			get;
50 		}
51 
52 		internal ReactiveProperty<int> DriverBrakeNotches
53 		{
54 			get;
55 		}
56 
HandleViewModel(Handle handle, Train train)57 		internal HandleViewModel(Handle handle, Train train)
58 		{
59 			HandleType = handle
60 				.ToReactivePropertyAsSynchronized(x => x.HandleType)
61 				.AddTo(disposable);
62 
63 			PowerNotches = handle
64 				.ToReactivePropertyAsSynchronized(x => x.PowerNotches, ignoreValidationErrorValue: true)
65 				.AddTo(disposable);
66 
67 			PowerNotches.Subscribe(_ => train.ApplyPowerNotchesToCar()).AddTo(disposable);
68 
69 			BrakeNotches = handle
70 				.ToReactivePropertyAsSynchronized(x => x.BrakeNotches, ignoreValidationErrorValue: true)
71 				.SetValidateNotifyError(x =>
72 				{
73 					if (x == 0 && train.Device.HoldBrake)
74 					{
75 						return "BrakeNotches must be at least 1 if HoldBrake is set.";
76 					}
77 
78 					return null;
79 				})
80 				.AddTo(disposable);
81 
82 			BrakeNotches.Subscribe(_ => train.ApplyBrakeNotchesToCar()).AddTo(disposable);
83 
84 			PowerNotchReduceSteps = handle
85 				.ToReactivePropertyAsSynchronized(x => x.PowerNotchReduceSteps)
86 				.AddTo(disposable);
87 
88 			HandleBehaviour = handle
89 				.ToReactivePropertyAsSynchronized(x => x.HandleBehaviour)
90 				.AddTo(disposable);
91 
92 			LocoBrake = handle
93 				.ToReactivePropertyAsSynchronized(x => x.LocoBrake)
94 				.AddTo(disposable);
95 
96 			LocoBrakeNotches = handle
97 				.ToReactivePropertyAsSynchronized(x => x.LocoBrakeNotches)
98 				.AddTo(disposable);
99 
100 			LocoBrakeNotches.Subscribe(_ => train.ApplyLocoBrakeNotchesToCar()).AddTo(disposable);
101 
102 			DriverPowerNotches = handle
103 				.ToReactivePropertyAsSynchronized(x => x.DriverPowerNotches, ignoreValidationErrorValue: true)
104 				.AddTo(disposable);
105 
106 			DriverBrakeNotches = handle
107 				.ToReactivePropertyAsSynchronized(x => x.DriverBrakeNotches, ignoreValidationErrorValue: true)
108 				.AddTo(disposable);
109 
110 			PowerNotches
111 				.SetValidateNotifyError(x =>
112 				{
113 					if (x < DriverPowerNotches.Value)
114 					{
115 						return "DriverPowerNotches must be less than or equal to PowerNotches.";
116 					}
117 
118 					return null;
119 				})
120 				.Subscribe(_ => DriverPowerNotches.ForceValidate())
121 				.AddTo(disposable);
122 
123 			PowerNotches
124 				.ObserveHasErrors
125 				.ToReadOnlyReactivePropertySlim(mode: ReactivePropertyMode.DistinctUntilChanged)
126 				.Where(x => !x)
127 				.Subscribe(_ => PowerNotches.ForceNotify())
128 				.AddTo(disposable);
129 
130 			BrakeNotches
131 				.SetValidateNotifyError(x =>
132 				{
133 					if (x < DriverBrakeNotches.Value)
134 					{
135 						return "DriverBrakeNotches must be less than or equal to BrakeNotches.";
136 					}
137 
138 					return null;
139 				})
140 				.Subscribe(_ => DriverBrakeNotches.ForceValidate())
141 				.AddTo(disposable);
142 
143 			BrakeNotches
144 				.ObserveHasErrors
145 				.ToReadOnlyReactivePropertySlim(mode: ReactivePropertyMode.DistinctUntilChanged)
146 				.Where(x => !x)
147 				.Subscribe(_ => BrakeNotches.ForceNotify())
148 				.AddTo(disposable);
149 
150 			DriverPowerNotches
151 				.SetValidateNotifyError(x =>
152 				{
153 					if (x > PowerNotches.Value)
154 					{
155 						return "DriverPowerNotches must be less than or equal to PowerNotches.";
156 					}
157 
158 					return null;
159 				})
160 				.Subscribe(_ => PowerNotches.ForceValidate())
161 				.AddTo(disposable);
162 
163 			DriverPowerNotches
164 				.ObserveHasErrors
165 				.ToReadOnlyReactivePropertySlim(mode: ReactivePropertyMode.DistinctUntilChanged)
166 				.Where(x => !x)
167 				.Subscribe(_ => DriverPowerNotches.ForceNotify())
168 				.AddTo(disposable);
169 
170 			DriverBrakeNotches
171 				.SetValidateNotifyError(x =>
172 				{
173 					if (x > BrakeNotches.Value)
174 					{
175 						return "DriverBrakeNotches must be less than or equal to BrakeNotches.";
176 					}
177 
178 					return null;
179 				})
180 				.Subscribe(_ => BrakeNotches.ForceValidate())
181 				.AddTo(disposable);
182 
183 			DriverBrakeNotches
184 				.ObserveHasErrors
185 				.ToReadOnlyReactivePropertySlim(mode: ReactivePropertyMode.DistinctUntilChanged)
186 				.Where(x => !x)
187 				.Subscribe(_ => DriverBrakeNotches.ForceNotify())
188 				.AddTo(disposable);
189 		}
190 	}
191 }
192