1 using System;
2 using System.Globalization;
3 using System.Linq;
4 using System.Reactive.Disposables;
5 using System.Reactive.Linq;
6 using System.Windows.Forms;
7 using Reactive.Bindings;
8 using Reactive.Bindings.Binding;
9 using Reactive.Bindings.Extensions;
10 using TrainEditor2.Extensions;
11 using TrainEditor2.ViewModels.Trains;
12 
13 namespace TrainEditor2.Views
14 {
15 	public partial class FormDelay : Form
16 	{
17 		private readonly CompositeDisposable disposable;
18 
19 		private ReactiveProperty<DelayViewModel.EntryViewModel> SelectedEntry
20 		{
21 			get;
22 		}
23 
FormDelay(ReadOnlyReactiveCollection<DelayViewModel.EntryViewModel> delay)24 		internal FormDelay(ReadOnlyReactiveCollection<DelayViewModel.EntryViewModel> delay)
25 		{
26 			InitializeComponent();
27 
28 			disposable = new CompositeDisposable();
29 
30 			listViewDelay.Items.AddRange(delay.Select((x, i) => new ListViewItem(new[] { (i + 1).ToString(CultureInfo.InvariantCulture), x.Up.Value, x.Down.Value }) { Tag = x }).ToArray());
31 
32 			SelectedEntry = new ReactiveProperty<DelayViewModel.EntryViewModel>();
33 
34 			SelectedEntry
35 				.BindTo(
36 					listViewDelay,
37 					x => x.FocusedItem,
38 					BindingMode.OneWayToSource,
39 					null,
40 					x => (DelayViewModel.EntryViewModel)x?.Tag,
41 					Observable.FromEvent<EventHandler, EventArgs>(
42 							h => (s, e) => h(e),
43 							h => listViewDelay.SelectedIndexChanged += h,
44 							h => listViewDelay.SelectedIndexChanged -= h
45 						)
46 						.ToUnit()
47 				)
48 				.AddTo(disposable);
49 
50 			CompositeDisposable entryDisposable = new CompositeDisposable().AddTo(disposable);
51 
52 			SelectedEntry
53 				.Where(x => x != null)
54 				.Subscribe(x =>
55 				{
56 					entryDisposable.Dispose();
57 					entryDisposable = new CompositeDisposable().AddTo(disposable);
58 
59 					x.Up.BindTo(
60 							textBoxUp,
61 							y => y.Text,
62 							BindingMode.TwoWay,
63 							null,
64 							null,
65 							Observable.FromEvent<EventHandler, EventArgs>(
66 									h => (s, e) => h(e),
67 									h => textBoxUp.TextChanged += h,
68 									h => textBoxDown.TextChanged -= h
69 								)
70 								.ToUnit()
71 						)
72 						.AddTo(entryDisposable);
73 
74 					x.Up.BindTo(
75 							listViewDelay.FocusedItem.SubItems[1],
76 							y => y.Text
77 						)
78 						.AddTo(entryDisposable);
79 
80 					x.Up.BindToErrorProvider(errorProvider, textBoxUp).AddTo(entryDisposable);
81 
82 					x.Down.BindTo(
83 							textBoxDown,
84 							y => y.Text,
85 							BindingMode.TwoWay,
86 							null,
87 							null,
88 							Observable.FromEvent<EventHandler, EventArgs>(
89 									h => (s, e) => h(e),
90 									h => textBoxDown.TextChanged += h,
91 									h => textBoxDown.TextChanged -= h
92 								)
93 								.ToUnit()
94 						)
95 						.AddTo(entryDisposable);
96 
97 					x.Down.BindTo(
98 							listViewDelay.FocusedItem.SubItems[2],
99 							y => y.Text
100 						)
101 						.AddTo(entryDisposable);
102 
103 					x.Down.BindToErrorProvider(errorProvider, textBoxDown).AddTo(entryDisposable);
104 				})
105 				.AddTo(disposable);
106 
107 			groupBoxEntry.Enabled = listViewDelay.SelectedIndices.Count == 1;
108 		}
109 
FormDelay_Load(object sender, EventArgs e)110 		private void FormDelay_Load(object sender, EventArgs e)
111 		{
112 			Icon = FormEditor.GetIcon();
113 		}
114 
ListViewDelay_SelectedIndexChanged(object sender, EventArgs e)115 		private void ListViewDelay_SelectedIndexChanged(object sender, EventArgs e)
116 		{
117 			groupBoxEntry.Enabled = listViewDelay.SelectedIndices.Count == 1;
118 		}
119 
ButtonOK_Click(object sender, EventArgs e)120 		private void ButtonOK_Click(object sender, EventArgs e)
121 		{
122 			Close();
123 		}
124 	}
125 }
126