Subversion Repositories Projects

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
2287 - 1
using GMap.NET;
2
using GMap.NET.MapProviders;
3
using GMap.NET.WindowsPresentation;
4
using MKLiveView.GMapCustomMarkers;
5
using System;
6
using System.Collections.Generic;
7
using System.ComponentModel;
8
using System.Data;
9
using System.Diagnostics;
10
using System.IO;
11
using System.Linq;
12
using System.Linq.Expressions;
13
using System.Runtime.InteropServices;
14
using System.Text;
15
using System.Threading;
16
using System.Threading.Tasks;
17
using System.Windows;
18
using System.Windows.Controls;
19
using System.Windows.Data;
20
using System.Windows.Documents;
21
using System.Windows.Input;
22
using System.Windows.Interop;
23
using System.Windows.Media;
24
using System.Windows.Media.Animation;
25
using System.Windows.Media.Imaging;
26
using System.Windows.Navigation;
27
using System.Windows.Shapes;
28
using System.Windows.Threading;
2313 - 29
using System.Globalization;
2324 - 30
using System.Xml;
31
using System.Xml.Linq;
2287 - 32
 
33
namespace MKLiveView
34
{
35
    /// <summary>
36
    /// Interaktionslogik für MainWindow.xaml
37
    /// </summary>
38
    public partial class MainWindow : Window
39
    {
2304 - 40
        #region declarations
2405 - 41
        object lockObj = new Object();
42
        MediaPlayer.MediaPlayer mediaPlayer = new MediaPlayer.MediaPlayer();
2304 - 43
 
2287 - 44
        GMapMarker copter;
45
        GMapMarker home;
46
        PointLatLng start;
47
        PointLatLng end;
48
        PointLatLng pHome;
2328 - 49
        GMapRoute mRouteWP;
2342 - 50
        GMapMarker wpActiveMarker;
2328 - 51
        List<PointLatLng> wpList = new List<PointLatLng>();
2405 - 52
        Circle cWPBound = new Circle();
53
        double dWPMaxRange = 0;
54
 
2324 - 55
        #region NC-Errors
2287 - 56
        String[] NC_Error = new string[44]
57
        {
58
            "No Error",
2381 - 59
            "FC not compatible",
60
            "MK3Mag not compatible",
61
            "no FC communication",
62
            "no compass communication",
63
            "no GPS communication",
64
            "bad compass value",
65
            "RC Signal lost",
66
            "FC spi rx error",
67
            "ERR: no NC communication",
68
            "ERR: FC Nick Gyro",
69
            "ERR: FC Roll Gyro",
70
            "ERR: FC Yaw Gyro",
71
            "ERR: FC Nick ACC",
72
            "ERR: FC Roll ACC",
73
            "ERR: FC Z-ACC",
74
            "ERR: Pressure sensor",
75
            "ERR: FC I2C",
76
            "ERR: Bl Missing",
77
            "Mixer Error",
78
            "FC: Carefree Error",
79
            "ERR: GPS lost",
80
            "ERR: Magnet Error",
81
            "Motor restart",
82
            "BL Limitation",
83
            "Waypoint range",
84
            "ERR:No SD-Card",
85
            "ERR:SD Logging aborted",
86
            "ERR:Flying range!",
87
            "ERR:Max Altitude",
88
            "No GPS Fix",
89
            "compass not calibrated",
90
            "ERR:BL selftest",
91
            "no ext. compass",
92
            "compass sensor",
93
            "FAILSAFE pos.!",
94
            "ERR:Redundancy",
95
            "Redundancy test",
96
            "GPS Update rate",
97
            "ERR:Canbus",
98
            "ERR: 5V RC-Supply",
99
            "ERR:Power-Supply",
100
            "ACC not calibr.",
101
            "ERR:Parachute!"
2287 - 102
        };
2381 - 103
        String[] NC_Error_Link = new string[44]
104
        {
105
            "",
106
            "http://wiki.mikrokopter.de/ErrorCodes#A1_.22FC_not_compatible_.22",
107
            "http://wiki.mikrokopter.de/ErrorCodes#A2_.22MK3Mag_not_compatible_.22",
108
            "http://wiki.mikrokopter.de/ErrorCodes#A3_.22no_FC_communication_.22",
109
            "http://wiki.mikrokopter.de/ErrorCodes#A4_.22no_compass_communication_.22",
110
            "http://wiki.mikrokopter.de/ErrorCodes#A5_.22no_GPS_communication_.22",
111
            "http://wiki.mikrokopter.de/ErrorCodes#A6_.22bad_compass_value.22",
112
            "http://wiki.mikrokopter.de/ErrorCodes#A7_.22RC_Signal_lost_.22",
113
            "http://wiki.mikrokopter.de/ErrorCodes#A8_.22FC_spi_rx_error_.22",
114
            "http://wiki.mikrokopter.de/ErrorCodes#A9:_.22ERR:_no_NC_communication.22",
115
            "http://wiki.mikrokopter.de/ErrorCodes#A10_.22ERR:_FC_Nick_Gyro.22",
116
            "http://wiki.mikrokopter.de/ErrorCodes#A11_.22ERR:_FC_Roll_Gyro.22",
117
            "http://wiki.mikrokopter.de/ErrorCodes#A12_.22ERR:_FC_Yaw_Gyro.22",
118
            "http://wiki.mikrokopter.de/ErrorCodes#A13_.22ERR:_FC_Nick_ACC.22",
119
            "http://wiki.mikrokopter.de/ErrorCodes#A14_.22ERR:_FC_Roll_ACC.22",
120
            "http://wiki.mikrokopter.de/ErrorCodes#A15_.22ERR:_FC_Z-ACC.22",
121
            "http://wiki.mikrokopter.de/ErrorCodes#A16_.22ERR:_Pressure_sensor.22",
122
            "http://wiki.mikrokopter.de/ErrorCodes#A17_.22ERR:_FC_I2C.22",
123
            "http://wiki.mikrokopter.de/ErrorCodes#A18_.22ERR:_Bl_Missing.22",
124
            "http://wiki.mikrokopter.de/ErrorCodes#A19_.22Mixer_Error.22",
125
            "http://wiki.mikrokopter.de/ErrorCodes#A20_.22FC:_Carefree_Error.22",
126
            "http://wiki.mikrokopter.de/ErrorCodes#A21_.22ERR:_GPS_lost.22",
127
            "http://wiki.mikrokopter.de/ErrorCodes#A22_.22ERR:_Magnet_Error.22",
128
            "http://wiki.mikrokopter.de/ErrorCodes#A23_.22Motor_restart.22",
129
            "http://wiki.mikrokopter.de/ErrorCodes#A24_.22BL_Limitation.22",
130
            "http://wiki.mikrokopter.de/ErrorCodes#A25_.22Waypoint_range.22",
131
            "http://wiki.mikrokopter.de/ErrorCodes#A26_.22ERR:No_SD-Card.22",
132
            "http://wiki.mikrokopter.de/ErrorCodes#A27_.22ERR:SD_Logging_aborted.22",
133
            "http://wiki.mikrokopter.de/ErrorCodes#A28_.22ERR:Flying_range.21.22",
134
            "http://wiki.mikrokopter.de/ErrorCodes#A29_.22ERR:Max_Altitude.22",
135
            "http://wiki.mikrokopter.de/ErrorCodes#A30_.22No_GPS_Fix.22",
136
            "http://wiki.mikrokopter.de/ErrorCodes#A31_.22compass_not_calibrated.22",
137
            "http://wiki.mikrokopter.de/ErrorCodes#A32_.22ERR:BL_selftest.22",
138
            "http://wiki.mikrokopter.de/ErrorCodes#A33_.22no_ext._compass.22",
139
            "http://wiki.mikrokopter.de/ErrorCodes#A34_.22compass_sensor.22",
140
            "http://wiki.mikrokopter.de/ErrorCodes#A35_.22FAILSAFE_pos..21__.22",
141
            "http://wiki.mikrokopter.de/ErrorCodes#A36_.22ERR:Redundancy__.22",
142
            "http://wiki.mikrokopter.de/ErrorCodes#A37_.22Redundancy_test_.22",
143
            "http://wiki.mikrokopter.de/ErrorCodes#A38_.22GPS_Update_rate.22",
144
            "http://wiki.mikrokopter.de/ErrorCodes#A39_.22ERR:Canbus.22",
145
            "http://wiki.mikrokopter.de/ErrorCodes#A40_.22ERR:_5V_RC-Supply.22",
146
            "http://wiki.mikrokopter.de/ErrorCodes#A41_.22ERR:Power-Supply.22",
147
            "http://wiki.mikrokopter.de/ErrorCodes#A42_.22ACC_not_calibr..22",
148
            "http://wiki.mikrokopter.de/ErrorCodes#A43_.22ERR:Parachute.21.22"
149
        };
150
 
2324 - 151
        #endregion NC-Errors
2287 - 152
        [FlagsAttribute]
153
        enum NC_HWError0 : short
154
        {
155
            None = 0,
156
            SPI_RX = 1,
157
            COMPASS_RX = 2,
158
            FC_INCOMPATIBLE = 4,
159
            COMPASS_INCOMPATIBLE = 8,
160
            GPS_RX = 16,
161
            COMPASS_VALUE = 32
162
        };
163
        [FlagsAttribute]
164
        enum FC_HWError0 : short
165
        {
166
            None = 0,
167
            GYRO_NICK = 1,
168
            GYRO_ROLL = 2,
169
            GYRO_YAW = 4,
170
            ACC_NICK = 8,
171
            ACC_ROLL = 16,
172
            ACC_TOP = 32,
173
            PRESSURE = 64,
174
            CAREFREE = 128
175
        };
176
        [FlagsAttribute]
177
        enum FC_HWError1 : short
178
        {
179
            None = 0,
180
            I2C = 1,
181
            BL_MISSING = 2,
182
            SPI_RX = 4,
183
            PPM = 8,
184
            MIXER = 16,
185
            RC_VOLTAGE = 32,
186
            ACC_NOT_CAL = 64,
187
            RES3 = 128
188
        };
189
        public enum LogMsgType { Incoming, Outgoing, Normal, Warning, Error };
190
        // Various colors for logging info
191
        private Color[] LogMsgTypeColor = { Color.FromArgb(255, 43, 145, 175), Colors.Green, Colors.Black, Colors.Orange, Colors.Red };
192
 
193
        bool _bCBInit = true;
194
        bool _init = true;
195
        bool check_HWError = false;
196
 
197
        string filePath = Directory.GetCurrentDirectory();
198
        bool bReadContinously = false;
199
        bool _debugDataAutorefresh = true;
200
        bool _navCtrlDataAutorefresh = true;
201
        bool _blctrlDataAutorefresh = true;
202
        bool _OSDAutorefresh = true;
203
        bool _bErrorLog = false;
204
        bool _bConnErr = false;
205
        bool _bFollowCopter = false;
2324 - 206
        bool _bGPXLog = false;
2376 - 207
        bool _Simulate = false;
2287 - 208
 
209
        bool _bSaveWinStateNormal = true;
210
        bool _bSaveWinStateFull = true;
211
 
212
        double scaleNormalAll = 1;
213
        double scaleNormalTopBar = 1;
214
        double scaleNormalMotors = 1;
215
        double scaleNormalOSD = 1;
216
        double scaleNormalLOG = 1;
217
        double scaleNormalHorizon = 1;
218
 
219
        double scaleFullAll = 1;
220
        double scaleFullTopBar = 1;
221
        double scaleFullMotors = 1;
222
        double scaleFullOSD = 1;
223
        double scaleFullLOG = 1;
224
        double scaleFullHorizon = 1;
225
 
226
        int _iCtrlAct = 0;
227
        int iOSDPage = 0;
228
        int iOSDMax = 0;
229
        int _iLifeCounter = 0;
230
        int crcError = 0;
231
 
2291 - 232
        bool _bSatFix = false;
233
        Storyboard stbSatFixLostAnim;
234
        bool _bAnimSatFixActive = false;
235
        bool _bVoiceSatFixActive = false;
236
        bool _bVoiceSatFixPlay = false;
237
        int _iSatsLast = 0;
238
        int _iSatsJitter = 0;
239
 
240
        bool _bMagneticFieldOK = false;
241
        Storyboard stbMagneticFieldAnim;
242
        bool _bAnimMagneticFieldActive = false;
243
        bool _bVoiceMagneticFieldActive = false;
244
        bool _bVoiceMagneticFieldPlay = false;
245
        int _iMagneticFieldLast = 0;
246
        int _iMagneticFieldJitter = 0;
247
 
248
        bool _bRCLevelOK = false;
249
        Storyboard stbRCLevelAnim;
250
        bool _bAnimRCLevelActive = false;
251
        bool _bVoiceRCLevelActive = false;
252
        bool _bVoiceRCLevelPlay = false;
253
        int _iRCLevelLast = 0;
254
        int _iRCLevelJitter = 0;
255
 
2287 - 256
        int _iMotors = 4;
257
        int _LipoCells = 4;
258
 
259
        double _dLipoVMax = 16.88;
260
        double _dLipoVMin = 12;
261
        double _dThresholdVoltageWarn = 0;
262
        double _dThresholdVoltageCrit = 0;
263
        Storyboard stbVoltageCritAnim;
264
        bool _bCritAnimVoltActive = false;
265
        bool _bCritVoiceVoltActive = false;
2291 - 266
        bool _bWarnVoiceVoltActive = false;
2287 - 267
        bool _bVoiceVoltPlay = false;
268
        double _dVoltLast = 0;
269
        int _iVoltJitter = 0;
270
 
2291 - 271
        double _dThresholdDistanceWarn = 100;
272
        Storyboard stbDistanceWarnAnim;
273
        bool _bAnimDistanceActive = false;
274
        bool _bVoiceDistanceActive = false;
275
        bool _bVoiceDistancePlay = false;
276
        double _dDistanceLast = 0;
277
        int _iDistanceJitter = 0;
278
 
279
        double _dThresholdDistanceMax = 1000;
280
        int _iThresholdRC = 160;
281
        int _iThresholdMagField = 15;
282
 
2295 - 283
        bool _bAutoHome = false;
284
        bool _bFirstSatFix = false;
285
        int _iFirstSatFix = 0;
2291 - 286
 
2287 - 287
        double _dTopHeight = 36;
288
 
289
        int[] serChan = new int[12] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
290
        int[] serChan_sub = new int[12] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
291
        string[] serChanTitle = new string[12];
292
 
293
        string[] sAnalogLabel = new string[32];
294
        string[] sAnalogData = new string[32];
2324 - 295
        int[] iAnalogData = new int[32];
2287 - 296
 
297
        int[] iTimings = new int[] {100,150,200,250,300,350,400,450,500,550,600,650,700,750,800,850,900,950,1000,1100,1200,1300,1400,1500,1600,1700,1800,1900,2000 };
298
        int[] iMotors = new int[] {3,4,5,6,7,8,9,10,11,12 };
299
        string[] sLiPoCells = new string[] { "3s", "4s", "5s", "6s" };
300
        /// <summary>
301
        /// interval for sending debugdata (multiplied by 10ms)
302
        /// </summary>
303
        byte debugInterval = 10; //(=> 100ms)
304
        /// <summary>
305
        /// interval for sending BL-CTRL status (multiplied by 10ms)
306
        /// </summary>
307
        byte blctrlInterval = 75;
308
        /// <summary>
309
        /// interval for sending NAV-CTRL status (multiplied by 10ms)
310
        /// </summary>
311
        byte navctrlInterval = 80;
312
        /// <summary>
313
        /// interval for sending OSD page update (multiplied by 10ms)
314
        /// </summary>
315
        byte OSDInterval = 85;
316
        /// <summary>
317
        /// datatable for the debug data array - displayed on settings tabpage in datagridview
318
        /// </summary>
319
        DataTable dtAnalog = new DataTable();
320
        /// <summary>
321
        /// datatable for motordata (current,temp)
322
        /// </summary>
2315 - 323
        DataTable dtMotors = new DataTable();
2287 - 324
 
325
        DataTable dtWaypoints = new DataTable();
2313 - 326
        static volatile int _iWPCount = -1;
327
        static volatile int _iWPIndex = -1;
328
        int _iWPTimeout = 1000;
2287 - 329
        bool _bGetWP = false;
2328 - 330
        bool _bShowWPRoute = false;
2287 - 331
        static volatile bool _bGetWPCount = false;
2324 - 332
        DataTable dtGPX = new DataTable();
333
        DataRow drGPX;
334
        bool _bAirborne = false;
2355 - 335
        int _wpIndex = -1, _wpCount = 0, _wpEdit = -1;
2340 - 336
 
2287 - 337
        DispatcherTimer timer = new DispatcherTimer();
338
 
339
        /// <summary>
340
        /// stuff for enabeling touch zoom for the map
341
        /// </summary>
342
        Point pTouch1 = new Point(0,0), pTouch2 = new Point(0,0);
343
        int iFirstStylusID = -1;
344
        public string connectButtonText
345
        {
346
            get
347
            {
348
                return bReadContinously ? "stop polling data" + System.Environment.NewLine + "from copter" : "start polling data" + System.Environment.NewLine + "from copter";
349
            }
350
        }
351
 
352
        WinState winState = new WinState();
2304 - 353
        #endregion declarations
2287 - 354
        public MainWindow()
355
        {
356
            InitializeComponent();
357
            _initForm();
358
            _dataTablesInit();
359
            _setupMap();
360
            _init = false;
361
            timer.Tick += new EventHandler(timerEvent);
362
            timer.Interval = new TimeSpan(0, 0, 1);
363
            timer.Start();
364
        }
365
 
366
        #region init
367
        void _initForm()
368
        {
369
            _readIni();
370
            if (_bSaveWinStateNormal)
371
                _setScaleSliders(false);
372
            cBoxTimingsDebug.ItemsSource =
373
                cBoxTimingsNav.ItemsSource =
374
                cBoxTimingsBl.ItemsSource =
375
                cBoxTimingsOSD.ItemsSource =
376
                iTimings;
377
            cBoxLiPoCells.ItemsSource = sLiPoCells;
378
            cBoxLiPoCells.SelectedItem = _LipoCells.ToString() + "s";
379
            _LipoMinMax();
380
            sliderThresholdVoltageWarn.Value = _dThresholdVoltageWarn;
381
            sliderThresholdVoltageCrit.Value = _dThresholdVoltageCrit;
382
            checkBoxThresholdVoltageVoice.IsChecked = _bVoiceVoltPlay;
2291 - 383
            checkBoxSatfixLost.IsChecked = _bVoiceSatFixPlay;
384
            checkBoxMagneticField.IsChecked = _bVoiceMagneticFieldPlay;
385
            checkBoxThresholdDistanceVoice.IsChecked = _bVoiceDistancePlay;
386
            sliderThresholdDistanceWarn.Value = _dThresholdDistanceWarn;
387
            checkBoxRClevel.IsChecked = _bVoiceRCLevelPlay;
2287 - 388
 
2291 - 389
            sliderThresholdDistanceWarn.Maximum = _dThresholdDistanceMax;
390
 
2287 - 391
            cBoxMotors.ItemsSource = iMotors;
392
            cBoxMotors.SelectedItem = _iMotors;
393
 
394
            serialPortCtrl.PortClosed += serialPortCtrl_PortClosed;
395
            serialPortCtrl.PortOpened += serialPortCtrl_PortOpened;
396
            serialPortCtrl.DataReceived += processMessage;
397
 
398
            chkbAutoBL.IsChecked = _blctrlDataAutorefresh;
399
            chkbAutoDbg.IsChecked = _debugDataAutorefresh;
400
            chkbAutoNav.IsChecked = _navCtrlDataAutorefresh;
401
            chkbAutoOSD.IsChecked = _OSDAutorefresh;
402
 
403
            cBoxTimingsDebug.SelectedItem = debugInterval * 10;
404
            cBoxTimingsNav.SelectedItem = navctrlInterval * 10;
405
            cBoxTimingsBl.SelectedItem = blctrlInterval * 10;
406
            cBoxTimingsOSD.SelectedItem = OSDInterval * 10;
2295 - 407
            checkBoxAutoSetHP.IsChecked = _bAutoHome;
2287 - 408
            checkBoxFollowCopter.IsChecked = _bFollowCopter;
2324 - 409
            checkBoxGPXLog.IsChecked = _bGPXLog;
2328 - 410
            checkBoxShowWPRoute.IsChecked = _bShowWPRoute;
2287 - 411
 
2349 - 412
            _initSerialCtrl();
2287 - 413
        }
414
        /// <summary>
415
        /// initialize the datatables
416
        /// with columnnames etc
417
        /// </summary>
418
        void _dataTablesInit()
419
        {
2315 - 420
            dtMotors.Columns.Add("#");
2313 - 421
            if (Thread.CurrentThread.CurrentUICulture.Name == "de-DE")
2315 - 422
                dtMotors.Columns.Add("Strom");
2313 - 423
            else
2315 - 424
                dtMotors.Columns.Add("Current");
425
            dtMotors.Columns.Add("Temp");
426
            dgvMotors1.DataContext = dtMotors.DefaultView;
2287 - 427
            _initDTMotors();
428
 
429
            Setter setter = new Setter(ContentControl.PaddingProperty, new Thickness(5,0,5,0));
430
            Style style = new Style(typeof(System.Windows.Controls.Primitives.DataGridColumnHeader));
431
            style.Setters.Add(setter);
432
            setter = new Setter(ContentControl.BackgroundProperty, new SolidColorBrush(Colors.Transparent));
433
            style.Setters.Add(setter);
434
            setter = new Setter(ContentControl.ForegroundProperty, new SolidColorBrush(Colors.White));
435
            style.Setters.Add(setter);
2313 - 436
 
437
            dtWaypoints.Columns.Add("Index",typeof(int));
2315 - 438
            dtWaypoints.Columns.Add("Type", typeof(int));
2313 - 439
            dtWaypoints.Columns.Add("Name",typeof(string));
2315 - 440
            dtWaypoints.Columns.Add("Latitude",typeof(double));
441
            dtWaypoints.Columns.Add("Longitude",typeof(double));
2313 - 442
            dtWaypoints.Columns.Add("Altitude",typeof(string));
443
            dtWaypoints.Columns.Add("Heading",typeof(string));
444
            dtWaypoints.Columns.Add("Speed",typeof(string));
445
            dtWaypoints.Columns.Add("ClimbRate",typeof(string));
446
            dtWaypoints.Columns.Add("Radius",typeof(string));
447
            dtWaypoints.Columns.Add("HoldTime",typeof(string));
448
            dtWaypoints.Columns.Add("AutoTrigger",typeof(string));
449
            dtWaypoints.Columns.Add("CamAngle",typeof(string));
450
            dtWaypoints.Columns.Add("Event",typeof(string));
451
            dtWaypoints.Columns.Add("Out1Timer",typeof(string));
452
            dtWaypoints.Columns.Add("Status",typeof(string));
453
            dtWaypoints.PrimaryKey = new DataColumn[] { dtWaypoints.Columns["Index"] };
454
            dgvWP.ItemsSource = dtWaypoints.DefaultView;
2287 - 455
            dgvWP.ColumnHeaderStyle = new Style();
456
            dgvWP.ColumnHeaderStyle = style;
2313 - 457
 
2324 - 458
            dtGPX.Columns.Add("Index",typeof(int));
459
            dtGPX.Columns.Add("Latitude",typeof(double));
460
            dtGPX.Columns.Add("Longitude",typeof(double));
461
            dtGPX.Columns.Add("Elevation",typeof(int));
462
            dtGPX.Columns.Add("Time",typeof(string));
463
            dtGPX.PrimaryKey = new DataColumn[] { dtGPX.Columns["Index"] };
464
            drGPX = dtGPX.NewRow();
2313 - 465
 
2287 - 466
        }
467
        /// <summary>
2315 - 468
        /// initialize the datatable dtMotors for motor values
2313 - 469
        /// DataGridView dgvMotors1 is bound to dtMotors1
2287 - 470
        /// </summary>
471
        void _initDTMotors()
472
        {
473
            for (int i = 0; i < 12; i++)
474
            {
2315 - 475
                if (dtMotors.Rows.Count < 12)
476
                    dtMotors.Rows.Add((i + 1).ToString(), "NA", "NA");
2287 - 477
                else
478
                {
2315 - 479
                    dtMotors.Rows[i].SetField(1, "NA");
480
                    dtMotors.Rows[i].SetField(2, "NA");
2287 - 481
                }
482
            }
483
        }
484
 
485
        #endregion init
486
 
487
        #region events
488
        private void serialPortCtrl_PortOpened()
489
        {
490
            Dispatcher.Invoke(() => imageWiFi.Source = new BitmapImage(new Uri("Images/WiFi_G.png", UriKind.Relative)));
491
            _getVersion();
492
            Thread.Sleep(100);
493
            //_OSDMenue(0);
494
            //Thread.Sleep(200);
495
            //_sendSerialData();
496
            _readCont(true);
497
        }
498
        private void serialPortCtrl_PortClosed()
499
        {
500
            Dispatcher.Invoke(() => imageWiFi.Source = new BitmapImage(new Uri("Images/WiFi_W.png", UriKind.Relative)));
501
            _readCont(false);
502
        }
2324 - 503
        bool _bToggle = false;
2287 - 504
        void timerEvent(object sender, EventArgs e)
505
        {
506
            if (bReadContinously)
507
            {
508
                if (_debugDataAutorefresh) { _readDebugData(true); Thread.Sleep(10); }
509
 
510
                if (_blctrlDataAutorefresh) { _readBLCtrl(true); Thread.Sleep(10); }
511
 
512
                if (_navCtrlDataAutorefresh && _iCtrlAct == 2) { _readNavData(true); Thread.Sleep(10); }
513
                check_HWError = true;
514
                _getVersion();
515
                Thread.Sleep(10);
516
                if (_OSDAutorefresh)
517
                {
518
                    if (iOSDMax == 0 | cbOSD.Items.Count != iOSDMax)
519
                        _initOSDCB();
520
                    _OSDMenueAutoRefresh();
521
                }
522
                if (_iLifeCounter > 0)
523
                {
524
                    Dispatcher.Invoke(() => imageConn.Source = new BitmapImage(new Uri("Images/Data_G.png", UriKind.Relative)));
525
                  //  Dispatcher.Invoke((Action)(() => rctConnection.Fill = Brushes.LightGreen));
526
                    _iLifeCounter = 0;
527
                    _bConnErr = false;
2327 - 528
                    if(_bAirborne && _bGPXLog)
2324 - 529
                    {
530
                        drGPX[0] = dtGPX.Rows.Count;
531
                        dtGPX.Rows.Add(new object[] { drGPX[0], drGPX[1], drGPX[2], drGPX[3], drGPX[4] });
532
                    }
2327 - 533
                    Dispatcher.Invoke((Action)(() => tbSideBarGPXLog.Background = (_bAirborne && _bGPXLog && _bToggle) ? new SolidColorBrush(Colors.LightSeaGreen) : new SolidColorBrush(Colors.Transparent)));
534
                    Dispatcher.Invoke((Action)(() => tbSideBarGPXLog.Foreground = (_bAirborne && _bGPXLog) ? new SolidColorBrush(Colors.White) : new SolidColorBrush(Color.FromArgb(255, 211, 210, 210))));
535
                    Dispatcher.Invoke((Action)(() => tbSideBarGPXLog.BorderBrush = (_bAirborne && _bGPXLog) ? new SolidColorBrush(Colors.White) : new SolidColorBrush(Color.FromArgb(255, 211, 210, 210))));
2324 - 536
                    _bToggle = !_bToggle;
2287 - 537
                }
538
                else
539
                {
540
                    if (!_bConnErr)
541
                    {
542
                        Log(LogMsgType.Error, "No communication to NC/FC!");
543
                        Dispatcher.Invoke(() => imageConn.Source = new BitmapImage(new Uri("Images/Data_R.png", UriKind.Relative)));
544
                       // Dispatcher.Invoke((Action)(() => rctConnection.Fill = Brushes.Red));
545
                        _bConnErr = true;
546
                    }
547
                }
548
            }
549
        }
550
 
551
        private void labelData_MouseDown(object sender, MouseButtonEventArgs e)
552
        {
553
            GridData.Visibility = GridData.Visibility == Visibility.Collapsed ? Visibility.Visible : Visibility.Collapsed;
554
            GridSettings.Visibility = GridWP.Visibility = Visibility.Collapsed;
555
        }
556
        private void labelMotorData_MouseDown(object sender, MouseButtonEventArgs e)
557
        {
558
            GridMotors.Visibility = GridMotors.Visibility == Visibility.Hidden ? Visibility.Visible : Visibility.Hidden;
559
            if (GridMotors.IsVisible)
560
                _setMotorGridSize();
561
        }
562
        private void labelSettings_MouseDown(object sender, MouseButtonEventArgs e)
563
        {
564
            GridData.Visibility = GridWP.Visibility = Visibility.Collapsed;
565
            GridSettings.Visibility = GridSettings.Visibility == Visibility.Collapsed ? Visibility.Visible : Visibility.Collapsed;
566
        }
567
        private void labelLog_MouseDown(object sender, MouseButtonEventArgs e)
568
        {
569
            GridLog.Visibility = GridLog.Visibility == Visibility.Collapsed ? Visibility.Visible : Visibility.Collapsed;
570
        }
571
        private void labelOSD_MouseDown(object sender, MouseButtonEventArgs e)
572
        {
573
            GridOSD.Visibility = GridOSD.Visibility == Visibility.Hidden ? Visibility.Visible : Visibility.Hidden;
574
        }
575
        private void labelWaypoints_MouseDown(object sender, MouseButtonEventArgs e)
576
        {
577
            GridData.Visibility = GridSettings.Visibility = Visibility.Collapsed;
578
            GridWP.Visibility = GridWP.Visibility == Visibility.Collapsed ? Visibility.Visible : Visibility.Collapsed;
579
        }
580
 
581
        private void btnGetWP_Click(object sender, RoutedEventArgs e)
582
        {
583
            Thread t = new Thread(new ThreadStart(_getWP));
584
            t.Start();
585
        }
586
        private void btnSendWPList_Click(object sender, RoutedEventArgs e)
587
        {
2313 - 588
            Thread t = new Thread(new ThreadStart(_sendWPList));
589
            t.Start();
2287 - 590
        }
591
 
592
        private void btnConnectToCopter_Click(object sender, RoutedEventArgs e)
593
        {
594
            if (!serialPortCtrl.Port.IsOpen)
595
                serialPortCtrl.Connect(true);
596
            else
597
                _readCont(!bReadContinously);
598
        }
599
        private void btnSetHP_Click(object sender, RoutedEventArgs e)
600
        {
2347 - 601
            _setHomePos();
2287 - 602
        }
603
        private void btnClearHP_Click(object sender, RoutedEventArgs e)
604
        {
2347 - 605
            _clearHomePos();
2287 - 606
        }
607
        private void btnGotoHP_Click(object sender, RoutedEventArgs e)
608
        {
609
            if (home != null && MainMap.Markers.Contains(home))
610
                MainMap.Position = home.Position;
611
        }
2295 - 612
        private void checkBoxAutoSetHP_Click(object sender, RoutedEventArgs e)
613
        {
614
            _bAutoHome = (bool)checkBoxAutoSetHP.IsChecked;
615
        }
2287 - 616
        private void chkBoxSaveNormalState_Click(object sender, RoutedEventArgs e)
617
        {
618
            _bSaveWinStateNormal = (bool)chkBoxSaveNormalState.IsChecked;
619
        }
620
        private void chkBoxSaveFullScreenState_Click(object sender, RoutedEventArgs e)
621
        {
622
            _bSaveWinStateFull = (bool)chkBoxSaveFullScreenState.IsChecked;
623
        }
624
 
2291 - 625
        #region thresholds
2287 - 626
        private void sliderThresholdVoltageWarn_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
627
        {
628
            if(!_init)
629
                _dThresholdVoltageWarn = sliderThresholdVoltageWarn.Value;
630
        }
631
        private void sliderThresholdVoltageCrit_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
632
        {
633
            if(!_init)
634
                _dThresholdVoltageCrit = sliderThresholdVoltageCrit.Value;
635
        }
636
        private void checkBoxThresholdVoltageVoice_Click(object sender, RoutedEventArgs e)
637
        {
638
            _bVoiceVoltPlay = (bool)checkBoxThresholdVoltageVoice.IsChecked;
639
        }
2291 - 640
 
641
        private void sliderThresholdDistanceWarn_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
642
        {
643
            if(!_init)
644
                _dThresholdDistanceWarn = sliderThresholdDistanceWarn.Value;
645
        }
646
        private void checkBoxThresholdDistanceVoice_Click(object sender, RoutedEventArgs e)
647
        {
648
            _bVoiceDistancePlay = (bool)checkBoxThresholdDistanceVoice.IsChecked;
649
        }
650
 
651
        private void checkBoxSatfixLost_Click(object sender, RoutedEventArgs e)
652
        {
653
            _bVoiceSatFixPlay = (bool)checkBoxSatfixLost.IsChecked;
654
        }
655
        private void checkBoxMagneticField_Click(object sender, RoutedEventArgs e)
656
        {
657
            _bVoiceMagneticFieldPlay = (bool)checkBoxMagneticField.IsChecked;
658
        }
659
        private void checkBoxRClevel_Click(object sender, RoutedEventArgs e)
660
        {
661
            _bVoiceRCLevelPlay = (bool)checkBoxRClevel.IsChecked;
662
        }
663
        #endregion thresholds
664
 
2287 - 665
        private void buttonSwitchNC_Click(object sender, RoutedEventArgs e)
666
        {
667
            _switchToNC();
668
        }
669
 
670
        private void Window_Loaded(object sender, RoutedEventArgs e)
671
        {
672
            stbVoltageCritAnim = TryFindResource("VoltageCritAnim") as Storyboard;
2291 - 673
            stbSatFixLostAnim = TryFindResource("SatFixLostAnim") as Storyboard;
674
            stbMagneticFieldAnim = TryFindResource("MagneticFieldCritAnim") as Storyboard;
675
            stbDistanceWarnAnim = TryFindResource("DistanceCritAnim") as Storyboard;
676
            stbRCLevelAnim = TryFindResource("RCCritAnim") as Storyboard;
2287 - 677
            _setMotorGridSize();
678
        }
2310 - 679
        private void Window_Closing(object sender, CancelEventArgs e)
680
        {
681
            _writeIni();
2324 - 682
            if(_bGPXLog && dtGPX.Rows.Count > 0)
683
                _saveGPXLog();
2310 - 684
        }
2379 - 685
        private void Window_Closed(object sender, EventArgs e)
686
        {
687
            Application.Current.Shutdown();
688
        }
689
 
2287 - 690
        #endregion events
691
 
692
        #region GMap
693
 
694
        void _setupMap()
695
        {
696
            MainMap.Manager.Mode = AccessMode.ServerAndCache;
697
            MainMap.MapProvider = GMapProviders.BingHybridMap;
698
            MainMap.SetPositionByKeywords("Landshut");
699
            MainMap.MinZoom = 0;
700
            MainMap.MaxZoom = 24;
701
            MainMap.Zoom = 16;
702
            MainMap.ShowCenter = true;
703
            MainMap.ShowTileGridLines = false;
704
            sliderMapZoom.Value = 16;
705
            comboBoxMapType.ItemsSource = providerList;
706
            comboBoxMapType.DisplayMemberPath = "Name";
707
            comboBoxMapType.SelectedItem = MainMap.MapProvider;
708
 
709
            // acccess mode
710
            comboBoxMode.ItemsSource = Enum.GetValues(typeof(AccessMode));
711
            comboBoxMode.SelectedItem = MainMap.Manager.Mode;
712
 
713
        }
714
 
715
        /// <summary>
716
        /// selection of relevant map providers --> if You need more, You can change the line:
717
        ///     comboBoxMapType.ItemsSource = providerList; 
718
        /// to:
719
        ///     comboBoxMapType.ItemsSource = GMapProviders.List;
720
        /// in _setupMap()
721
        /// or add items here:
722
        /// </summary>
723
        List<GMap.NET.MapProviders.GMapProvider> providerList = new List<GMap.NET.MapProviders.GMapProvider>
724
        { GMap.NET.MapProviders.GMapProviders.OpenCycleMap, GMap.NET.MapProviders.GMapProviders.OpenCycleLandscapeMap, GMap.NET.MapProviders.GMapProviders.OpenCycleTransportMap,
725
        GMap.NET.MapProviders.GMapProviders.BingMap,GMap.NET.MapProviders.GMapProviders.BingSatelliteMap,GMap.NET.MapProviders.GMapProviders.BingHybridMap,
726
        GMap.NET.MapProviders.GMapProviders.GoogleMap,GMap.NET.MapProviders.GMapProviders.GoogleSatelliteMap,GMap.NET.MapProviders.GMapProviders.GoogleHybridMap,GMap.NET.MapProviders.GMapProviders.GoogleTerrainMap,
727
        GMap.NET.MapProviders.GMapProviders.OviMap,GMap.NET.MapProviders.GMapProviders.OviSatelliteMap,GMap.NET.MapProviders.GMapProviders.OviHybridMap,GMap.NET.MapProviders.GMapProviders.OviTerrainMap};
728
 
729
        private void MainMap_Loaded(object sender, RoutedEventArgs e)
730
        {
731
            MainMap.Manager.Mode = AccessMode.ServerAndCache;
732
            copter = new GMapMarker(MainMap.Position);
2318 - 733
 
734
            copter.Shape = new CustomMarkerCopter(this, copter, MainMap.Position.Lat.ToString("0.#######°") + System.Environment.NewLine + MainMap.Position.Lng.ToString("0.#######°"),"red");
735
            if (comboBoxCopterColor.SelectionBoxItem != null)
736
            {
737
                string s = comboBoxCopterColor.SelectionBoxItem.ToString();
2385 - 738
                ((CustomMarkerCopter)(copter.Shape)).setCopterColor(s);
2318 - 739
            }
2385 - 740
            Dispatcher.Invoke(() => {
741
                if (comboBoxCopterHeadingColor.SelectionBoxItem != null)
742
                {
743
                    string s = comboBoxCopterHeadingColor.SelectionBoxItem.ToString();
744
                    ((CustomMarkerCopter)(copter.Shape)).setHeadingColor(s);
745
                }
746
            });
2405 - 747
            copter.Offset = new System.Windows.Point(-26, -26);
2287 - 748
            copter.ZIndex = int.MaxValue;
749
            MainMap.Markers.Add(copter);
750
            copter.Position = MainMap.Position;
751
        }
2347 - 752
        void _setHomePos()
2287 - 753
        {
754
            pHome = MainMap.Position;
755
            if (!MainMap.Markers.Contains(home))
756
            {
757
                home = new GMapMarker(MainMap.Position);
758
                home.Shape = new CustomMarkerHome(this, home, MainMap.Position.Lat.ToString("0.#######°") + System.Environment.NewLine + MainMap.Position.Lng.ToString("0.#######°"));
2405 - 759
                home.Offset = new System.Windows.Point(-16.5, -16.5);
2287 - 760
                // home.ZIndex = int.MaxValue;
761
                MainMap.Markers.Add(home);
762
            }
763
            home.Position = MainMap.Position;
764
            ((CustomMarkerHome)(home.Shape)).setText(MainMap.Position.Lat.ToString("0.#######°") + System.Environment.NewLine + MainMap.Position.Lng.ToString("0.#######°"));
2405 - 765
 
766
            if (checkBoxShowWPMaxRange.IsChecked == true)
767
            {
768
                if (cWPBound != null && cWPBound.Tag != null)
769
                    MainMap.Markers.Remove(cWPBound.Tag as GMapMarker);
770
 
771
                createCircle(home.Position, dWPMaxRange);
2408 - 772
                Dispatcher.Invoke(() =>
773
                {
774
                    if (comboBoxWPMaxRangeColor.SelectionBoxItem != null)
775
                    {
776
                        string s = comboBoxWPMaxRangeColor.SelectionBoxItem.ToString();
777
                        cWPBound.setColor(s);
778
                    }
779
                });
2405 - 780
            }
781
 
2287 - 782
        }
2347 - 783
        void _setActiveWP(int iIndex)
2287 - 784
        {
2347 - 785
            if (wpActiveMarker == null || !MainMap.Markers.Contains(wpActiveMarker))
786
            {
787
                Dispatcher.Invoke(() =>
788
                {
789
                    wpActiveMarker = new GMapMarker(wpList[iIndex]);
790
                    wpActiveMarker.Shape = new CustomMarkerWPActive(this, wpActiveMarker, "wpActive", 0);
791
                    wpActiveMarker.Offset = new Point(-17.5, -17.5);
792
                    MainMap.Markers.Add(wpActiveMarker);
793
                });
794
            }
795
            else
796
                Dispatcher.Invoke(() => wpActiveMarker.Position = wpList[iIndex]);
797
 
2401 - 798
            Dispatcher.Invoke(() => tbWPStatusHeight.Text = dtWaypoints.Rows[iIndex][5].ToString() + " m");
2347 - 799
        }
800
        void _clearHomePos()
801
        {
2287 - 802
            MainMap.Markers.Remove(home);
2405 - 803
            if (cWPBound != null && cWPBound.Tag != null)
804
                MainMap.Markers.Remove(cWPBound.Tag as GMapMarker);
2287 - 805
        }
2335 - 806
        void _clearMapMarkers(Type markerType)
807
        {
808
            for (int k = 0; k < MainMap.Markers.Count;)
809
            {
810
                GMapMarker p = MainMap.Markers[k];
2340 - 811
                if (p.GetType() == markerType | (p.Shape != null && p.Shape.GetType() == markerType))
2335 - 812
                    MainMap.Markers.Remove(p);
813
                else
814
                    k++;
815
            }
2287 - 816
 
2335 - 817
        }
2369 - 818
 
819
        GMapMarker _findWPMarker(string name)
2368 - 820
        {
821
            for (int k = 0; k < MainMap.Markers.Count;)
822
            {
823
                GMapMarker p = MainMap.Markers[k];
824
                if (p.GetType() == typeof(CustomMarkerWP) | (p.Shape != null && p.Shape.GetType() == typeof(CustomMarkerWP)))
2369 - 825
                    if (((CustomMarkerWP)p.Shape).WPText == name)
826
                        return p;
2368 - 827
                    else
828
                        k++;
829
                else
830
                    k++;
831
            }
2369 - 832
            return null;
2368 - 833
        }
2369 - 834
        void _clearWPMarker(string name)
835
        {
836
            GMapMarker p = _findWPMarker(name);
837
            if(p != null)
838
                MainMap.Markers.Remove(p);
839
        }
2368 - 840
        void _renameWPMarker(string s1, string s2)
841
        {
2369 - 842
            GMapMarker p = _findWPMarker(s1);
843
            if (p != null)
844
                ((CustomMarkerWP)p.Shape).WPText = s2;
2368 - 845
        }
2372 - 846
        void _WPMarkerSetType(string text, int type)
847
        {
848
            GMapMarker p = _findWPMarker(text);
849
            if (p != null)
850
                ((CustomMarkerWP)p.Shape).WPType = type;
851
        }
2369 - 852
        void _repositionWPMarker(PointLatLng point, string name)
853
        {
854
            GMapMarker p = _findWPMarker(name);
855
            if (p != null)
856
                p.Position = point;
857
        }
858
 
2405 - 859
        void createCircle(PointLatLng center, double distance)
860
        {
861
 
862
            GMapMarker it = new GMapMarker(center);
863
            it.ZIndex = -1;
864
 
865
            cWPBound.Center = center;
866
            cWPBound.Bound = GMap.NET.PureProjection.GetPointFromDistance(center, distance);
867
            cWPBound.Tag = it;
868
            cWPBound.IsHitTestVisible = false;
869
            UpdateCircle(cWPBound);
870
            it.Shape = cWPBound;
871
            MainMap.Markers.Add(it);
872
        }
873
        // calculates circle radius
874
        void UpdateCircle(Circle c)
875
        {
876
            var pxCenter = MainMap.FromLatLngToLocal(c.Center);
877
            var pxBounds = MainMap.FromLatLngToLocal(c.Bound);
878
 
879
            double a = (double)(pxBounds.X - pxCenter.X);
880
            double b = (double)(pxBounds.Y - pxCenter.Y);
881
            var pxCircleRadius = Math.Sqrt(a * a + b * b);
882
 
883
            c.Width = c.Height = pxCircleRadius * 2;
884
            //c.Width = 55 + pxCircleRadius * 2;
885
            //c.Height = 55 + pxCircleRadius * 2;
886
            (c.Tag as GMapMarker).Offset = new System.Windows.Point(-c.Width / 2, -c.Height / 2);
887
        }
888
 
2287 - 889
        // access mode
890
        private void comboBoxMode_DropDownClosed(object sender, EventArgs e)
891
        {
892
            MainMap.Manager.Mode = (AccessMode)comboBoxMode.SelectedItem;
893
            MainMap.ReloadMap();
894
        }
895
        // zoom up
896
        private void czuZoomUp_Click(object sender, RoutedEventArgs e)
897
        {
898
            MainMap.Zoom = ((int)MainMap.Zoom) + 1;
899
        }
900
 
901
        // zoom down
902
        private void czuZoomDown_Click(object sender, RoutedEventArgs e)
903
        {
904
            MainMap.Zoom = ((int)(MainMap.Zoom + 0.99)) - 1;
905
        }
906
 
907
        // prefetch
908
        private void buttonPrefetch_Click(object sender, RoutedEventArgs e)
909
        {
910
            RectLatLng area = MainMap.SelectedArea;
911
            if (!area.IsEmpty)
912
            {
913
                for (int i = (int)MainMap.Zoom; i <= MainMap.MaxZoom; i++)
914
                {
915
                    MessageBoxResult res = MessageBox.Show("Ready ripp at Zoom = " + i + " ?", "GMap.NET", MessageBoxButton.YesNoCancel);
916
 
917
                    if (res == MessageBoxResult.Yes)
918
                    {
919
                        TilePrefetcher obj = new TilePrefetcher();
920
                        obj.Owner = this;
921
                        obj.ShowCompleteMessage = true;
922
                        obj.Start(area, i, MainMap.MapProvider, 100);
923
                    }
924
                    else if (res == MessageBoxResult.No)
925
                    {
926
                        continue;
927
                    }
928
                    else if (res == MessageBoxResult.Cancel)
929
                    {
930
                        break;
931
                    }
932
                }
933
            }
934
            else
935
            {
936
                MessageBox.Show("Select map area holding ALT", "GMap.NET", MessageBoxButton.OK, MessageBoxImage.Exclamation);
937
            }
938
        }
939
 
940
        // goto by geocoder
941
        private void buttonGeoCoding_Click(object sender, RoutedEventArgs e)
942
        {
943
            _goto_byGeoCoder();
944
        }
945
        // goto by geocoder
946
        private void textBoxGeo_KeyUp(object sender, System.Windows.Input.KeyEventArgs e)
947
        {
948
            if (e.Key == System.Windows.Input.Key.Enter)
949
                _goto_byGeoCoder();
950
        }
951
        void _goto_byGeoCoder()
952
        {
953
            GeoCoderStatusCode status = MainMap.SetPositionByKeywords(textBoxGeo.Text);
954
            if (status != GeoCoderStatusCode.G_GEO_SUCCESS)
955
            {
956
                MessageBox.Show("Geocoder can't find: '" + textBoxGeo.Text + "', reason: " + status.ToString(), "GMap.NET", MessageBoxButton.OK, MessageBoxImage.Exclamation);
957
            }
958
        }
959
        private void buttonGeoLoc_Click(object sender, RoutedEventArgs e)
960
        {
961
            try
962
            {
963
                double lat = double.Parse(textBoxLat.Text, System.Globalization.CultureInfo.InvariantCulture);
964
                double lng = double.Parse(textBoxLng.Text, System.Globalization.CultureInfo.InvariantCulture);
965
 
966
                MainMap.Position = new PointLatLng(lat, lng);
967
            }
968
            catch (Exception ex)
969
            {
970
                MessageBox.Show("incorrect coordinate format: " + ex.Message);
971
            }
972
 
973
        }
974
 
975
        private void ReloadMap_Click(object sender, RoutedEventArgs e)
976
        {
977
            MainMap.ReloadMap();
978
        }
979
 
980
        private void MainMap_OnPositionChanged(PointLatLng point)
981
        {
982
            if (_bFollowCopter)
983
                _setCopterData(MainMap.Position);
984
        }
985
 
986
        private void MainMap_OnMapZoomChanged()
987
        {
988
            if (_bFollowCopter)
989
                _setCopterData(MainMap.Position);
990
            if((int)sliderMapZoom.Value != MainMap.Zoom)
991
                sliderMapZoom.Value = MainMap.Zoom;
2405 - 992
            if(cWPBound != null && cWPBound.Tag != null)
993
                UpdateCircle(cWPBound);
2287 - 994
        }
995
 
996
        void _setCopterData(PointLatLng p)
997
        {
998
            Dispatcher.Invoke(() =>
999
            {
1000
                copter.Position = p;
1001
                ((CustomMarkerCopter)(copter.Shape)).setText(p.Lat.ToString("0.#######°") + System.Environment.NewLine + p.Lng.ToString("0.#######°"));
1002
                textBoxLat_currentPos.Text = p.Lat.ToString() + "°";
1003
                textBoxLng_currentPos.Text = p.Lng.ToString() + "°";
1004
            });
1005
            if (home != null && MainMap.Markers.Contains(home))
1006
            {
1007
                Dispatcher.Invoke(() => ArtHor.rotateHome = GMapProviders.EmptyProvider.Projection.GetBearing(copter.Position, home.Position));
1008
                double d = GMapProviders.EmptyProvider.Projection.GetDistance(home.Position, copter.Position);
1009
                Dispatcher.Invoke(() => tbTopDistanceHP.Text = (d * 1000).ToString("0.0 m"));
2291 - 1010
 
1011
                if(d*1000 < _dThresholdDistanceWarn)
1012
                {
1013
                    _iDistanceJitter = 0; _bVoiceDistanceActive = false;
1014
                    if (stbDistanceWarnAnim != null && _bAnimDistanceActive)
1015
                    {
1016
                        Dispatcher.Invoke(() => stbDistanceWarnAnim.Stop());
1017
                        _bAnimDistanceActive = false;
1018
                    }
1019
                }
1020
                else
1021
                {
1022
                    if (_iDistanceJitter < 20)
1023
                    { _iDistanceJitter++; }
1024
                    if (_iDistanceJitter == 20)
1025
                    {
1026
                        if (stbDistanceWarnAnim != null && !_bAnimDistanceActive)
1027
                        {
1028
                            Dispatcher.Invoke(() => stbDistanceWarnAnim.Begin());
1029
                            _bAnimDistanceActive = true;
1030
                        }
1031
                        if (_bVoiceDistancePlay && !_bVoiceDistanceActive)
1032
                        {
2398 - 1033
                            ThreadPool.QueueUserWorkItem(new WaitCallback(_mediaPlayer), "Voice\\Distance.mp3");
1034
                            //Thread t = new Thread(()=>_mediaPlayer("Voice\\Distance.mp3"));
1035
                            //t.Start();
2291 - 1036
                            _bVoiceDistanceActive = true;
1037
                        }
1038
                        _iDistanceJitter++;
1039
                    }
1040
                }
2287 - 1041
            }
1042
        }
1043
 
1044
        private void checkBoxFollowCopter_Click(object sender, RoutedEventArgs e)
1045
        {
1046
            _bFollowCopter = (bool)checkBoxFollowCopter.IsChecked;
1047
        }
1048
 
1049
        private void sliderMapZoom_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
1050
        {
1051
            if (MainMap.Zoom != sliderMapZoom.Value)
1052
                MainMap.Zoom = (int)sliderMapZoom.Value;
1053
        }
1054
        #region Touch zooming hackattack ;) 
1055
        /// <summary>
1056
        /// inspired by http://www.codeproject.com/Articles/692286/WPF-and-multi-touch
1057
        /// </summary>
1058
        bool bFirstAccess = true;
1059
        double dDistance = 0;
1060
        int iZoom;
1061
        private void MainMap_StylusDown(object sender, StylusDownEventArgs e)
1062
        {
1063
            var id = e.StylusDevice.Id;
1064
            e.StylusDevice.Capture(MainMap);
1065
            if (iFirstStylusID == -1)
1066
            {
1067
                iFirstStylusID = id;
1068
            }
1069
            else
1070
            {
1071
 
1072
                MainMap.CanDragMap = false;
1073
            }
1074
        }
1075
        private void MainMap_StylusUp(object sender, StylusEventArgs e)
1076
        {
1077
            MainMap.ReleaseStylusCapture();
1078
            iFirstStylusID = -1;
1079
            bFirstAccess = true;
1080
            MainMap.CanDragMap = true;
1081
            iZoom = 0;
1082
        }
1083
        private void MainMap_StylusMove(object sender, StylusEventArgs e)
1084
        {
1085
            var id = e.StylusDevice.Id;
1086
            var tp = e.GetPosition(MainMap);
1087
 
1088
            // This is the first Stylus point; just record its position. 
1089
            if (id == iFirstStylusID)
1090
            {
1091
                pTouch1.X = tp.X;
1092
                pTouch1.Y = tp.Y;
1093
            }
1094
            else
1095
            if (iFirstStylusID > -1)
1096
            {
1097
                pTouch2.X = tp.X;
1098
                pTouch2.Y = tp.Y;
1099
                double distance = Point.Subtract(pTouch1, pTouch2).Length;
1100
                if (!bFirstAccess)
1101
                {
1102
                    if (distance > dDistance)
1103
                        iZoom++;
1104
                    else
1105
                        if (distance < dDistance)
1106
                        iZoom--;
1107
                }
1108
                if (iZoom > 30)
1109
                {
1110
                    iZoom = 0;
1111
                    Dispatcher.Invoke(() => sliderMapZoom.Value += 1);
1112
                }
1113
                if (iZoom < -30)
1114
                {
1115
                    iZoom = 0;
1116
                    Dispatcher.Invoke(() => sliderMapZoom.Value -= 1);
1117
                }
1118
                dDistance = distance;
1119
                bFirstAccess = false;
1120
            }
1121
        }
1122
        #endregion Touch zooming hackattack ;)
1123
 
1124
        #endregion GMap
1125
 
1126
        #region settings
1127
        private void cBoxTimingsDebug_DropDownClosed(object sender, EventArgs e)
1128
        {
1129
            if(! _bCBInit && cBoxTimingsDebug.SelectedIndex > -1)
1130
                debugInterval = (byte)(Convert.ToInt16(cBoxTimingsDebug.SelectedItem) / 10);
1131
        }
1132
        private void cBoxTimingsNav_DropDownClosed(object sender, EventArgs e)
1133
        {
1134
            if(! _bCBInit && cBoxTimingsNav.SelectedIndex > -1)
1135
                navctrlInterval = (byte)(Convert.ToInt16(cBoxTimingsNav.SelectedItem) / 10);
1136
        }
1137
        private void cBoxTimingsBl_DropDownClosed(object sender, EventArgs e)
1138
        {
1139
            if (!_bCBInit && cBoxTimingsBl.SelectedIndex > -1)
1140
                blctrlInterval = (byte)(Convert.ToInt16(cBoxTimingsBl.SelectedItem) / 10);
1141
        }
1142
        private void cBoxTimingsOSD_DropDownClosed(object sender, EventArgs e)
1143
        {
1144
            if (!_bCBInit && cBoxTimingsOSD.SelectedIndex > -1)
1145
                OSDInterval = (byte)(Convert.ToInt16(cBoxTimingsOSD.SelectedItem) / 10);
1146
        }
1147
        private void chkbAutoDbg_Click(object sender, RoutedEventArgs e)
1148
        {
1149
            if (!_init) _debugDataAutorefresh = (bool)chkbAutoDbg.IsChecked;
1150
        }
1151
        private void chkbAutoNav_Click(object sender, RoutedEventArgs e)
1152
        {
1153
            if (!_init) _navCtrlDataAutorefresh = (bool)chkbAutoNav.IsChecked;
1154
        }
1155
        private void chkbAutoBL_Click(object sender, RoutedEventArgs e)
1156
        {
1157
            if (!_init) _blctrlDataAutorefresh = (bool)chkbAutoBL.IsChecked;
1158
        }
1159
        private void chkbAutoOSD_Click(object sender, RoutedEventArgs e)
1160
        {
1161
            if (!_init) _OSDAutorefresh = (bool)chkbAutoOSD.IsChecked;
1162
        }
1163
 
1164
        private void cBoxLiPoCells_DropDownClosed(object sender, EventArgs e)
1165
        {
1166
            if (cBoxLiPoCells.SelectedIndex > -1)
1167
            {
1168
                _LipoCells = cBoxLiPoCells.SelectedIndex + 3;
1169
                _LipoMinMax();
1170
            }
1171
        }
1172
        void _LipoMinMax()
1173
        {
1174
            _dLipoVMax = (double)(_LipoCells) * 4.22;
1175
            _dLipoVMin = (double)_LipoCells * 3;
1176
            pbTopVoltage.Maximum = _dLipoVMax;
1177
            pbTopVoltage.Minimum = _dLipoVMin;
1178
            sliderThresholdVoltageWarn.Maximum = _dLipoVMax;
1179
            sliderThresholdVoltageWarn.Minimum = _dLipoVMin;
1180
        }
1181
        private void cBoxMotors_DropDownClosed(object sender, EventArgs e)
1182
        {
1183
            if (cBoxMotors.SelectedIndex > -1)
1184
            {
1185
                _iMotors = cBoxMotors.SelectedIndex + 3;
1186
                Dispatcher.Invoke(() =>
1187
                {
1188
                    dgvMotors1.Height = (272 / 12.6) * (_iMotors + 1);  //272 / 12.6 --> Workaround, cause the headerheight = NaN...?
1189
                    GridMotors.Height = dgvMotors1.Height + 10;
1190
                });
1191
            }
1192
        }
1193
        void _setMotorGridSize()
1194
        {
1195
            if (dgvMotors1.Columns.Count > 2)
1196
            {
1197
                dgvMotors1.Columns[0].Width = 24;
1198
                dgvMotors1.Columns[1].Width = 50;
1199
                dgvMotors1.Columns[2].Width = 50;
1200
                dgvMotors1.Height = (272 / 12.6) * (_iMotors + 1);
1201
                GridMotors.Height = dgvMotors1.Height + 10;
1202
            }
1203
 
1204
        }
1205
        #endregion settings
1206
 
1207
        #region functions  
1208
 
1209
        #region logging      
1210
        /// <summary> Log data to the terminal window. </summary>
1211
        /// <param name="msgtype"> The type of message to be written. </param>
1212
        /// <param name="msg"> The string containing the message to be shown. </param>
1213
        private void Log(LogMsgType msgtype, string msg)
1214
        {
1215
            Dispatcher.Invoke(() =>
1216
            {
1217
               // rtfTerminal.CaretPosition = rtfTerminal.CaretPosition.DocumentEnd;
1218
               // rtfTerminal.Foreground = new SolidColorBrush(LogMsgTypeColor[(int)msgtype]);
1219
//                rtfTerminal.AppendText(msg + "\r");
1220
                TextRange tr = new TextRange(rtfTerminal.Document.ContentEnd,rtfTerminal.Document.ContentEnd);
1221
                tr.Text = msg;
1222
                tr.ApplyPropertyValue(TextElement.ForegroundProperty, new SolidColorBrush(LogMsgTypeColor[(int)msgtype]));
1223
                rtfTerminal.AppendText("\r");
1224
                rtfTerminal.ScrollToEnd();
1225
            });
1226
        }
2381 - 1227
        private void ErrorLog(LogMsgType msgtype, string msg , string linkURL, string linkName)
2287 - 1228
        {
2381 - 1229
 
2287 - 1230
            Dispatcher.Invoke(() =>
1231
            {
2381 - 1232
                Paragraph para = new Paragraph();
1233
                para.Margin = new Thickness(0); // remove indent between paragraphs
1234
 
1235
                Hyperlink link = new Hyperlink();
1236
                if (linkURL != "" && linkName != "")
1237
                {
1238
                    link.IsEnabled = true;
1239
                    link.Inlines.Add(linkName);
1240
                    link.NavigateUri = new Uri(linkURL);
1241
                    link.RequestNavigate += (sender, args) => Process.Start(args.Uri.ToString());
1242
                }
1243
                //msg = DateTime.Now.ToLongTimeString() + msg;
1244
                para.Foreground = new SolidColorBrush(LogMsgTypeColor[(int)msgtype]);
1245
                Run r = new Run("[" + DateTime.Now.ToLongTimeString() + "]: ");
1246
                r.Foreground = new SolidColorBrush(Colors.Black);
1247
                para.Inlines.Add(r);
1248
                para.Inlines.Add(msg);
1249
                para.Inlines.Add(link);
1250
                rtfError.Document.Blocks.Add(para);
1251
                //TextRange tr = new TextRange(rtfError.Document.ContentEnd, rtfError.Document.ContentEnd);
1252
                //tr.Text = msg + link;
1253
                //tr.ApplyPropertyValue(TextElement.ForegroundProperty, new SolidColorBrush(LogMsgTypeColor[(int)msgtype]));
1254
                //rtfError.AppendText("\r");
2287 - 1255
                rtfError.ScrollToEnd();
1256
 
2381 - 1257
                //_bErrorLog = true;
2287 - 1258
            });
1259
        }
1260
        /// <summary>
1261
        /// Clear the line in the  errorlog window 
1262
        /// containing the error string when error has ceased
1263
        /// </summary>
1264
        /// <param name="s">substring of errrormessage</param>
1265
        void _clearErrorLog(string s)
1266
        {
1267
            Dispatcher.Invoke((Action)(() =>
1268
            {
1269
                TextRange searchRange = new TextRange(rtfError.Document.ContentStart, rtfError.Document.ContentEnd);
1270
                TextRange foundRange = FindTextInRange(searchRange, s);
1271
 
1272
                int iStart = searchRange.Text.IndexOf(s, StringComparison.OrdinalIgnoreCase);
1273
 
1274
 
1275
                if (iStart > -1)
1276
                {
1277
                    int iLength = 0;
1278
                    int iEnd = searchRange.Text.IndexOf('\r', iStart);
1279
                    if (iEnd > 0)
1280
                    {
1281
                        iLength = iEnd + 1;
1282
                        int iHttp = searchRange.Text.IndexOf("http", iEnd);
1283
                        if (iHttp == iLength)
1284
                        {
1285
                            int iEnd2 = searchRange.Text.IndexOf('\r', iLength);
1286
                            if (iEnd2 > iLength)
1287
                            {
1288
                                iLength = iEnd2 + 1;
1289
                              //  TextRange result = new TextRange(rtfError.Document.ContentStart.GetPositionAtOffset(iStart), GetTextPositionAtOffset(rtfError.Document.ContentStart.GetPositionAtOffset(iStart), iLength));
1290
 
1291
                                rtfError.Selection.Select(rtfError.Document.ContentStart.GetPositionAtOffset(iStart), GetTextPositionAtOffset(rtfError.Document.ContentStart.GetPositionAtOffset(iStart), iLength));
1292
                                rtfError.Selection.Text = string.Empty;
1293
                                if (rtfError.Document.ContentEnd.GetTextRunLength(LogicalDirection.Backward) < 2) _bErrorLog = false;
1294
                            }
1295
 
1296
                        }
1297
                        else
1298
                        {
1299
                            rtfError.Selection.Select(rtfError.Document.ContentStart.GetPositionAtOffset(iStart), GetTextPositionAtOffset(rtfError.Document.ContentStart.GetPositionAtOffset(iStart), iLength));
1300
                            rtfError.Selection.Text = string.Empty;
1301
                            if (rtfError.Document.ContentEnd.GetTextRunLength(LogicalDirection.Backward) < 2) _bErrorLog = false;
1302
                        }
1303
                    }
1304
                }
1305
            }));
1306
 
1307
        }
1308
        public TextRange FindTextInRange(TextRange searchRange, string searchText)
1309
        {
1310
            int offset = searchRange.Text.IndexOf(searchText, StringComparison.OrdinalIgnoreCase);
1311
            if (offset < 0)
1312
                return null;  // Not found
1313
 
1314
            var start = GetTextPositionAtOffset(searchRange.Start, offset);
1315
            TextRange result = new TextRange(start, GetTextPositionAtOffset(start, searchText.Length));
1316
 
1317
            return result;
1318
        }
1319
        TextPointer GetTextPositionAtOffset(TextPointer position, int characterCount)
1320
        {
1321
            while (position != null)
1322
            {
1323
                if (position.GetPointerContext(LogicalDirection.Forward) == TextPointerContext.Text)
1324
                {
1325
                    int count = position.GetTextRunLength(LogicalDirection.Forward);
1326
                    if (characterCount <= count)
1327
                    {
1328
                        return position.GetPositionAtOffset(characterCount);
1329
                    }
1330
 
1331
                    characterCount -= count;
1332
                }
1333
 
1334
                TextPointer nextContextPosition = position.GetNextContextPosition(LogicalDirection.Forward);
1335
                if (nextContextPosition == null)
1336
                    return position;
1337
 
1338
                position = nextContextPosition;
1339
            }
1340
 
1341
            return position;
1342
        }
1343
        #endregion logging
1344
 
1345
        #region processing received data
1346
 
1347
        private void processMessage(byte[] message)
1348
        {
1349
            if (message.Length > 0)
1350
            {
1351
                _iLifeCounter++;
1352
                //Log(LogMsgType.Incoming, BitConverter.ToString(message));
1353
                //Log(LogMsgType.Incoming, message.Length.ToString());
1354
                string s = new string(ASCIIEncoding.ASCII.GetChars(message, 0, message.Length));
1355
                char cmdID;
1356
                byte adr;
1357
                byte[] data;
1358
                byte[] tmp = null;
1359
                if (message[0] != '#')
1360
                {
1361
                    int iFound = -1;
1362
                    for (int i = 0; i < message.Length; i++)   //Sometimes the FC/NC sends strings without termination (like WP messages)
1363
                    {                                   //so this is a workaround to not spam the log box
1364
                        if (message[i] == 35)
1365
                        {
1366
                            iFound = i;
1367
                            break;
1368
                        }
1369
                    }
1370
                    if (iFound > 0)
1371
                    {
1372
                        s = new string(ASCIIEncoding.ASCII.GetChars(message, 0, iFound));
1373
                        tmp = new byte[message.Length - iFound];
1374
                        Buffer.BlockCopy(message, iFound, tmp, 0, message.Length - iFound);
1375
                    }
1376
                    s = s.Trim('\0', '\n', '\r');
1377
                    if (s.Length > 0)
1378
                        Log(LogMsgType.Normal, s);
1379
                    if (tmp != null)
1380
                    {
1381
                        s = new string(ASCIIEncoding.ASCII.GetChars(tmp, 0, tmp.Length));
1382
                        processMessage(tmp);
1383
                    }
1384
                }
1385
                //Debug.Print(s);
1386
                else
1387
                {
1388
                    FlightControllerMessage.ParseMessage(message, out cmdID, out adr, out data);
1389
 
1390
                    if (adr == 255) { crcError++; }
1391
                    else crcError = 0;
1392
                    Dispatcher.Invoke(() => tbCrc.Text = crcError.ToString());
1393
                    //display the active controller (FC / NC) 
1394
                    if (adr > 0 && adr < 3 && adr != _iCtrlAct) //adr < 3: temporary workaround cause when I've connected the FC alone it always switches between mk3mag & FC every second...???
1395
                    {
1396
                        _iCtrlAct = adr;
1397
                        switch (adr)
1398
                        {
1399
                            case 1:
1400
                                Dispatcher.Invoke(() => tbCtrl.Text = "FC");
2381 - 1401
                               // Dispatcher.Invoke(() => buttonSwitchNC.Visibility = Visibility.Visible);
1402
                               // Dispatcher.Invoke(() => labelSwitchToNavi.Visibility = Visibility.Visible);
2287 - 1403
                              //  _setFieldsNA(); //display fields NA for FC 
1404
                                break;
1405
                            case 2:
1406
                                Dispatcher.Invoke(() => tbCtrl.Text = "NC");
1407
                                //Dispatcher.Invoke(() => buttonSwitchNC.Visibility = Visibility.Hidden);
1408
                                //Dispatcher.Invoke(() => labelSwitchToNavi.Visibility = Visibility.Hidden);
1409
                                break;
1410
                            //case 3:
1411
                            //    lblCtrl.Invoke((Action)(() => lblCtrl.Text = "MK3MAG"));
1412
                            //    break;
1413
                            //case 4:
1414
                            //    lblCtrl.Invoke((Action)(() => lblCtrl.Text = "BL-CTRL"));
1415
                            //    break;
1416
                            default:
1417
                                Dispatcher.Invoke(() => tbCtrl.Text = "NA");
1418
                                break;
1419
                        }
1420
                       // _loadLabelNames();
1421
                    }
1422
                    // else
1423
                    //     Debug.Print("Address == 0?");
1424
 
1425
                    if (data != null && data.Length > 0)
1426
                    {
1427
                        s = new string(ASCIIEncoding.ASCII.GetChars(data, 1, data.Length - 1));
1428
                        s = s.Trim('\0', '\n');
1429
 
1430
                        switch (cmdID)
1431
                        {
1432
                            //case 'A': //Label names
1433
                            //    _processLabelNames(s);
1434
                            //    break;
1435
 
1436
                            case 'D': //Debug data
1437
                                _processDebugVals(adr, data);
1438
                                break;
1439
 
1440
                            case 'V': //Version
1441
                                _processVersion(adr, data);
1442
                                break;
1443
 
1444
                            case 'K'://BL-CTRL data
1445
                                _processBLCtrl(data);
1446
                                break;
1447
 
1448
                            case 'O': //NC Data
1449
                                _processNCData(data);
1450
                                break;
1451
 
2381 - 1452
                            //case 'E': //NC error-string
1453
                            //    ErrorLog(LogMsgType.Error, "NC Error: " + s);
1454
                            //    break;
2287 - 1455
 
1456
                            case 'L': //OSD Menue (called by pagenumber)
1457
                                _processOSDSingle(data);
1458
                                break;
1459
 
1460
                            case 'H': //OSD Menue (with autoupdate - called by Key)
1461
                                _processOSDAuto(data);
1462
                                break;
1463
 
1464
                            case 'X': //Waypoint data
1465
                                _processWPData(data);
1466
                                break;
1467
 
2313 - 1468
                            case 'W': //return new Waypoint items count after sending waypoint to copter
1469
                                _iWPCount = data[0];
1470
                                break;
2287 - 1471
                                //default:
1472
                                //    Log(LogMsgType.Incoming, "cmd: " + cmdID.ToString());
1473
                                //    Log(LogMsgType.Incoming, BitConverter.ToString(data));
1474
                                //    break;
1475
                        }
1476
                    }
1477
                    //else
1478
                    //{
1479
                    //    Log(LogMsgType.Incoming, "cmd: " + cmdID.ToString());
1480
                    //    Log(LogMsgType.Incoming, BitConverter.ToString(data));
1481
                    //}
1482
                }
1483
            }
1484
        }
1485
        /// <summary>
1486
        /// Analog label names 'A'
1487
        /// each label name is returned as a single string 
1488
        /// and added to string array sAnalogLabel[]
1489
        /// and the datatable dtAnalog
1490
        /// </summary>
1491
        /// <param name="s">the label name</param>
1492
        void _processLabelNames(string s)
1493
        {
1494
            //if (iLableIndex < 32)
1495
            //{
1496
            //    sAnalogLabel[iLableIndex] = s;
1497
            //    if (dtAnalog.Rows.Count < 32)
1498
            //        dtAnalog.Rows.Add(s, "");
1499
            //    else
1500
            //        dtAnalog.Rows[iLableIndex].SetField(0, s);
1501
 
1502
            //  //  _getAnalogLabels(iLableIndex + 1);
1503
            //}
1504
            //Debug.Print(s);
1505
        }
1506
        /// <summary>
1507
        /// Debug values 'D'
1508
        /// </summary>
1509
        /// <param name="adr">adress of the active controller (1-FC, 2-NC)</param>
1510
        /// <param name="data">the received byte array to process</param>
1511
        void _processDebugVals(byte adr, byte[] data)
1512
        {
1513
            if (data.Length == 66)
1514
            {
2324 - 1515
 
2287 - 1516
                double v;
1517
                int index = 0;
1518
                Int16 i16 = 0;
1519
                double dTemp = 0;
1520
                for (int i = 2; i < 66; i += 2)
1521
                {
1522
                    i16 = data[i + 1];
1523
                    i16 = (Int16)(i16 << 8);
1524
                    iAnalogData[index] = data[i] + i16;
1525
                    sAnalogData[index] = (data[i] + i16).ToString();
1526
                   // dtAnalog.Rows[index].SetField(1, sAnalogData[index]);
1527
 
1528
                    if (adr == 2) //NC
1529
                    {
1530
                        switch (index)
1531
                        {
1532
                            case 0: //pitch (German: nick)
1533
                                Dispatcher.Invoke(() => ArtHor.Pitch = ((double)iAnalogData[index] / (double)10));
1534
                                Dispatcher.Invoke((Action)(() => tbPitch.Text = ((double)iAnalogData[index] / (double)10).ToString("0.0°")));
1535
                                break;
1536
                            case 1: //roll
1537
                                Dispatcher.Invoke(() => ArtHor.Roll = ((double)iAnalogData[index] / (double)10));
1538
                                Dispatcher.Invoke((Action)(() => tbRoll.Text = ((double)iAnalogData[index] / (double)10).ToString("0.0°")));
1539
                                break;
1540
                            case 4: //altitude
1541
                                Dispatcher.Invoke(() => tbAlt.Text = ((double)iAnalogData[index] / (double)10).ToString("0.0 m"));
1542
                                Dispatcher.Invoke(() => tbTopHeight.Text = ((double)iAnalogData[index] / (double)10).ToString("0.0 m"));
2324 - 1543
                                Dispatcher.Invoke(() => { drGPX[3] = (double)iAnalogData[index] / (double)10; });
2287 - 1544
                                break;
1545
                            case 7: //Voltage
1546
                                v = (double)iAnalogData[index] / (double)10;
1547
                                Dispatcher.Invoke(() => tbVolt.Text = v.ToString("0.0 V"));
1548
                                Dispatcher.Invoke(() => tbTopVoltage.Text = v.ToString("0.0 V"));
1549
                                Dispatcher.Invoke(() => pbTopVoltage.Value = v);
1550
                                if (v - _dLipoVMin < 1 | v < _dThresholdVoltageWarn)
1551
                                {
1552
                                    if (v == _dVoltLast)
1553
                                        if(_iVoltJitter < 20) _iVoltJitter++;
1554
                                    else
1555
                                    {
1556
                                        _iVoltJitter = 0;
1557
                                        _dVoltLast = v;
1558
                                    }
1559
                                    if (_iVoltJitter == 20)
1560
                                    {
1561
                                        Dispatcher.Invoke(() => pbTopVoltage.Foreground = Brushes.Orange);
1562
 
1563
                                        if (v - _dLipoVMin < 1 | v < _dThresholdVoltageCrit)
1564
                                        {
1565
                                            Dispatcher.Invoke(() => pbTopVoltage.Foreground = Brushes.Red);
1566
                                            if (stbVoltageCritAnim != null && !_bCritAnimVoltActive)
1567
                                            {
1568
                                                Dispatcher.Invoke(() => stbVoltageCritAnim.Begin());
1569
                                                _bCritAnimVoltActive = true;
1570
                                            }
1571
                                            if (_bVoiceVoltPlay && !_bCritVoiceVoltActive)
1572
                                            {
2398 - 1573
                                                ThreadPool.QueueUserWorkItem(new WaitCallback(_mediaPlayer), "Voice\\CriticalBattery.mp3");
1574
                                                //Thread t = new Thread(() => _mediaPlayer("Voice\\CriticalBattery.mp3"));
1575
                                                //t.Start();
2287 - 1576
                                                _bCritVoiceVoltActive = true;
1577
                                            }
1578
                                        }
1579
                                        else
1580
                                        {
1581
                                            if (stbVoltageCritAnim != null && _bCritAnimVoltActive)
1582
                                            {
1583
                                                Dispatcher.Invoke(() => stbVoltageCritAnim.Stop());
1584
                                                _bCritAnimVoltActive = false;
1585
                                            }
1586
                                            _bCritVoiceVoltActive = false;
1587
 
2291 - 1588
                                            if (_bVoiceVoltPlay && !_bWarnVoiceVoltActive)
2287 - 1589
                                            {
2398 - 1590
                                                ThreadPool.QueueUserWorkItem(new WaitCallback(_mediaPlayer), "Voice\\LowBattery.mp3");
1591
                                                //Thread t = new Thread(() => _mediaPlayer("Voice\\LowBattery.mp3"));
1592
                                                //t.Start();
2291 - 1593
                                                _bWarnVoiceVoltActive = true;
2287 - 1594
                                            }
1595
                                        }
1596
                                    }
1597
                                }
1598
                                else
1599
                                {
1600
                                    Dispatcher.Invoke(() => pbTopVoltage.Foreground = new SolidColorBrush(Color.FromArgb(255, 107, 195, 123)));
1601
                                    if (stbVoltageCritAnim != null && _bCritAnimVoltActive)
1602
                                    {
1603
                                        Dispatcher.Invoke(() => stbVoltageCritAnim.Stop());
1604
                                        _bCritAnimVoltActive = false;
1605
                                    }
1606
                                    _bCritVoiceVoltActive = false;
2291 - 1607
                                    _bWarnVoiceVoltActive = false;
2287 - 1608
                                    _iVoltJitter = 0;
1609
                                }
1610
                                break;
1611
                            case 8: // Current
1612
                                Dispatcher.Invoke(() => tbCur.Text = ((double)iAnalogData[index] / (double)10).ToString("0.0 A"));
1613
                                Dispatcher.Invoke(() => tbTopCurrent.Text = ((double)iAnalogData[index] / (double)10).ToString("0.0 A"));
1614
                                break;
1615
                            case 10: //heading
2291 - 1616
                                Dispatcher.Invoke((Action)(() => tbHeading.Text = sAnalogData[index] + "°"));
2399 - 1617
                                if (!_Simulate) //use NavData for simulation
1618
                                {
1619
                                    Dispatcher.Invoke(() => ArtHor.rotate = iAnalogData[index]);
1620
                                    Dispatcher.Invoke(() => ((CustomMarkerCopter)(copter.Shape)).rotate = iAnalogData[index]);
1621
                                }
2287 - 1622
                                break;
1623
                            case 12: // SPI error
2291 - 1624
                                Dispatcher.Invoke((Action)(() => tbSPI.Text = sAnalogData[index]));
2287 - 1625
                                break;
1626
                            case 14: //i2c error
2291 - 1627
                                Dispatcher.Invoke((Action)(() => tbI2C.Text = sAnalogData[index]));
2287 - 1628
                                break;
1629
                            case 20: //Earthmagnet field
2291 - 1630
                                Dispatcher.Invoke((Action)(() => tbMagF.Text = sAnalogData[index] + "%"));
1631
                                Dispatcher.Invoke((Action)(() => tbTopEarthMag.Text = sAnalogData[index] + "%"));
1632
 
1633
                                if (Math.Abs(100 - iAnalogData[index]) < _iThresholdMagField)
1634
                                {
1635
                                    Dispatcher.Invoke(() => imageEarthMag.Source = new BitmapImage(new Uri("Images/EarthMag.png", UriKind.Relative)));
1636
                                    _iMagneticFieldJitter = 0; _bVoiceMagneticFieldActive = false;
1637
                                    if (stbMagneticFieldAnim != null && _bAnimMagneticFieldActive)
1638
                                    {
1639
                                        Dispatcher.Invoke(() => stbMagneticFieldAnim.Stop());
1640
                                        _bAnimMagneticFieldActive = false;
1641
                                    }
1642
                                }
1643
                                else
1644
                                {
1645
                                    Dispatcher.Invoke(() => imageEarthMag.Source = new BitmapImage(new Uri("Images/EarthMag_R.png", UriKind.Relative)));
1646
                                    if(_iMagneticFieldLast >= Math.Abs(100 - iAnalogData[index]))
1647
                                    {
1648
                                        if (_iMagneticFieldJitter < 20)
1649
                                            _iMagneticFieldJitter++;
1650
                                    }
1651
                                    else
1652
                                    {
1653
                                        _iMagneticFieldJitter = 0;
1654
                                        _iMagneticFieldLast = Math.Abs(100 - iAnalogData[index]);
1655
                                    }
1656
                                    if(_iMagneticFieldJitter == 20)
1657
                                    {
1658
                                        if (stbMagneticFieldAnim != null && !_bAnimMagneticFieldActive)
1659
                                        {
1660
                                            Dispatcher.Invoke(() => stbMagneticFieldAnim.Begin());
1661
                                            _bAnimMagneticFieldActive = true;
1662
                                        }
1663
                                        if (_bVoiceMagneticFieldPlay && !_bVoiceMagneticFieldActive)
1664
                                        {
2398 - 1665
                                            ThreadPool.QueueUserWorkItem(new WaitCallback(_mediaPlayer), "Voice\\MagneticField.mp3");
1666
                                            //Thread t = new Thread(() => _mediaPlayer("Voice\\MagneticField.mp3"));
1667
                                            //t.Start();
2291 - 1668
                                            _bVoiceMagneticFieldActive = true;
1669
                                        }
1670
                                    }
1671
                                }
2287 - 1672
                                break;
1673
                            case 21: //GroundSpeed
1674
                                     Dispatcher.Invoke((Action)(() => tbSpeed.Text = ((double)iAnalogData[index] / (double)100).ToString("0.00 m/s")));
2399 - 1675
                                    if (!_Simulate)
1676
                                        Dispatcher.Invoke((Action)(() => tbTopSpeed.Text = ((double)iAnalogData[index] / (double)100).ToString("0.00 m/s")));
2287 - 1677
                                break;
2291 - 1678
 
1679
                            ///**********   needs testing --> not sure what position this is  ***************
2287 - 1680
                            case 28: //Distance East from saved home position -> calculate distance with distance N + height
1681
                                    dTemp = Math.Pow((double)iAnalogData[index], 2) + Math.Pow((double)iAnalogData[index - 1], 2);
1682
                                    dTemp = Math.Sqrt(dTemp) / (double)10; //'flat' distance from HP with N/E
1683
                                                                           //  lblNCDist.Invoke((Action)(() => lblNCDist.Text = dTemp.ToString("0.00")));
1684
                                    dTemp = Math.Pow(dTemp, 2) + Math.Pow(((double)iAnalogData[4] / (double)10), 2); //adding 'height' into calculation
1685
                                    dTemp = Math.Sqrt(dTemp) / (double)10;
1686
                               //     Dispatcher.Invoke((Action)(() => tbTopDistanceHP.Text = dTemp.ToString("0.0 m")));
1687
                                    Dispatcher.Invoke((Action)(() => tbHP1.Text = dTemp.ToString("0.0 m")));
1688
                                break;
2291 - 1689
 
2287 - 1690
                            case 31: //Sats used
1691
                                     Dispatcher.Invoke((Action)(() => tbSats.Text = sAnalogData[index]));
1692
                                    // Dispatcher.Invoke((Action)(() => tbTopSats.Text = sAnalogData[index]));                                   
1693
                                break;
1694
                        }
1695
                    }
1696
                    index++;
1697
                }
1698
            }
1699
            else
1700
                Debug.Print("wrong data-length (66): " + data.Length.ToString());
1701
        }
1702
        /// <summary>
1703
        /// Version string 'V'
1704
        /// </summary>
1705
        /// <param name="adr">adress of the active controller (1-FC, 2-NC)</param>
1706
        /// <param name="data">the received byte array to process</param>
1707
        void _processVersion(byte adr, byte[] data)
1708
        {
1709
            if (data.Length == 12)
1710
            {
1711
                if (!check_HWError)
1712
                {
1713
                    string[] sVersionStruct = new string[10] { "SWMajor: ", "SWMinor: ", "ProtoMajor: ", "LabelTextCRC: ", "SWPatch: ", "HardwareError 1: ", "HardwareError 2: ", "HWMajor: ", "BL_Firmware: ", "Flags: " };
1714
                    string sVersion = "";
1715
                    //sbyte[] signed = Array.ConvertAll(data, b => unchecked((sbyte)b));
1716
                    Log(LogMsgType.Warning, (adr == 1 ? "FC-" : "NC-") + "Version: ");
1717
                    sVersion = "HW V" + (data[7] / 10).ToString() + "." + (data[7] % 10).ToString();
1718
                    Log(LogMsgType.Incoming, sVersion);
1719
                    sVersion = "SW V" + (data[0]).ToString() + "." + (data[1]).ToString() + ((char)(data[4] + 'a')).ToString();
1720
                    Log(LogMsgType.Incoming, sVersion);
1721
                    Log(LogMsgType.Incoming, "BL-Firmware: V" + (data[8] / 100).ToString() + "." + (data[8] % 100).ToString());
1722
                }
1723
                if (data[5] > 0) //error0 
1724
                {
1725
                    if (adr == 1)
2381 - 1726
                        ErrorLog(LogMsgType.Error, " FC - HW-Error " + data[5].ToString() + ": " + ((FC_HWError0)data[5]).ToString(),"","");
2287 - 1727
                    if (adr == 2)
2381 - 1728
                        ErrorLog(LogMsgType.Error, " NC - HW-Error " + data[5].ToString() + ": " + ((NC_HWError0)data[5]).ToString(),"","");
2287 - 1729
                }
1730
                if (data[6] > 0) //error1 
1731
                {
1732
                    if (adr == 1)
2381 - 1733
                        ErrorLog(LogMsgType.Error, " FC - HW-Error " + data[6].ToString() + ": " + ((FC_HWError1)data[6]).ToString(),"","");
2287 - 1734
                    if (adr == 2)
2381 - 1735
                        ErrorLog(LogMsgType.Error, " NC - Unknown HW-ERROR: " + data[6].ToString(),"",""); //@moment NC has only one error field
2287 - 1736
                }
2381 - 1737
                //if ((data[5] + data[6] == 0) && _bErrorLog)
1738
                //    _clearErrorLog(adr == 1 ? "FC - HW-Error" : "NC - HW-Error");
2287 - 1739
 
1740
            }
1741
            check_HWError = false;
1742
        }
1743
        /// <summary>
1744
        /// BL-Ctrl data 'K'
1745
        /// for FC you have to use a customized firmware
1746
        /// </summary>
1747
        /// <param name="data">the received byte array to process</param>
1748
        void _processBLCtrl(byte[] data)
1749
        {
1750
            if (data.Length % 6 == 0) //data.Length up to 96 (16 motors x 6 byte data) --> new datastruct in FC -> not standard!
1751
            {
1752
                bool bAvailable = false;
1753
                for (int i = 0; i < data.Length && data[i] < _iMotors; i += 6) // data[i] < _iMotors -- only show set number of motors (12 max @ moment)
1754
                {
1755
 
1756
                    if ((data[i + 4] & 128) == 128) //Status bit at pos 7 = 128 dec -- if true, motor is available
1757
                        bAvailable = true;
1758
                    else
1759
                        bAvailable = false;
1760
 
1761
                    if (data[i] < _iMotors)
1762
                    {
1763
                        if (bAvailable)
1764
                        {
2315 - 1765
                            dtMotors.Rows[data[i]].SetField(1, ((double)data[i + 1] / (double)10).ToString("0.0 A"));
1766
                            dtMotors.Rows[data[i]].SetField(2, data[i + 2].ToString("0 °C"));
2287 - 1767
                        }
1768
                        else
1769
                        {
2315 - 1770
                            dtMotors.Rows[data[i]].SetField(1, "NA");
1771
                            dtMotors.Rows[data[i]].SetField(2, "NA");
2287 - 1772
                        }
1773
                    }
1774
                    //if (data[i] > 3 && data[i] < 8)
1775
                    //{
1776
                    //    if (bAvailable)
1777
                    //    {
1778
                    //        dtMotors2.Rows[data[i] - 4].SetField(1, ((double)data[i + 1] / (double)10).ToString("0.0 A"));
1779
                    //        dtMotors2.Rows[data[i] - 4].SetField(2, data[i + 2].ToString("0 °C"));
1780
                    //    }
1781
                    //    else
1782
                    //    {
1783
                    //        dtMotors2.Rows[data[i] - 4].SetField(1, "NA");
1784
                    //        dtMotors2.Rows[data[i] - 4].SetField(2, "NA");
1785
                    //    }
1786
                    //}
1787
                }
1788
            }
1789
        }
1790
        /// <summary>
1791
        /// Navi-Ctrl data 'O'
1792
        /// GPS-Position, capacatiy, flying time...
1793
        /// </summary>
1794
        /// <param name="data">the received byte array to process</param>
1795
        void _processNCData(byte[] data)
1796
        {
1797
            int i_32, i_16, iVal;
1798
            double d;
1799
            i_32 = data[4];
1800
            iVal = i_32 << 24;
1801
            i_32 = data[3];
1802
            iVal += i_32 << 16;
1803
            i_32 = data[2];
1804
            iVal += i_32 << 8;
1805
            iVal += data[1];
1806
            d = (double)iVal / Math.Pow(10, 7);
2324 - 1807
            Dispatcher.Invoke(() => { drGPX[2] = d; });
1808
 
2287 - 1809
            PointLatLng p = new PointLatLng();
1810
 
1811
            p.Lng = d;
1812
          //  lblNCGPSLong.Invoke((Action)(() => lblNCGPSLong.Text = d.ToString("0.######°"))); //GPS-Position: Longitude in decimal degree
1813
            //lblNCGPSLong.Invoke((Action)(() => lblNCGPSLong.Text = _convertDegree(d))); //GPS-Position: Longitude in minutes, seconds
1814
 
1815
            i_32 = data[8];
1816
            iVal = i_32 << 24;
1817
            i_32 = data[7];
1818
            iVal += i_32 << 16;
1819
            i_32 = data[6];
1820
            iVal += i_32 << 8;
1821
            iVal += data[5];
1822
            d = (double)iVal / Math.Pow(10, 7);
2324 - 1823
            Dispatcher.Invoke(() => { drGPX[1] = d; });
1824
            Dispatcher.Invoke(() => { drGPX[4] = DateTime.UtcNow.ToString("u", System.Globalization.CultureInfo.InvariantCulture); }); //2011-01-14T01:59:01Z });
2287 - 1825
            p.Lat = d;
2399 - 1826
 
2291 - 1827
            if (data[50] > 4)//if more than 4 sats in use . otherwise the map would jump and scroll insane at beginning
1828
            {
1829
                _bSatFix = true; _iSatsJitter = 0; _bVoiceSatFixActive = false;
2295 - 1830
                if(_bAutoHome && !_bFirstSatFix)
1831
                {
1832
                    if (_iFirstSatFix < 3)
1833
                        _iFirstSatFix++;
1834
                    else
1835
                    {
1836
                        _bFirstSatFix = true;
2347 - 1837
                        Dispatcher.Invoke(() => _setHomePos());
2295 - 1838
                    }
1839
                }
2291 - 1840
                if (stbSatFixLostAnim != null && _bAnimSatFixActive)
1841
                {
1842
                    Dispatcher.Invoke(() => stbSatFixLostAnim.Stop());
1843
                    _bAnimSatFixActive = false;
1844
                }
1845
                if (!_bFollowCopter)
1846
                {
1847
                    _setCopterData(p);
1848
                    if (!MainMap.ViewArea.Contains(p))
1849
                        Dispatcher.Invoke(() => MainMap.Position = p);
2287 - 1850
 
2291 - 1851
                }
1852
                else
2287 - 1853
                    Dispatcher.Invoke(() => MainMap.Position = p);
1854
            }
1855
            else
2291 - 1856
            {
1857
                if(_bSatFix)
1858
                {
1859
                    if (data[50] == _iSatsLast)
1860
                    {
1861
                        if (_iSatsJitter < 20) _iSatsJitter++;
1862
                    }
1863
                    else
1864
                    {
1865
                        _iSatsJitter = 0;
1866
                        _iSatsLast = data[50];
1867
                    }
2287 - 1868
 
2291 - 1869
                    if (_iSatsJitter == 20)
1870
                    {
1871
                        if (stbSatFixLostAnim != null && !_bAnimSatFixActive)
1872
                        {
1873
                            Dispatcher.Invoke(() => stbSatFixLostAnim.Begin());
1874
                            _bAnimSatFixActive = true;
1875
                        }
1876
                        if (_bVoiceSatFixPlay && !_bVoiceSatFixActive)
1877
                        {
2405 - 1878
                            _bVoiceSatFixActive = true;
2398 - 1879
                            ThreadPool.QueueUserWorkItem(new WaitCallback(_mediaPlayer), "Voice\\SatFixLost.mp3");
1880
                            //Thread th = new Thread(() => _mediaPlayer("Voice\\SatFixLost.mp3"));
1881
                            //th.Start();
2291 - 1882
                        }
1883
 
1884
                        _bSatFix = false;
1885
                    }
1886
                }
1887
            }
1888
 
2399 - 1889
            //Distance to next WP
2287 - 1890
            i_16 = data[28];
1891
            i_16 = (Int16)(i_16 << 8);
1892
            iVal = data[27] + i_16;
2399 - 1893
            Dispatcher.Invoke((Action)(() => tbWP.Text = ((double)iVal / (double)10).ToString("0.0 m")));
1894
            Dispatcher.Invoke((Action)(() => lblWPRouteDistanceWP.Content = ((double)iVal / (double)10).ToString("0.0 m")));
2401 - 1895
            Dispatcher.Invoke((Action)(() => tbWPStatusDistanceWP.Text = ((double)iVal / (double)10).ToString("0.0 m")));
2287 - 1896
 
1897
            i_16 = data[45];
1898
            i_16 = (Int16)(i_16 << 8);
1899
            iVal = data[44] + i_16;
1900
        //    Dispatcher.Invoke((Action)(() => tbTopDistanceHP.Text = ((double)iVal / (double)10).ToString("0.0 m"))); //Distance to HP set by GPS on
1901
            Dispatcher.Invoke((Action)(() => tbHP.Text = ((double)iVal / (double)10).ToString("0.0 m"))); //Distance to HP set by GPS on
1902
 
1903
            Dispatcher.Invoke((Action)(() => tbWPIndex.Text = data[48].ToString())); //Waypoint index
2355 - 1904
            Dispatcher.Invoke((Action)(() => lblWPIndexNC.Content = data[48].ToString()));
2401 - 1905
            Dispatcher.Invoke((Action)(() => lblWPStatusIndexNC.Content = data[48].ToString()));
2399 - 1906
            if(data[48] > 0 && _wpIndex != data[48] -1 && wpList.Count >= data[48] -1)
2342 - 1907
            {
2347 - 1908
                _setActiveWP(data[48]-1);
2355 - 1909
                if((data[67] & 2) == 2)
1910
                    Dispatcher.Invoke(() => {
1911
                        DataGridRow row;
1912
                        if (_wpIndex > -1)
1913
                        {
1914
                            row = (DataGridRow)dgvWP.ItemContainerGenerator.ContainerFromIndex(_wpIndex);
1915
                            row.Background = new SolidColorBrush(Colors.Transparent);
1916
                            row.BorderBrush = new SolidColorBrush(Colors.Transparent);
1917
                            row.BorderThickness = new Thickness(0);
1918
                        }
1919
                        _wpIndex = data[48] - 1;
1920
                        row = (DataGridRow)dgvWP.ItemContainerGenerator.ContainerFromIndex(_wpIndex);
2366 - 1921
                        row.Background = new SolidColorBrush(Color.FromArgb(80, 0, 255, 100));
1922
                        row.BorderBrush = new SolidColorBrush(Colors.SpringGreen);
2355 - 1923
                        row.BorderThickness = new Thickness(2);
1924
                        dgvWP.UpdateLayout();
1925
                    });
2347 - 1926
                _wpIndex = data[48]-1;
2342 - 1927
            }
2347 - 1928
            else
1929
            {
1930
                if ((data[48] == 0 || wpList.Count == 0) & MainMap.Markers.Contains(wpActiveMarker))
2355 - 1931
                {
2347 - 1932
                    Dispatcher.Invoke(() => MainMap.Markers.Remove(wpActiveMarker));
2355 - 1933
                    Dispatcher.Invoke(() =>
1934
                    {
1935
                        DataGridRow row;
2368 - 1936
                        if (_wpIndex > -1 && data[48] == 0 && wpList.Count > _wpIndex)
2355 - 1937
                        {
1938
                            row = (DataGridRow)dgvWP.ItemContainerGenerator.ContainerFromIndex(_wpIndex);
1939
                            row.Background = new SolidColorBrush(Colors.Transparent);
1940
                            row.BorderBrush = new SolidColorBrush(Colors.Transparent);
1941
                            row.BorderThickness = new Thickness(0);
1942
                            _wpIndex = -1;
1943
                        }
1944
                    });
1945
 
1946
                }
2347 - 1947
            }
2342 - 1948
 
2287 - 1949
            Dispatcher.Invoke((Action)(() => tbWPCount.Text = data[49].ToString())); //Waypoints count
2355 - 1950
            Dispatcher.Invoke((Action)(() => lblWPCountNC.Content = data[49].ToString())); //Waypoints count
2401 - 1951
            Dispatcher.Invoke((Action)(() => lblWPStatusCountNC.Content = data[49].ToString())); //Waypoints count
2340 - 1952
            _wpCount = data[49];
2287 - 1953
            Dispatcher.Invoke((Action)(() => tbTopSats.Text = data[50].ToString())); //Satellites
1954
 
1955
            //--------------- Capacity used ------------------------
1956
            i_16 = data[81];
1957
            i_16 = (Int16)(i_16 << 8);
1958
            iVal = data[80] + i_16;
1959
            Dispatcher.Invoke((Action)(() => tbCapacity.Text = iVal.ToString() + " mAh"));
1960
            Dispatcher.Invoke((Action)(() => tbTopCapacity.Text = iVal.ToString() + " mAh"));
1961
 
2398 - 1962
            //--------------- Ground speed ------------------------
1963
            i_16 = data[59];
1964
            i_16 = (Int16)(i_16 << 8);
1965
            iVal = data[58] + i_16;
2399 - 1966
            Dispatcher.Invoke((Action)(() => tbNCGrSpeed.Text = ((double)(iVal)/100).ToString("0.00 m/s")));
1967
            if(_Simulate)
1968
                Dispatcher.Invoke((Action)(() => tbTopSpeed.Text = ((double)(iVal)/100).ToString("0.00 m/s")));
2398 - 1969
 
1970
            //--------------- Heading north ------------------------
1971
            i_16 = data[61];
1972
            i_16 = (Int16)(i_16 << 8);
1973
            iVal = data[60] + i_16;
1974
            Dispatcher.Invoke((Action)(() => tbHeadingNorth.Text = iVal.ToString() + " °"));
1975
 
1976
            //--------------- Heading compass ------------------------
1977
            i_16 = data[63];
1978
            i_16 = (Int16)(i_16 << 8);
1979
            iVal = data[62] + i_16;
1980
            Dispatcher.Invoke((Action)(() => tbHeadingCompass.Text = iVal.ToString() + " °"));
2399 - 1981
            if (_Simulate)
1982
            {
1983
                Dispatcher.Invoke(() => ArtHor.rotate = iVal);
1984
                Dispatcher.Invoke(() => ((CustomMarkerCopter)(copter.Shape)).rotate = iVal);
1985
            }
2287 - 1986
            //--------------- Flying time ------------------------
1987
            i_16 = data[56];
1988
            i_16 = (Int16)(i_16 << 8);
1989
            iVal = data[55] + i_16;
1990
            TimeSpan t = TimeSpan.FromSeconds(iVal);
1991
            string Text = t.Hours.ToString("D2") + ":" + t.Minutes.ToString("D2") + ":" + t.Seconds.ToString("D2");
1992
            Dispatcher.Invoke((Action)(() => tbFTime.Text = Text.ToString()));
1993
            Dispatcher.Invoke((Action)(() => tbTopFTime.Text = Text.ToString()));
1994
 
1995
            //--------------- RC quality ------------------------
1996
            Dispatcher.Invoke((Action)(() => tbRCQ.Text = data[66].ToString()));
1997
            Dispatcher.Invoke((Action)(() => tbTopRC.Text = data[66].ToString()));
1998
 
2291 - 1999
            if(data[66] > _iThresholdRC)
2000
            {
2001
                _iRCLevelJitter = 0; _bVoiceRCLevelActive = false;
2002
                if (stbRCLevelAnim != null && _bAnimRCLevelActive)
2003
                {
2004
                    Dispatcher.Invoke(() => stbRCLevelAnim.Stop());
2005
                    _bAnimRCLevelActive = false;
2006
                }
2007
            }
2008
            else
2009
            {
2010
                if (_iRCLevelJitter < 20) _iRCLevelJitter++;
2011
                if (_iRCLevelJitter == 20)
2012
                {
2013
                    if (stbRCLevelAnim != null && !_bAnimRCLevelActive)
2014
                    {
2015
                        Dispatcher.Invoke(() => stbRCLevelAnim.Begin());
2016
                        _bAnimRCLevelActive = true;
2017
                    }
2018
                    if (_bVoiceRCLevelPlay && !_bVoiceRCLevelActive)
2019
                    {
2405 - 2020
                        _bVoiceRCLevelActive = true;
2398 - 2021
                        ThreadPool.QueueUserWorkItem(new WaitCallback(_mediaPlayer), "Voice\\MagneticField.mp3");
2022
                        //Thread th = new Thread(() => _mediaPlayer("Voice\\RCLevel.mp3"));
2023
                        //th.Start();
2291 - 2024
                    }
2025
                        _iRCLevelJitter++;
2026
                }
2027
            }
2028
 
2405 - 2029
            //Waypoint max range (by license)
2030
            if(dWPMaxRange != (double)data[70])
2031
            {
2032
                dWPMaxRange = (double)data[70];
2033
                if (home != null && checkBoxShowWPMaxRange.IsChecked == true)
2034
                {
2035
                    if (cWPBound != null && cWPBound.Tag != null)
2036
                        MainMap.Markers.Remove(cWPBound.Tag as GMapMarker);
2037
 
2038
                    createCircle(home.Position, dWPMaxRange);
2408 - 2039
                    Dispatcher.Invoke(() =>
2040
                    {
2041
                        if (comboBoxWPMaxRangeColor.SelectionBoxItem != null)
2042
                        {
2043
                            string s = comboBoxWPMaxRangeColor.SelectionBoxItem.ToString();
2044
                            cWPBound.setColor(s);
2045
                        }
2046
                    });
2405 - 2047
                }
2048
                Dispatcher.Invoke((Action)(() => tbWPMaxRange.Text = data[70].ToString() + " m"));
2049
            }
2399 - 2050
            //Target hold time
2051
            Dispatcher.Invoke((Action)(() => lblWPHoldTime.Content = data[73].ToString()+ " s"));
2401 - 2052
            Dispatcher.Invoke((Action)(() => tbWPStatusHoldTime.Text = data[73].ToString()+ " s"));
2399 - 2053
 
2287 - 2054
            //--------------- NC Error ------------------------
2055
            Dispatcher.Invoke((Action)(() => tbNCErr.Text = data[69].ToString()));  //NC Errornumber
2056
            if (data[69] > 0)
2057
                _readNCError();
2058
            if (data[69] > 0 & data[69] < 44)
2381 - 2059
                ErrorLog(LogMsgType.Error," NC Error [" + data[69].ToString() + "]: ",NC_Error_Link[data[69]], NC_Error[data[69]]);
2060
            //else
2061
            //    if (_bErrorLog) _clearErrorLog("NC Error");
2287 - 2062
 
2298 - 2063
            //-------------FC / NC Status Flags
2064
            Dispatcher.Invoke((Action)(() => FC1_1.Background = ((data[67] & 1) ==1) ? new SolidColorBrush(Colors.LightSeaGreen) : new SolidColorBrush(Colors.Transparent)));// FC_STATUS_MOTOR_RUN                             0x01
2065
            Dispatcher.Invoke((Action)(() => FC1_2.Background = ((data[67] & 2) ==2) ? new SolidColorBrush(Colors.LightSeaGreen) : new SolidColorBrush(Colors.Transparent)));// FC_STATUS_FLY                                   0x02
2066
            Dispatcher.Invoke((Action)(() => FC1_3.Background = ((data[67] & 4) ==4) ? new SolidColorBrush(Colors.LightSeaGreen) : new SolidColorBrush(Colors.Transparent)));// FC_STATUS_CALIBRATE                             0x04
2067
            Dispatcher.Invoke((Action)(() => FC1_4.Background = ((data[67] & 8) ==8) ? new SolidColorBrush(Colors.LightSeaGreen) : new SolidColorBrush(Colors.Transparent)));// FC_STATUS_START                                 0x08
2068
            Dispatcher.Invoke((Action)(() => FC1_5.Background = ((data[67] & 16) ==16) ? new SolidColorBrush(Colors.LightCoral) : new SolidColorBrush(Colors.Transparent)));// FC_STATUS_EMERGENCY_LANDING                      0x10
2069
            Dispatcher.Invoke((Action)(() => FC1_6.Background = ((data[67] & 32) ==32) ? new SolidColorBrush(Colors.LightCoral) : new SolidColorBrush(Colors.Transparent)));// FC_STATUS_LOWBAT                         0x20
2070
 
2071
            Dispatcher.Invoke((Action)(() => FC2_1.Background = ((data[74] & 1) ==1) ? new SolidColorBrush(Colors.LightSeaGreen) : new SolidColorBrush(Colors.Transparent)));// FC_STATUS2_CAREFREE                             0x01
2072
            Dispatcher.Invoke((Action)(() => FC2_2.Background = ((data[74] & 2) ==2) ? new SolidColorBrush(Colors.LightSeaGreen) : new SolidColorBrush(Colors.Transparent)));// FC_STATUS2_ALTITUDE_CONTROL                     0x02
2073
            Dispatcher.Invoke((Action)(() => FC2_3.Background = ((data[74] & 4) ==4) ? new SolidColorBrush(Colors.LightCoral) : new SolidColorBrush(Colors.Transparent)));// FC_STATUS2_RC_FAILSAVE_ACTIVE                      0x04
2074
            Dispatcher.Invoke((Action)(() => FC2_4.Background = ((data[74] & 8) ==8) ? new SolidColorBrush(Colors.LightSeaGreen) : new SolidColorBrush(Colors.Transparent)));// FC_STATUS2_OUT1_ACTIVE                          0x08
2075
            Dispatcher.Invoke((Action)(() => FC2_5.Background = ((data[74] & 16) ==16) ? new SolidColorBrush(Colors.LightSeaGreen) : new SolidColorBrush(Colors.Transparent)));// FC_STATUS2_OUT2_ACTIVE                        0x10
2076
            Dispatcher.Invoke((Action)(() => FC2_6.Background = ((data[74] & 32) ==32) ? new SolidColorBrush(Colors.LightSeaGreen) : new SolidColorBrush(Colors.Transparent)));// FC_STATUS2_WAIT_FOR_TAKEOFF                   0x20   // Motor Running, but still on the ground
2077
            Dispatcher.Invoke((Action)(() => FC2_7.Background = ((data[74] & 64) ==64) ? new SolidColorBrush(Colors.LightSeaGreen) : new SolidColorBrush(Colors.Transparent)));// FC_STATUS2_AUTO_STARTING                              0x40
2078
            Dispatcher.Invoke((Action)(() => FC2_8.Background = ((data[74] & 128) ==128) ? new SolidColorBrush(Colors.LightSeaGreen) : new SolidColorBrush(Colors.Transparent)));// FC_STATUS2_AUTO_LANDING                             0x80
2079
 
2080
            Dispatcher.Invoke((Action)(() => NC1_2.Background = ((data[68] & 2) == 2) ? new SolidColorBrush(Colors.LightSeaGreen) : new SolidColorBrush(Colors.Transparent)));// NC_FLAG_PH                                     0x02
2081
            Dispatcher.Invoke((Action)(() => NC1_3.Background = ((data[68] & 4) == 4) ? new SolidColorBrush(Colors.LightSeaGreen) : new SolidColorBrush(Colors.Transparent)));// NC_FLAG_CH                                     0x04
2082
            Dispatcher.Invoke((Action)(() => NC1_4.Background = ((data[68] & 8) == 8) ? new SolidColorBrush(Colors.LightCoral) : new SolidColorBrush(Colors.Transparent)));// NC_FLAG_RANGE_LIMIT                               0x08
2083
            Dispatcher.Invoke((Action)(() => NC1_5.Background = ((data[68] & 16) == 16) ? new SolidColorBrush(Colors.LightCoral) : new SolidColorBrush(Colors.Transparent)));// NC_FLAG_NOSERIALLINK                            0x10
2084
            Dispatcher.Invoke((Action)(() => NC1_6.Background = ((data[68] & 32) == 32) ? new SolidColorBrush(Colors.LightSeaGreen) : new SolidColorBrush(Colors.Transparent)));// NC_FLAG_TARGET_REACHED                               0x20
2085
            Dispatcher.Invoke((Action)(() => NC1_7.Background = ((data[68] & 64) == 64) ? new SolidColorBrush(Colors.DodgerBlue) : new SolidColorBrush(Colors.Transparent)));// NC_FLAG_MANUAL_CONTROL                          0x40
2086
            Dispatcher.Invoke((Action)(() => NC1_8.Background = ((data[68] & 128) == 128) ? new SolidColorBrush(Colors.LightSeaGreen) : new SolidColorBrush(Colors.Transparent)));// NC_FLAG_GPS_OK                                     0x80
2299 - 2087
 
2088
            //Sidebar StatusSymbols
2089
            Dispatcher.Invoke((Action)(() => tbSideBarStatusMotors.Background = ((data[67] & 1) ==1) ? new SolidColorBrush(Colors.LightSeaGreen) : new SolidColorBrush(Colors.Transparent)));// FC_STATUS_MOTOR_RUN                             0x01
2090
            Dispatcher.Invoke((Action)(() => tbSideBarStatusMotors.Foreground = ((data[67] & 1) ==1) ? new SolidColorBrush(Colors.White) : new SolidColorBrush(Color.FromArgb(255,211,210,210))));// FC_STATUS_MOTOR_RUN                                0x01
2091
            Dispatcher.Invoke((Action)(() => tbSideBarStatusMotors.BorderBrush = ((data[67] & 1) ==1) ? new SolidColorBrush(Colors.White) : new SolidColorBrush(Color.FromArgb(255, 211, 210, 210))));// FC_STATUS_MOTOR_RUN                            0x01
2092
 
2093
            Dispatcher.Invoke((Action)(() => tbSideBarStatusCF.Background = ((data[74] & 1) == 1) ? new SolidColorBrush(Colors.LightSeaGreen) : new SolidColorBrush(Colors.Transparent)));// FC_STATUS2_CAREFREE                                0x01
2094
            Dispatcher.Invoke((Action)(() => tbSideBarStatusCF.Foreground = ((data[74] & 1) == 1) ? new SolidColorBrush(Colors.White) : new SolidColorBrush(Color.FromArgb(255, 211, 210, 210))));// FC_STATUS2_CAREFREE                                0x01
2095
            Dispatcher.Invoke((Action)(() => tbSideBarStatusCF.BorderBrush = ((data[74] & 1) ==1) ? new SolidColorBrush(Colors.White) : new SolidColorBrush(Color.FromArgb(255, 211, 210, 210))));// FC_STATUS2_CAREFREE                                0x01
2096
 
2097
            Dispatcher.Invoke((Action)(() => tbSideBarStatusEmergencyLanding.Background = ((data[67] & 16) == 16) ? new SolidColorBrush(Colors.LightCoral) : new SolidColorBrush(Colors.Transparent)));// FC_STATUS_EMERGENCY_LANDING                   0x10
2304 - 2098
            Dispatcher.Invoke((Action)(() => tbSideBarStatusEmergencyLanding.Foreground = ((data[67] & 16) == 16) ? new SolidColorBrush(Colors.White) : new SolidColorBrush(Color.FromArgb(255, 211, 210, 210))));// FC_STATUS_EMERGENCY_LANDING                0x10
2099
            Dispatcher.Invoke((Action)(() => tbSideBarStatusEmergencyLanding.BorderBrush = ((data[67] & 16) == 16) ? new SolidColorBrush(Colors.White) : new SolidColorBrush(Color.FromArgb(255, 211, 210, 210))));// FC_STATUS_EMERGENCY_LANDING               0x10
2299 - 2100
 
2101
            Dispatcher.Invoke((Action)(() => tbSideBarStatusAC.Background = ((data[74] & 2) ==2) ? new SolidColorBrush(Colors.LightSeaGreen) : new SolidColorBrush(Colors.Transparent)));// FC_STATUS2_ALTITUDE_CONTROL                         0x02
2102
            Dispatcher.Invoke((Action)(() => tbSideBarStatusAC.Foreground = ((data[74] & 2) ==2) ? new SolidColorBrush(Colors.White) : new SolidColorBrush(Color.FromArgb(255, 211, 210, 210))));// FC_STATUS2_ALTITUDE_CONTROL                         0x02
2103
            Dispatcher.Invoke((Action)(() => tbSideBarStatusAC.BorderBrush = ((data[74] & 2) ==2) ? new SolidColorBrush(Colors.White) : new SolidColorBrush(Color.FromArgb(255, 211, 210, 210))));// FC_STATUS2_ALTITUDE_CONTROL                        0x02
2104
 
2105
            Dispatcher.Invoke((Action)(() => tbSideBarStatusPH.Text = ((data[68] & 4) == 4) ? "CH" : "PH"));// NC_FLAG_PH 0x02 / NC_FLAG_CH 0x04
2304 - 2106
            Dispatcher.Invoke((Action)(() => tbSideBarStatusPH.Background = (((data[68] & 2) == 2)|((data[68] & 4) == 4)) ? new SolidColorBrush(Colors.LightSeaGreen) : new SolidColorBrush(Colors.Transparent)));// NC_FLAG_PH 0x02 / NC_FLAG_CH 0x04
2107
            Dispatcher.Invoke((Action)(() => tbSideBarStatusPH.Foreground = (((data[68] & 2) == 2)|((data[68] & 4) == 4)) ? new SolidColorBrush(Colors.White) : new SolidColorBrush(Color.FromArgb(255, 211, 210, 210))));// NC_FLAG_PH 0x02 / NC_FLAG_CH 0x04
2108
            Dispatcher.Invoke((Action)(() => tbSideBarStatusPH.BorderBrush = (((data[68] & 2) == 2)|((data[68] & 4) == 4)) ? new SolidColorBrush(Colors.White) : new SolidColorBrush(Color.FromArgb(255, 211, 210, 210))));// NC_FLAG_PH 0x02 / NC_FLAG_CH 0x04
2299 - 2109
 
2324 - 2110
            _bAirborne = (data[67] & 2) == 2 ? true : false;
2287 - 2111
        }
2112
        /// <summary>
2113
        /// Navi-Ctrl WP data struct 'X'
2114
        /// called by index
2115
        /// </summary>
2116
        /// <param name="data">the received byte array to process</param>
2117
        void _processWPData(byte[] data)
2118
        {
2313 - 2119
            _iWPCount = data[0];
2287 - 2120
            _bGetWPCount = false;
2121
            if (data.Length >= 28)
2122
            {
2123
                Dispatcher.Invoke(() => lblWPIndex.Content = data[1].ToString());
2124
                Dispatcher.Invoke(() => lblWPCount.Content = data[0].ToString());
2125
                if (_bGetWP)
2126
                {
2127
                    if (data[1] == 1)
2315 - 2128
                    {
2333 - 2129
                        Dispatcher.Invoke(() =>
2130
                        {
2356 - 2131
                            wpList.Clear();
2132
                            _clearMapMarkers(typeof(CustomMarkerWP));
2133
                            if (mRouteWP != null)
2134
                                MainMap.Markers.Remove(mRouteWP);
2135
                            if (wpActiveMarker != null)
2136
                                MainMap.Markers.Remove(wpActiveMarker);
2137
                            lblWPRouteDistance.Content = "0 m";
2138
                            dtWaypoints.Rows.Clear();
2368 - 2139
                            _wpEdit = -1;_wpIndex = -1;
2318 - 2140
                        });
2315 - 2141
                    }
2287 - 2142
                    DataRow dr = dtWaypoints.NewRow();
2143
                    dr = Waypoints.toDataRow(data, dr);
2313 - 2144
                    dtWaypoints.Rows.Add(dr);
2363 - 2145
                    _createWP(new PointLatLng((double)dr[3], (double)dr[4]), (string)dr[2], (int)dr[1]);
2313 - 2146
                    Dispatcher.Invoke(() => dgvWP.Items.Refresh());
2147
                    Dispatcher.Invoke(() => _iWPIndex = data[1]);
2287 - 2148
                    if (data[1] == data[0])
2149
                    {
2150
                        _bGetWP = false;
2368 - 2151
                        _routeUpdate();
2287 - 2152
                    }
2153
 
2154
                }
2155
            }
2156
            else
2157
            {
2158
                Dispatcher.Invoke(() => lblWPIndex.Content = 0);
2159
                Dispatcher.Invoke(() => lblWPCount.Content = 0);
2160
            }
2161
        }
2162
        /// <summary>
2163
        /// OSD Menue 'L'
2164
        /// single page called by pagenumber
2165
        /// no autoupdate
2166
        /// </summary>
2167
        /// <param name="data">the received byte array to process</param>
2168
        void _processOSDSingle(byte[] data)
2169
        {
2170
            if (data.Length == 84)
2171
            {
2172
                string sMessage = "";
2173
                iOSDPage = data[0];
2174
                iOSDMax = data[1];
2175
                if (cbOSD.Items.Count != iOSDMax) _initOSDCB();
2176
                sMessage = new string(ASCIIEncoding.ASCII.GetChars(data, 2, data.Length - 4));
2177
                OSD(LogMsgType.Incoming, sMessage.Substring(0, 20)+ "\r", true);
2178
                OSD(LogMsgType.Incoming, sMessage.Substring(20, 20)+ "\r", false);
2179
                OSD(LogMsgType.Incoming, sMessage.Substring(40, 20)+ "\r", false);
2180
                OSD(LogMsgType.Incoming, sMessage.Substring(60, 20), false);
2181
                Dispatcher.Invoke(() => { cbOSD.SelectedValue = iOSDPage; });
2182
              //  lblOSDPageNr.Invoke((Action)(() => lblOSDPageNr.Text = iOSDPage.ToString("[0]")));
2183
 
2184
            }
2185
            //else
2186
            //    OSD(LogMsgType.Incoming, "Wrong length: " + data.Length + " (should be 84)");
2187
 
2188
        }
2189
        /// <summary>
2190
        /// OSD Menue 'H'
2191
        /// called by keys (0x01,0x02,0x03,0x04)
2192
        /// autoupdate
2193
        /// </summary>
2194
        /// <param name="data">the received byte array to process</param>
2195
        void _processOSDAuto(byte[] data)
2196
        {
2197
            if (data.Length == 81)
2198
            {
2199
                string sMessage = "";
2200
                sMessage = new string(ASCIIEncoding.ASCII.GetChars(data, 0, data.Length - 1));
2201
                OSD(LogMsgType.Incoming, sMessage.Substring(0, 20)+ "\r", true);
2202
                OSD(LogMsgType.Incoming, sMessage.Substring(20, 20)+ "\r", false);
2203
                OSD(LogMsgType.Incoming, sMessage.Substring(40, 20)+ "\r", false);
2204
                OSD(LogMsgType.Incoming, sMessage.Substring(60, 20), false);
2205
 
2206
            }
2207
            //else
2208
            //    OSD(LogMsgType.Incoming, "Wrong length: " + data.Length + " (should be 81)");
2209
        }
2210
 
2211
        #endregion processing received data
2212
 
2213
        #region controller messages
2214
        /// <summary> send message to controller to request data
2215
        /// for detailed info see http://wiki.mikrokopter.de/en/SerialProtocol/
2216
        /// </summary>
2217
        /// <param name="CMDID"> the command ID </param>
2218
        /// <param name="address"> the address of the controller: 0-any, 1-FC, 2-NC </param>
2219
        private void _sendControllerMessage(char CMDID, byte address)
2220
        {
2221
            if (serialPortCtrl.Port.IsOpen)
2222
            {
2223
                Stream serialStream = serialPortCtrl.Port.BaseStream;
2224
                byte[] bytes = FlightControllerMessage.CreateMessage(CMDID, address);
2225
                serialStream.Write(bytes, 0, bytes.Length);
2226
 
2227
            }
2228
            else
2229
                Log(LogMsgType.Error, "NOT CONNECTED!");
2230
        }
2231
        /// <summary> send message to controller to request data
2232
        /// for detailed info see http://wiki.mikrokopter.de/en/SerialProtocol/
2233
        /// </summary>
2234
        /// <param name="CMDID"> the command ID </param>
2235
        /// <param name="address"> the address of the controller: 0-any, 1-FC, 2-NC </param>
2236
        /// <param name="data"> additional data for the request</param>
2237
        private void _sendControllerMessage(char CMDID, byte address, byte[] data)
2238
        {
2239
            if (serialPortCtrl.Port.IsOpen)
2240
            {
2241
                Stream serialStream = serialPortCtrl.Port.BaseStream;
2242
                byte[] bytes = FlightControllerMessage.CreateMessage(CMDID, address, data);
2243
                serialStream.Write(bytes, 0, bytes.Length);
2244
 
2245
            }
2246
            else
2247
                Log(LogMsgType.Error, "NOT CONNECTED!");
2248
        }
2249
 
2250
        /// <summary>
2251
        /// start/stop continous polling of controller values
2252
        /// </summary>
2253
        /// <param name="b">start/stop switch</param>
2254
        void _readCont(bool b)
2255
        {
2256
            bReadContinously = b;
2257
            if (bReadContinously)
2258
            {
2259
                if (_debugDataAutorefresh) { _readDebugData(true); Thread.Sleep(10); }
2260
                if (_blctrlDataAutorefresh) { _readBLCtrl(true); Thread.Sleep(10); }
2261
                if (_navCtrlDataAutorefresh && _iCtrlAct == 2) { _readNavData(true); Thread.Sleep(10); }
2262
                if (_OSDAutorefresh) { _OSDMenueAutoRefresh(); Thread.Sleep(10); }
2263
                // Dispatcher.Invoke((Action)(() => rctConnection.Fill = Brushes.LightGreen));
2264
                Dispatcher.Invoke(() => imageConn.Source = new BitmapImage(new Uri("Images/Data_G.png", UriKind.Relative)));
2265
            }
2266
            else
2267
            {
2268
                // Dispatcher.Invoke((Action)(() => rctConnection.Fill = Brushes.LightGray));
2269
                Dispatcher.Invoke(() => imageConn.Source = new BitmapImage(new Uri("Images/Data_W.png", UriKind.Relative)));
2270
                _bConnErr = false;
2271
            }
2272
            _iLifeCounter = 0;
2273
        }
2274
 
2275
        private void _getVersion()
2276
        {
2277
            _sendControllerMessage('v', 0);
2278
        }
2279
        /// <summary>
2280
        /// get FC version struct via NC
2281
        /// by sending '1' as data (not documented in wiki...)
2282
        /// returns HW error 255 (comment in uart1.c : tells the KopterTool that it is the FC-version)
2283
        /// </summary>
2284
        /// <param name="ctrl">controller number 1=FC</param> 
2285
        private void _getVersion(byte ctrl)
2286
        {
2287
            _sendControllerMessage('v', 0, new byte[1] { ctrl });
2288
        }
2289
        /// <summary>
2290
        /// Switch back to NC by sending the 'Magic Packet' 0x1B,0x1B,0x55,0xAA,0x00
2291
        /// </summary>
2292
        private void _switchToNC()
2293
        {
2294
            if (serialPortCtrl.Port.IsOpen)
2295
            {
2296
                Stream serialStream = serialPortCtrl.Port.BaseStream;
2297
                byte[] bytes = new byte[5] { 0x1B, 0x1B, 0x55, 0xAA, 0x00 };
2298
                serialStream.Write(bytes, 0, bytes.Length);
2299
 
2300
                Thread.Sleep(100);
2301
                _getVersion();
2302
                Thread.Sleep(100);
2303
               // _OSDMenue(0);
2304
            }
2305
            else
2306
                Log(LogMsgType.Error, "NOT CONNECTED!");
2307
        }
2308
        /// <summary>
2309
        /// switch to FC
2310
        /// </summary>
2311
        private void _switchToFC()
2312
        {
2313
            _sendControllerMessage('u', 2, new byte[1] { (byte)0 });
2314
            Thread.Sleep(100);
2315
            _getVersion();
2316
            Thread.Sleep(100);
2317
          //  _OSDMenue(0);
2318
        }
2319
        /// <summary>
2320
        /// send RESET signal to FC
2321
        /// </summary>
2322
        private void _resetCtrl()
2323
        {
2324
            _sendControllerMessage('R', 1);
2325
        }
2326
        /// <summary>
2327
        /// poll the debug data (4sec subscription)
2328
        /// </summary>
2329
        /// <param name="auto"> onetimequery(false) or autoupdate(true) with set timing interval </param>
2330
        private void _readDebugData(bool auto)
2331
        {
2332
            byte interval = auto ? debugInterval : (byte)0;
2333
            _sendControllerMessage('d', 0, new byte[1] { debugInterval });
2334
        }
2335
        /// <summary>
2336
        /// poll the BL-CTRL status via NC (4sec subscription)
2337
        /// </summary>
2338
        /// <param name="auto"> onetimequery(false) or autoupdate(true) with set timing interval </param>
2339
        private void _readBLCtrl(bool auto)
2340
        {
2341
            byte interval = auto ? blctrlInterval : (byte)0;
2342
            _sendControllerMessage('k', 0, new byte[1] { interval });
2343
        }
2344
        /// <summary>
2345
        /// poll the NC data struct (4sec subscription)
2346
        /// </summary>
2347
        /// <param name="auto"> onetimequery(false) or autoupdate(true) with set timing interval </param>
2348
        private void _readNavData(bool auto)
2349
        {
2350
            byte interval = auto ? navctrlInterval : (byte)0;
2351
            _sendControllerMessage('o', 2, new byte[1] { interval });
2352
        }
2353
        /// <summary>
2354
        /// get the errortext for pending NC error
2355
        /// </summary>
2356
        private void _readNCError()
2357
        {
2358
            _sendControllerMessage('e', 2);
2359
        }
2360
        /// <summary>
2361
        /// request the Waypoint at index
2362
        /// </summary>
2363
        /// <param name="index"></param>
2364
        void _getpWP(int index)
2365
        {
2366
            if (serialPortCtrl.Port.IsOpen)
2367
            {
2368
                Stream serialStream = serialPortCtrl.Port.BaseStream;
2369
                byte[] bytes = FlightControllerMessage.CreateMessage('x', 2, new byte[1] { (byte)index });
2370
                serialStream.Write(bytes, 0, bytes.Length);
2371
            }
2372
            else
2373
                Log(LogMsgType.Error, "NOT CONNECTED!");
2374
 
2375
        }
2376
        void _getWP()
2377
        {
2335 - 2378
            int iTimeout = 0;
2287 - 2379
            _bGetWPCount = true;
2315 - 2380
            _getpWP(1); //get the itemscount of wp
2335 - 2381
            while (_bGetWPCount & iTimeout < _iWPTimeout * 5)
2382
            {
2383
                Thread.Sleep(10);
2384
                iTimeout++;
2385
            }
2386
            if (_iWPCount > 0 & !_bGetWPCount)
2287 - 2387
                _getWPList();
2388
        }
2389
        void _getWPList()
2390
        {
2391
            _bGetWP = true;
2313 - 2392
            int iTimeout=0;
2393
            for (int j = 0; j < _iWPCount; j++)
2287 - 2394
            {
2395
                _getpWP(j + 1);
2313 - 2396
                iTimeout = 0;
2397
                while (_iWPIndex != j + 1 & iTimeout < _iWPTimeout * 5)
2398
                {
2399
                    Thread.Sleep(1);
2400
                    iTimeout++;
2401
                }
2287 - 2402
            }
2403
        }
2363 - 2404
        /// <summary>
2405
        /// Wrapper for _clearCopterWPList()
2406
        /// necessary, cause it is called by threadnew which does not like return values...
2407
        /// </summary>
2340 - 2408
        void clearCopterWPList()
2313 - 2409
        {
2340 - 2410
            _clearCopterWPList();
2411
        }
2363 - 2412
        /// <summary>
2413
        /// clear the WP list of the copter
2414
        /// by sending 'invalid' and index '0'
2415
        /// </summary>
2416
        /// <returns></returns>
2340 - 2417
        bool _clearCopterWPList()
2418
        {
2335 - 2419
            int iTimeout = 0;
2313 - 2420
            if (serialPortCtrl.Port.IsOpen)
2421
            {
2422
                byte[] bData = new byte[30];
2423
                for (int i = 0; i < 30; i++)
2424
                    bData[i] = 0;
2425
                Stream serialStream = serialPortCtrl.Port.BaseStream;
2426
                byte[] bytes = FlightControllerMessage.CreateMessage('w', 2, bData); //delete all WP on Copter by sending 'invalid'(==0) at index 0
2427
                serialStream.Write(bytes, 0, bytes.Length);
2287 - 2428
 
2313 - 2429
                _iWPCount = -1;
2340 - 2430
                while (_iWPCount == -1 & iTimeout < _iWPTimeout)
2335 - 2431
                {
2313 - 2432
                    Thread.Sleep(10);
2335 - 2433
                    iTimeout++;
2434
                }
2313 - 2435
                Dispatcher.Invoke(() => lblWPCount.Content = _iWPCount.ToString());
2335 - 2436
                if (_iWPCount > -1)
2340 - 2437
                    return true;
2438
                else
2439
                    Log(LogMsgType.Error, "Timeout while sending list!");
2440
            }
2441
            else
2442
                Log(LogMsgType.Error, "NOT CONNECTED!");
2443
 
2444
            return false;
2445
}
2446
        void _sendWPList()
2447
        {
2362 - 2448
            _sendWPList(0);
2449
        }
2450
        void _sendWPList(int iStart)
2451
        {
2340 - 2452
            int iTimeout = 0;
2453
            if (serialPortCtrl.Port.IsOpen)
2454
            {
2455
                if (_clearCopterWPList())
2313 - 2456
                {
2362 - 2457
                    int k = 1;
2458
                    for (int i = iStart; i < dtWaypoints.Rows.Count; i++)
2335 - 2459
                    {
2362 - 2460
                        k = iStart > 0 ? k : -1;
2376 - 2461
                        _sendWayPoint(dtWaypoints.Rows[i], k, 'w',false);
2313 - 2462
 
2335 - 2463
                        _iWPCount = -1;
2464
                        iTimeout = 0;
2465
                        while (_iWPCount == -1 & iTimeout < _iWPTimeout * 5)
2466
                        {
2467
                            Thread.Sleep(10);
2468
                            iTimeout++;
2469
                        }
2470
                        if (_iWPCount == -1)
2471
                        {
2472
                            Log(LogMsgType.Error, "Timeout while sending list!");
2473
                            break;
2474
                        }
2475
                        Dispatcher.Invoke(() => lblWPCount.Content = _iWPCount.ToString());
2362 - 2476
                        k++;
2335 - 2477
                    }
2313 - 2478
                }
2479
            }
2480
            else
2481
                Log(LogMsgType.Error, "NOT CONNECTED!");
2482
 
2483
        }
2376 - 2484
        bool _sendWayPoint(DataRow dr, int index, char command,bool bSim)
2340 - 2485
        {
2313 - 2486
 
2340 - 2487
            if (serialPortCtrl.Port.IsOpen)
2488
            {
2489
                byte[] bData = new byte[30];
2490
                for (int i = 0; i < 30; i++)
2491
                    bData[i] = 0;
2492
                Stream serialStream = serialPortCtrl.Port.BaseStream;
2493
                byte[] bytes;
2494
                int iVal;
2495
                double dVal;
2496
                NumberFormatInfo nfi = new NumberFormatInfo();
2497
                nfi.NumberDecimalSeparator = ",";
2498
 
2499
                //longitude
2500
                dVal = Convert.ToDouble(dr[4], nfi);
2501
                iVal = (int)(dVal * Math.Pow(10, 7));
2502
                bData[0] = (byte)(iVal & 0xff);
2503
                bData[1] = (byte)((iVal >> 8) & 0xff);
2504
                bData[2] = (byte)((iVal >> 16) & 0xff);
2505
                bData[3] = (byte)(iVal >> 24);
2506
                //latitude
2507
                dVal = Convert.ToDouble(dr[3], nfi);
2508
                iVal = (int)(dVal * Math.Pow(10, 7));
2509
                bData[4] = (byte)(iVal & 0xff);
2510
                bData[5] = (byte)((iVal >> 8) & 0xff);
2511
                bData[6] = (byte)((iVal >> 16) & 0xff);
2512
                bData[7] = (byte)(iVal >> 24);
2513
                //altitude
2514
                dVal = Convert.ToDouble(dr[5], nfi);
2515
                iVal = (int)(dVal * 10);
2516
                bData[8] = (byte)(iVal & 0xff);
2517
                bData[9] = (byte)((iVal >> 8) & 0xff);
2518
                bData[10] = (byte)((iVal >> 16) & 0xff);
2519
                bData[11] = (byte)(iVal >> 24);
2376 - 2520
                if(bSim)
2521
                    bData[12] = 3; //Status 'SIMULATE'
2340 - 2522
                //Status 'NEWDATA'
2376 - 2523
                else
2524
                    bData[12] = 1;
2340 - 2525
                //heading
2526
                iVal = Convert.ToInt16(dr[6]);
2527
                bData[13] = (byte)(iVal & 0xff);
2528
                bData[14] = (byte)((iVal >> 8) & 0xff);
2529
                //ToleranceRadius
2530
                bData[15] = Convert.ToByte(dr[9]);
2531
                //HoldTime
2532
                bData[16] = Convert.ToByte(dr[10]);
2533
                //Event_Flag
2534
                bData[17] = Convert.ToByte(dr[13]);
2535
                //Index
2379 - 2536
                bData[18] = index > -1 ? (byte)index : Convert.ToByte((int)dr[0]);
2340 - 2537
                //Type
2538
                bData[19] = Convert.ToByte(dr[1]);
2539
                //WP_EventChannelValue
2540
                bData[20] = Convert.ToByte(dr[14]);
2541
                //AltitudeRate
2542
                bData[21] = Convert.ToByte(dr[8]);
2543
                //Speed
2544
                bData[22] = Convert.ToByte(dr[7]);
2545
                //CamAngle
2546
                bData[23] = (byte)Convert.ToInt16(dr[12]);
2547
                //Name
2362 - 2548
                string s = index > 0 ? ((string)dr[2]).Substring(0, 1) + index.ToString() : (string)dr[2];
2549
                byte[] name = ASCIIEncoding.ASCII.GetBytes(s);
2340 - 2550
                bData[24] = name.Length > 0 ? name[0] : (byte)0;
2551
                bData[25] = name.Length > 1 ? name[1] : (byte)0;
2552
                bData[26] = name.Length > 2 ? name[2] : (byte)0;
2553
                bData[27] = name.Length > 3 ? name[3] : (byte)0;
2554
                //Autotrigger
2555
                bData[28] = Convert.ToByte(dr[11]);
2556
 
2356 - 2557
                bytes = FlightControllerMessage.CreateMessage(command, 2, bData);
2340 - 2558
                serialStream.Write(bytes, 0, bytes.Length);
2559
 
2560
                return true;
2561
            }
2562
 
2563
            return false;
2564
        }
2287 - 2565
        #region OSD-Menue
2566
 
2567
        /// <summary>
2568
        /// one time query of the OSD Menue with pagenumber
2569
        /// </summary>
2570
        /// <param name="iMenue">Menue page</param>
2571
        void _OSDMenue(int iMenue)
2572
        {
2573
            if (serialPortCtrl.Port.IsOpen)
2574
            {
2575
                if (iMenue > iOSDMax)
2576
                    iMenue = 0;
2577
                Stream serialStream = serialPortCtrl.Port.BaseStream;
2578
                byte[] bytes = FlightControllerMessage.CreateMessage('l', 0, new byte[1] { (byte)iMenue });
2579
                serialStream.Write(bytes, 0, bytes.Length);
2580
            }
2581
            else
2582
                Log(LogMsgType.Error, "NOT CONNECTED!");
2583
 
2584
        }
2585
        /// <summary>
2586
        /// call the OSDMenue and start autorefresh
2587
        ///  usually by sending a menuekey
2588
        /// a bit tricky - but by sending inverted value of 32 (32 = 0010 0000) you can start the OSD menue with autoupdate (abo) without switching the page with the keyvalues (0x1, 0x2)
2589
        /// therefore the value has to be negative (inverted) in order to distinguish from old (2 line) menuestyle
2590
        /// and must not have any bits of the menue keys 0x1 0x2 0x4 0x8 (0x10?) --> 0x20 = -33
2591
        /// </summary>
2592
        void _OSDMenueAutoRefresh()
2593
        {
2594
            _sendControllerMessage('h', 0, new byte[2] { unchecked((byte)(-33)), OSDInterval });
2595
        }
2596
        void _OSDMenueAutoRefresh(byte key)
2597
        {
2598
            _sendControllerMessage('h', 0, new byte[2] { unchecked((byte)~key), OSDInterval });
2599
        }
2600
        /// <summary>
2601
        /// initialize the OSD menue combobox
2602
        /// combox is filled by numbers from 0 to max pagenumber
2603
        /// </summary>
2604
        void _initOSDCB()
2605
        {
2606
            _bCBInit = true;
2607
            if (iOSDMax == 0)
2608
            {
2609
                _OSDMenue(0);
2610
                Thread.Sleep(10);
2611
            }
2612
            Dispatcher.Invoke((Action)(() => cbOSD.Items.Clear()));
2613
            for (int i = 0; i <= iOSDMax; i++)
2614
            {
2615
                Dispatcher.Invoke((Action)(() => cbOSD.Items.Add(i)));
2616
            }
2617
            Dispatcher.Invoke((Action)(() => cbOSD.SelectedItem = iOSDPage));
2618
            _bCBInit = false;
2619
        }
2620
        private void btnOSDForward_Click(object sender, RoutedEventArgs e)
2621
        {
2622
            iOSDPage++;
2623
            if (iOSDPage > iOSDMax)
2624
                iOSDPage = 0;
2625
 
2626
            _OSDMenue(iOSDPage);
2627
        }
2628
        private void btnOSDBackward_Click(object sender, RoutedEventArgs e)
2629
        {
2630
            iOSDPage--;
2631
            if (iOSDPage < 0)
2632
                iOSDPage = iOSDMax;
2633
 
2634
            _OSDMenue(iOSDPage);
2635
        }
2636
        private void btnOSDLeave_Click(object sender, RoutedEventArgs e)
2637
        {
2638
            _OSDMenueAutoRefresh(8);
2639
        }
2640
        private void btnOSDEnter_Click(object sender, RoutedEventArgs e)
2641
        {
2642
            _OSDMenueAutoRefresh(4);
2643
        }
2644
        private void cbOSD_DropDownClosing(object sender, EventArgs e)
2645
        {
2646
            if (!_bCBInit && cbOSD.SelectedIndex > -1)
2647
                _OSDMenue(cbOSD.SelectedIndex);
2648
        }
2649
        private void OSD(LogMsgType msgtype, string msg, bool bNew)
2650
        {
2651
            Dispatcher.Invoke(() =>
2652
            {
2653
                TextRange tr;
2654
                if (bNew)
2655
                {
2656
                    rtfOSD.SelectAll();
2657
                    rtfOSD.Selection.Text = string.Empty;
2658
                }
2659
                tr = new TextRange(rtfOSD.Document.ContentEnd, rtfOSD.Document.ContentEnd);
2660
                tr.Text = msg;
2661
                tr.ApplyPropertyValue(TextElement.ForegroundProperty, new SolidColorBrush(LogMsgTypeColor[(int)msgtype]));
2662
                //     rtfOSD.AppendText("\r");
2663
                rtfOSD.ScrollToEnd();
2664
 
2665
            });
2666
        }
2667
 
2668
        #endregion OSD-Menue
2669
 
2670
        #endregion controller messages
2671
 
2398 - 2672
        void _mediaPlayer(object file)
2295 - 2673
        {
2405 - 2674
            Monitor.TryEnter(lockObj);
2675
            try
2295 - 2676
            {
2405 - 2677
                if (File.Exists((string)file))
2678
                {
2679
 
2680
                    mediaPlayer.Open((string)file);
2681
                    mediaPlayer.Play();
2682
                }
2683
 
2295 - 2684
            }
2405 - 2685
            finally
2686
            {
2687
                Monitor.Exit(lockObj);
2688
            }
2295 - 2689
        }
2310 - 2690
 
2362 - 2691
        #region ui
2310 - 2692
        /// <summary>
2693
        /// Switch between fullscreen and normal window mode
2694
        /// save & restore scaling settings
2695
        /// </summary>
2696
        /// <param name="sender"></param>
2697
        /// <param name="e"></param>
2287 - 2698
        private void imageFullscreen_MouseDown(object sender, MouseButtonEventArgs e)
2699
        {
2700
            if (winState.isMaximized)
2701
            {
2702
                winState.Restore(this);
2703
                imageFullscreen.Source = new BitmapImage(new Uri("Images/Fullscreen.png", UriKind.Relative));
2704
                if(_bSaveWinStateFull)
2705
                    _saveScaleSliders(true);
2706
                if(_bSaveWinStateNormal)
2707
                    _setScaleSliders(false);
2708
            }
2709
            else
2710
            {
2711
                winState.Maximize(this);
2712
                imageFullscreen.Source = new BitmapImage(new Uri("Images/RestoreScreen.png", UriKind.Relative));
2713
                if(_bSaveWinStateNormal)
2714
                    _saveScaleSliders(false);
2715
                if(_bSaveWinStateFull)
2716
                    _setScaleSliders(true);
2717
            }
2718
        }
2719
 
2720
        /// <summary>
2721
        /// reset the scaling of all UI elements to default
2722
        /// </summary>
2723
        /// <param name="sender"></param>
2724
        /// <param name="e"></param>
2725
        private void buttonUIScaleReset_Click(object sender, RoutedEventArgs e)
2726
        {
2727
            UIScaleHorizonSlider.Value =
2728
                UIScaleLOGSlider.Value =
2729
                UIScaleMotorsSlider.Value =
2730
                UIScaleOSDSlider.Value =
2731
                UIScaleSlider.Value =
2732
                UIScaleTopSlider.Value = 1;
2733
        }
2734
        /// <summary>
2735
        /// adjust the top postion of UI elements below the top bar to fit the bottom position of the bar when scaling the top bar
2736
        /// </summary>
2737
        /// <param name="sender"></param>
2738
        /// <param name="e"></param>
2739
        private void UIScaleTopSlider_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
2740
        {
2741
            GridSettings.Margin = new Thickness(GridSettings.Margin.Left, 36 * UIScaleTopSlider.Value, GridSettings.Margin.Right, GridSettings.Margin.Bottom);
2742
            if (GridMotors != null)
2743
                GridMotors.Margin = new Thickness(GridMotors.Margin.Left, 36 * UIScaleTopSlider.Value, GridMotors.Margin.Right, GridMotors.Margin.Bottom);
2744
            if (GridSideBar != null)
2745
                GridSideBar.Margin = new Thickness(GridSideBar.Margin.Left, 36 * UIScaleTopSlider.Value, GridSideBar.Margin.Right, GridSideBar.Margin.Bottom);
2401 - 2746
            if (WPStatus != null)
2747
                WPStatus.Margin = new Thickness(WPStatus.Margin.Left, 36 * UIScaleTopSlider.Value, WPStatus.Margin.Right, WPStatus.Margin.Bottom);
2287 - 2748
            if (GridOSD != null)
2401 - 2749
            {
2750
                if(WPStatus.Visibility == Visibility.Visible)
2751
                    GridOSD.Margin = new Thickness(GridOSD.Margin.Left, 36 * UIScaleTopSlider.Value + WPStatus.Margin.Bottom, GridOSD.Margin.Right, GridOSD.Margin.Bottom);
2752
                else
2753
                    GridOSD.Margin = new Thickness(GridOSD.Margin.Left, 36 * UIScaleTopSlider.Value, GridOSD.Margin.Right, GridOSD.Margin.Bottom);
2754
            }
2287 - 2755
            if (GridData != null)
2756
                GridData.Margin = new Thickness(GridData.Margin.Left, 36 * UIScaleTopSlider.Value, GridData.Margin.Right, GridData.Margin.Bottom);
2757
            if (GridWP != null)
2758
                GridWP.Margin = new Thickness(GridWP.Margin.Left, 36 * UIScaleTopSlider.Value, GridWP.Margin.Right, GridWP.Margin.Bottom);
2759
        }
2310 - 2760
        /// <summary>
2761
        /// restore the saved scalings for the fullscreen/normal window mode
2762
        /// </summary>
2763
        /// <param name="bFull">the mode the window is set to</param>
2287 - 2764
        void _setScaleSliders(bool bFull)
2765
        {
2766
            if(bFull)
2767
            {
2768
                UIScaleSlider.Value = scaleFullAll;
2769
                UIScaleTopSlider.Value = scaleFullTopBar;
2770
                UIScaleMotorsSlider.Value = scaleFullMotors;
2771
                UIScaleOSDSlider.Value = scaleFullOSD;
2772
                UIScaleLOGSlider.Value = scaleFullLOG;
2773
                UIScaleHorizonSlider.Value = scaleFullHorizon;
2774
            }
2775
            else
2776
            {
2777
                UIScaleSlider.Value = scaleNormalAll;
2778
                UIScaleTopSlider.Value = scaleNormalTopBar;
2779
                UIScaleMotorsSlider.Value = scaleNormalMotors;
2780
                UIScaleOSDSlider.Value = scaleNormalOSD;
2781
                UIScaleLOGSlider.Value = scaleNormalLOG;
2782
                UIScaleHorizonSlider.Value = scaleNormalHorizon;
2783
            }
2784
        }
2785
 
2310 - 2786
        /// <summary>
2787
        /// save the scalings for the actual window mode
2788
        /// </summary>
2789
        /// <param name="bFull">the actual window mode</param>
2287 - 2790
        void _saveScaleSliders(bool bFull)
2791
        {
2792
 
2793
            if (bFull)
2794
            {
2795
                scaleFullAll = UIScaleSlider.Value;
2796
                scaleFullTopBar = UIScaleTopSlider.Value;
2797
                scaleFullMotors = UIScaleMotorsSlider.Value;
2798
                scaleFullOSD = UIScaleOSDSlider.Value;
2799
                scaleFullLOG = UIScaleLOGSlider.Value;
2800
                scaleFullHorizon = UIScaleHorizonSlider.Value;
2801
            }
2802
            else
2803
            {
2804
                scaleNormalAll = UIScaleSlider.Value;
2805
                scaleNormalTopBar = UIScaleTopSlider.Value;
2806
                scaleNormalMotors = UIScaleMotorsSlider.Value;
2807
                scaleNormalOSD = UIScaleOSDSlider.Value;
2808
                scaleNormalLOG = UIScaleLOGSlider.Value;
2809
                scaleNormalHorizon = UIScaleHorizonSlider.Value;
2810
            }
2811
        }
2362 - 2812
        #endregion ui
2287 - 2813
 
2814
        /// <summary>
2815
        /// read settings from ini-file
2816
        /// </summary>
2817
        void _readIni()
2818
        {
2819
            if (!File.Exists(filePath + "\\MKLiveViewSettings.ini"))
2820
                _writeIni();
2821
            IniFile ini = new IniFile("MKLiveViewSettings.ini");
2822
            ini.path = filePath + "\\MKLiveViewSettings.ini";
2312 - 2823
            try
2824
            {
2287 - 2825
 
2312 - 2826
                string sVal = ini.IniReadValue("timings", "AutorefreshDebugData");
2827
                if (sVal != "") _debugDataAutorefresh = Convert.ToBoolean(sVal);
2828
                sVal = ini.IniReadValue("timings", "AutorefreshNavCtrlData");
2829
                if (sVal != "") _navCtrlDataAutorefresh = Convert.ToBoolean(sVal);
2830
                sVal = ini.IniReadValue("timings", "AutorefreshBLCtrlData");
2831
                if (sVal != "") _blctrlDataAutorefresh = Convert.ToBoolean(sVal);
2832
                sVal = ini.IniReadValue("timings", "AutorefreshOSDData");
2833
                if (sVal != "") _OSDAutorefresh = Convert.ToBoolean(sVal);
2287 - 2834
 
2312 - 2835
                sVal = ini.IniReadValue("timings", "IntervalDebugData");
2836
                if (sVal != "") debugInterval = (byte)Convert.ToInt16(sVal);
2837
                sVal = ini.IniReadValue("timings", "IntervalNavCtrlData");
2838
                if (sVal != "") navctrlInterval = (byte)Convert.ToInt16(sVal);
2839
                sVal = ini.IniReadValue("timings", "IntervalBLCtrlData");
2840
                if (sVal != "") blctrlInterval = (byte)Convert.ToInt16(sVal);
2841
                sVal = ini.IniReadValue("timings", "IntervalOSDData");
2842
                if (sVal != "") OSDInterval = (byte)Convert.ToInt16(sVal);
2287 - 2843
 
2312 - 2844
                sVal = ini.IniReadValue("topBar", "voltage");
2845
                if (sVal != "") chkBoxTopBarShowVoltage.IsChecked = Convert.ToBoolean(sVal);
2846
                sVal = ini.IniReadValue("topBar", "capacity");
2847
                if (sVal != "") chkBoxTopBarShowCapacity.IsChecked = Convert.ToBoolean(sVal);
2848
                sVal = ini.IniReadValue("topBar", "current");
2849
                if (sVal != "") chkBoxTopBarShowCurrent.IsChecked = Convert.ToBoolean(sVal);
2850
                sVal = ini.IniReadValue("topBar", "flightTime");
2851
                if (sVal != "") chkBoxTopBarShowFlightTime.IsChecked = Convert.ToBoolean(sVal);
2852
                sVal = ini.IniReadValue("topBar", "distanceHP");
2853
                if (sVal != "") chkBoxTopBarShowDistanceHP.IsChecked = Convert.ToBoolean(sVal);
2854
                sVal = ini.IniReadValue("topBar", "height");
2855
                if (sVal != "") chkBoxTopBarShowHeight.IsChecked = Convert.ToBoolean(sVal);
2856
                sVal = ini.IniReadValue("topBar", "speed");
2857
                if (sVal != "") chkBoxTopBarShowSpeed.IsChecked = Convert.ToBoolean(sVal);
2858
                sVal = ini.IniReadValue("topBar", "magneticField");
2859
                if (sVal != "") chkBoxTopBarShowMF.IsChecked = Convert.ToBoolean(sVal);
2860
                sVal = ini.IniReadValue("topBar", "satellites");
2861
                if (sVal != "") chkBoxTopBarShowSatellites.IsChecked = Convert.ToBoolean(sVal);
2862
                sVal = ini.IniReadValue("topBar", "rc");
2863
                if (sVal != "") chkBoxTopBarShowRC.IsChecked = Convert.ToBoolean(sVal);
2287 - 2864
 
2312 - 2865
                sVal = ini.IniReadValue("style", "saveFullScreen");
2866
                if (sVal != "") chkBoxSaveFullScreenState.IsChecked = Convert.ToBoolean(sVal);
2867
                sVal = ini.IniReadValue("style", "saveNormalState");
2868
                if (sVal != "") chkBoxSaveNormalState.IsChecked = Convert.ToBoolean(sVal);
2287 - 2869
 
2312 - 2870
                sVal = ini.IniReadValue("style", "scaleNormalAll");
2871
                if (sVal != "") scaleNormalAll = Convert.ToDouble(sVal);
2872
                sVal = ini.IniReadValue("style", "scaleNormalTopBar");
2873
                if (sVal != "") scaleNormalTopBar = Convert.ToDouble(sVal);
2874
                sVal = ini.IniReadValue("style", "scaleNormalMotors");
2875
                if (sVal != "") scaleNormalMotors = Convert.ToDouble(sVal);
2876
                sVal = ini.IniReadValue("style", "scaleNormalOSD");
2877
                if (sVal != "") scaleNormalOSD = Convert.ToDouble(sVal);
2878
                sVal = ini.IniReadValue("style", "scaleNormalLOG");
2879
                if (sVal != "") scaleNormalLOG = Convert.ToDouble(sVal);
2880
                sVal = ini.IniReadValue("style", "scaleNormalHorizon");
2881
                if (sVal != "") scaleNormalHorizon = Convert.ToDouble(sVal);
2287 - 2882
 
2312 - 2883
                sVal = ini.IniReadValue("style", "scaleFullAll");
2884
                if (sVal != "") scaleFullAll = Convert.ToDouble(sVal);
2885
                sVal = ini.IniReadValue("style", "scaleFullTopBar");
2886
                if (sVal != "") scaleFullTopBar = Convert.ToDouble(sVal);
2887
                sVal = ini.IniReadValue("style", "scaleFullMotors");
2888
                if (sVal != "") scaleFullMotors = Convert.ToDouble(sVal);
2889
                sVal = ini.IniReadValue("style", "scaleFullOSD");
2890
                if (sVal != "") scaleFullOSD = Convert.ToDouble(sVal);
2891
                sVal = ini.IniReadValue("style", "scaleFullLOG");
2892
                if (sVal != "") scaleFullLOG = Convert.ToDouble(sVal);
2893
                sVal = ini.IniReadValue("style", "scaleFullHorizon");
2894
                if (sVal != "") scaleFullHorizon = Convert.ToDouble(sVal);
2287 - 2895
 
2312 - 2896
                sVal = ini.IniReadValue("general", "LiPoCells");
2897
                _LipoCells = Convert.ToInt16(sVal);
2898
                sVal = ini.IniReadValue("general", "Motors");
2899
                if (sVal != "") _iMotors = Convert.ToInt16(sVal);
2287 - 2900
 
2312 - 2901
                sVal = ini.IniReadValue("map", "followMe");
2902
                if (sVal != "") _bFollowCopter = Convert.ToBoolean(sVal);
2903
                sVal = ini.IniReadValue("map", "AutoSetHome");
2904
                if (sVal != "") _bAutoHome = Convert.ToBoolean(sVal);
2324 - 2905
                sVal = ini.IniReadValue("map", "GPXLog");
2906
                if (sVal != "") _bGPXLog = Convert.ToBoolean(sVal);
2287 - 2907
 
2312 - 2908
                sVal = ini.IniReadValue("threshold", "VoltageWarning");
2909
                if(sVal != "") _dThresholdVoltageWarn = Convert.ToDouble(sVal);
2910
                sVal = ini.IniReadValue("threshold", "VoltageCritical");
2911
                if(sVal != "") _dThresholdVoltageCrit = Convert.ToDouble(sVal);
2912
                sVal = ini.IniReadValue("threshold", "VoiceVoltageEnable");
2913
                if(sVal != "") _bVoiceVoltPlay = Convert.ToBoolean(sVal);
2914
                sVal = ini.IniReadValue("threshold", "VoiceSatFixEnable");
2915
                if(sVal != "") _bVoiceSatFixPlay = Convert.ToBoolean(sVal);
2916
                sVal = ini.IniReadValue("threshold", "VoiceMagFieldEnable");
2917
                if(sVal != "") _bVoiceMagneticFieldPlay = Convert.ToBoolean(sVal);
2918
                sVal = ini.IniReadValue("threshold", "DistanceWarning");
2919
                if(sVal != "") _dThresholdDistanceWarn = Convert.ToDouble(sVal);
2920
                sVal = ini.IniReadValue("threshold", "VoiceDistanceWarnEnable");
2921
                if(sVal != "") _bVoiceDistancePlay = Convert.ToBoolean(sVal);
2922
                sVal = ini.IniReadValue("threshold", "VoiceRCLevelWarnEnable");
2923
                if(sVal != "") _bVoiceRCLevelPlay = Convert.ToBoolean(sVal);
2924
                sVal = ini.IniReadValue("threshold", "MaxDistance");
2925
                if(sVal != "") _dThresholdDistanceMax = Convert.ToDouble(sVal);
2926
                sVal = ini.IniReadValue("threshold", "RCThreshold");
2927
                if(sVal != "") _iThresholdRC = Convert.ToInt32(sVal);
2928
                sVal = ini.IniReadValue("threshold", "MagFieldThreshold");
2929
                if(sVal != "") _iThresholdMagField = Convert.ToInt32(sVal);
2321 - 2930
 
2931
                sVal = ini.IniReadValue("waypoints", "wpcolor");
2932
                if(sVal != "") comboBoxWPColor.SelectedIndex = Convert.ToInt32(sVal);
2933
                sVal = ini.IniReadValue("waypoints", "poicolor");
2934
                if(sVal != "") comboBoxPOIColor.SelectedIndex = Convert.ToInt32(sVal);
2935
                sVal = ini.IniReadValue("waypoints", "fscolor");
2936
                if(sVal != "") comboBoxFSColor.SelectedIndex = Convert.ToInt32(sVal);
2937
                sVal = ini.IniReadValue("waypoints", "coptercolor");
2938
                if(sVal != "") comboBoxCopterColor.SelectedIndex = Convert.ToInt32(sVal);
2385 - 2939
                sVal = ini.IniReadValue("waypoints", "copterheadingcolor");
2940
                if(sVal != "") comboBoxCopterHeadingColor.SelectedIndex = Convert.ToInt32(sVal);
2379 - 2941
                sVal = ini.IniReadValue("waypoints", "landingcolor");
2942
                if(sVal != "") comboBoxLandingColor.SelectedIndex = Convert.ToInt32(sVal);
2328 - 2943
                sVal = ini.IniReadValue("waypoints", "routecolor");
2944
                if(sVal != "") comboBoxRouteColor.SelectedIndex = Convert.ToInt32(sVal);
2945
                sVal = ini.IniReadValue("waypoints", "showWPRoute");
2946
                if(sVal != "") _bShowWPRoute = Convert.ToBoolean(sVal);
2408 - 2947
                sVal = ini.IniReadValue("waypoints", "showWPMaxRange");
2948
                if(sVal != "") checkBoxShowWPMaxRange.IsChecked = Convert.ToBoolean(sVal);
2949
                sVal = ini.IniReadValue("waypoints", "WPMaxRangecolor");
2950
                if(sVal != "") comboBoxWPMaxRangeColor.SelectedIndex = Convert.ToInt32(sVal);
2349 - 2951
 
2952
                for (int i = 0; i < 12; i++)
2953
                {
2954
                    sVal = ini.IniReadValue("serial", "ch" + i.ToString() + "Val");
2955
                    if (sVal != "")
2956
                        serChan[i] = Convert.ToInt16(sVal);
2957
                    sVal = ini.IniReadValue("serial", "ch" + i.ToString() + "Title");
2958
                    if (sVal != "")
2959
                        serChanTitle[i] = sVal;
2960
                    for (int y = 0; i < 4 && y < 3; y++)
2961
                    {
2962
                        sVal = ini.IniReadValue("serial", "ch" + i.ToString() + "ValSub" + y.ToString());
2963
                        if (sVal != "")
2964
                            serChan_sub[(i * 3) + y] = Convert.ToInt16(sVal);
2965
                    }
2966
                }
2967
 
2312 - 2968
            }
2969
            catch (Exception e)
2970
            {
2287 - 2971
 
2312 - 2972
                MessageBox.Show("Error parsing ini-file!" + Environment.NewLine + e.Message,"Read ini-file" ,MessageBoxButton.OK,MessageBoxImage.Error);
2973
            }
2974
 
2287 - 2975
        }
2976
 
2977
        /// <summary>
2978
        /// save settings to ini-file
2979
        /// </summary>
2980
        void _writeIni()
2981
        {
2982
 
2983
            IniFile ini = new IniFile("MKLiveViewSettings.ini");
2984
            ini.path = filePath + "\\MKLiveViewSettings.ini";
2985
 
2312 - 2986
            try
2987
            {
2287 - 2988
 
2312 - 2989
                ini.IniWriteValue("timings", "AutorefreshDebugData", _debugDataAutorefresh ? "true" : "false");
2990
                ini.IniWriteValue("timings", "AutorefreshNavCtrlData", _navCtrlDataAutorefresh ? "true" : "false");
2991
                ini.IniWriteValue("timings", "AutorefreshBLCtrlData", _blctrlDataAutorefresh ? "true" : "false");
2992
                ini.IniWriteValue("timings", "AutorefreshOSDData", _OSDAutorefresh ? "true" : "false");
2287 - 2993
 
2312 - 2994
                ini.IniWriteValue("timings", "IntervalDebugData", debugInterval.ToString());
2995
                ini.IniWriteValue("timings", "IntervalNavCtrlData", navctrlInterval.ToString());
2996
                ini.IniWriteValue("timings", "IntervalBLCtrlData", blctrlInterval.ToString());
2997
                ini.IniWriteValue("timings", "IntervalOSDData", OSDInterval.ToString());
2287 - 2998
 
2312 - 2999
                ini.IniWriteValue("general", "LiPoCells", _LipoCells.ToString());
3000
                ini.IniWriteValue("general", "Motors", _iMotors.ToString());
2287 - 3001
 
2312 - 3002
                ini.IniWriteValue("map", "followMe", _bFollowCopter.ToString());
3003
                ini.IniWriteValue("map", "AutoSetHome", _bAutoHome.ToString());
2324 - 3004
                ini.IniWriteValue("map", "GPXLog", _bGPXLog.ToString());
2287 - 3005
 
2312 - 3006
                ini.IniWriteValue("topBar", "voltage", chkBoxTopBarShowVoltage.IsChecked.ToString());
3007
                ini.IniWriteValue("topBar", "capacity", chkBoxTopBarShowCapacity.IsChecked.ToString());
3008
                ini.IniWriteValue("topBar", "current", chkBoxTopBarShowCurrent.IsChecked.ToString());
3009
                ini.IniWriteValue("topBar", "flightTime", chkBoxTopBarShowFlightTime.IsChecked.ToString());
3010
                ini.IniWriteValue("topBar", "distanceHP", chkBoxTopBarShowDistanceHP.IsChecked.ToString());
3011
                ini.IniWriteValue("topBar", "height", chkBoxTopBarShowHeight.IsChecked.ToString());
3012
                ini.IniWriteValue("topBar", "speed", chkBoxTopBarShowSpeed.IsChecked.ToString());
3013
                ini.IniWriteValue("topBar", "magneticField", chkBoxTopBarShowMF.IsChecked.ToString());
3014
                ini.IniWriteValue("topBar", "satellites", chkBoxTopBarShowSatellites.IsChecked.ToString());
3015
                ini.IniWriteValue("topBar", "rc", chkBoxTopBarShowRC.IsChecked.ToString());
2287 - 3016
 
2312 - 3017
                ini.IniWriteValue("style", "saveFullScreen", chkBoxSaveFullScreenState.IsChecked.ToString());
3018
                ini.IniWriteValue("style", "saveNormalState", chkBoxSaveNormalState.IsChecked.ToString());
2287 - 3019
 
2312 - 3020
                ini.IniWriteValue("style", "scaleNormalAll", scaleNormalAll.ToString());
3021
                ini.IniWriteValue("style", "scaleNormalTopBar", scaleNormalTopBar.ToString());
3022
                ini.IniWriteValue("style", "scaleNormalMotors", scaleNormalMotors.ToString());
3023
                ini.IniWriteValue("style", "scaleNormalOSD", scaleNormalOSD.ToString());
3024
                ini.IniWriteValue("style", "scaleNormalLOG", scaleNormalLOG.ToString());
3025
                ini.IniWriteValue("style", "scaleNormalHorizon", scaleNormalHorizon.ToString());
2287 - 3026
 
2312 - 3027
                ini.IniWriteValue("style", "scaleFullAll", scaleFullAll.ToString());
3028
                ini.IniWriteValue("style", "scaleFullTopBar", scaleFullTopBar.ToString());
3029
                ini.IniWriteValue("style", "scaleFullMotors", scaleFullMotors.ToString());
3030
                ini.IniWriteValue("style", "scaleFullOSD", scaleFullOSD.ToString());
3031
                ini.IniWriteValue("style", "scaleFullLOG", scaleFullLOG.ToString());
3032
                ini.IniWriteValue("style", "scaleFullHorizon", scaleFullHorizon.ToString());
2287 - 3033
 
2312 - 3034
                ini.IniWriteValue("style", "horizon", chkBoxShowHorizon.IsChecked.ToString());
3035
 
3036
                ini.IniWriteValue("threshold", "VoltageWarning", _dThresholdVoltageWarn.ToString());
3037
                ini.IniWriteValue("threshold", "VoltageCritical", _dThresholdVoltageCrit.ToString());
3038
                ini.IniWriteValue("threshold", "VoiceVoltageEnable", _bVoiceVoltPlay.ToString());
3039
                ini.IniWriteValue("threshold", "VoiceSatFixEnable", _bVoiceSatFixPlay.ToString());
3040
                ini.IniWriteValue("threshold", "VoiceMagFieldEnable", _bVoiceMagneticFieldPlay.ToString());
3041
                ini.IniWriteValue("threshold", "VoiceDistanceWarnEnable", _bVoiceDistancePlay.ToString());
3042
                ini.IniWriteValue("threshold", "VoiceRCLevelWarnEnable", _bVoiceRCLevelPlay.ToString());
3043
                ini.IniWriteValue("threshold", "DistanceWarning", _dThresholdDistanceWarn.ToString());
3044
                ini.IniWriteValue("threshold", "MaxDistance", _dThresholdDistanceMax.ToString());
3045
                ini.IniWriteValue("threshold", "RCThreshold", _iThresholdRC.ToString());
3046
                ini.IniWriteValue("threshold", "MagFieldThreshold", _iThresholdMagField.ToString());
2321 - 3047
 
3048
                ini.IniWriteValue("waypoints", "wpcolor", comboBoxWPColor.SelectedIndex.ToString());
3049
                ini.IniWriteValue("waypoints", "poicolor", comboBoxPOIColor.SelectedIndex.ToString());
3050
                ini.IniWriteValue("waypoints", "fscolor", comboBoxFSColor.SelectedIndex.ToString());
3051
                ini.IniWriteValue("waypoints", "coptercolor", comboBoxCopterColor.SelectedIndex.ToString());
2385 - 3052
                ini.IniWriteValue("waypoints", "copterheadingcolor", comboBoxCopterHeadingColor.SelectedIndex.ToString());
2379 - 3053
                ini.IniWriteValue("waypoints", "landingcolor", comboBoxLandingColor.SelectedIndex.ToString());
2328 - 3054
                ini.IniWriteValue("waypoints", "routecolor", comboBoxRouteColor.SelectedIndex.ToString());
3055
                ini.IniWriteValue("waypoints", "showWPRoute", _bShowWPRoute.ToString());
2408 - 3056
                ini.IniWriteValue("waypoints", "showWPMaxRange", ((bool)checkBoxShowWPMaxRange.IsChecked).ToString());
3057
                ini.IniWriteValue("waypoints", "WPMaxRangecolor", comboBoxWPMaxRangeColor.SelectedIndex.ToString());
2349 - 3058
 
3059
                for (int i = 0; i < 12; i++)
3060
                {
3061
                    ini.IniWriteValue("serial", "ch" + i.ToString() + "Val", serChan[i].ToString());
3062
                    ini.IniWriteValue("serial", "ch" + i.ToString() + "Title", serChanTitle[i]);
3063
                    for (int y = 0; i < 4 && y < 3; y++)
3064
                    {
3065
                        ini.IniWriteValue("serial", "ch" + i.ToString() + "ValSub" + y.ToString(), serChan_sub[(i * 3) + y].ToString());
3066
                    }
3067
                }
3068
 
2312 - 3069
            }
3070
            catch (Exception e)
3071
            {
3072
 
3073
                MessageBox.Show("Error writing ini-file!" + Environment.NewLine + "Please make sure that the programm is in a location where it is allowed to write" + Environment.NewLine + e.Message, "Write ini-file", MessageBoxButton.OK, MessageBoxImage.Error);
3074
            }
2287 - 3075
        }
2350 - 3076
 
2349 - 3077
        #region serial channels
3078
        /// <summary>
3079
        /// Sending the serial channel values
3080
        /// </summary>
3081
        void _sendSerialData()
3082
        {
3083
            byte[] serData = new byte[12];
3084
            for (int i = 0; i < 12; i++)
3085
            {
3086
                serData[i] = unchecked((byte)(serChan[i] - 127));
3087
            }
3088
            _sendControllerMessage('y', 1, serData);
3089
        }
3090
        /// <summary>
3091
        /// init the controls for displaying
3092
        /// and setting serial control channels
3093
        /// </summary>
3094
        void _initSerialCtrl()
3095
        {
3096
            SerChan1ScaleSlider.Value = serChan[0];
3097
            textBoxSerial1.Text = serChanTitle[0];
3098
            SerChan2ScaleSlider.Value = serChan[1];
3099
            textBoxSerial2.Text = serChanTitle[1];
2350 - 3100
            SerChan3ScaleSlider.Value = serChan[2];
3101
            textBoxSerial3.Text = serChanTitle[2];
2349 - 3102
            //SerChan4ScaleSlider.Value = serChan[3];
3103
            //textBoxSerial4.Text = serChanTitle[3];
3104
            //trckbarSerial5.Value = serChan[4];
3105
            //textBoxSerial5.Text = serChanTitle[4];
3106
            //trckbarSerial6.Value = serChan[5];
3107
            //textBoxSerial6.Text = serChanTitle[5];
3108
            //trckbarSerial7.Value = serChan[6];
3109
            //textBoxSerial7.Text = serChanTitle[6];
3110
            //trckbarSerial8.Value = serChan[7];
3111
            //textBoxSerial8.Text = serChanTitle[7];
2312 - 3112
 
2349 - 3113
            textBoxSerial1_val1.Text = serChan_sub[0].ToString();
3114
            textBoxSerial1_val2.Text = serChan_sub[1].ToString();
3115
            textBoxSerial1_val3.Text = serChan_sub[2].ToString();
3116
            textBoxSerial2_val1.Text = serChan_sub[3].ToString();
3117
            textBoxSerial2_val2.Text = serChan_sub[4].ToString();
3118
            textBoxSerial2_val3.Text = serChan_sub[5].ToString();
2350 - 3119
            textBoxSerial3_val1.Text = serChan_sub[6].ToString();
3120
            textBoxSerial3_val2.Text = serChan_sub[7].ToString();
3121
            textBoxSerial3_val3.Text = serChan_sub[8].ToString();
2349 - 3122
            //textBoxSerial4_val1.Text = serChan_sub[9].ToString();
3123
            //textBoxSerial4_val2.Text = serChan_sub[10].ToString();
3124
            //textBoxSerial4_val3.Text = serChan_sub[11].ToString();
3125
        }
3126
        private void SerChan1ScaleSlider_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
3127
        {
3128
            if (!_init)
3129
            {
3130
                serChan[0] = (int)SerChan1ScaleSlider.Value;
3131
                _sendSerialData();
3132
            }
3133
        }
3134
        private void textBoxSerial1_TextChanged(object sender, TextChangedEventArgs e)
3135
        {
3136
            if (!_init)
3137
            {
3138
                serChanTitle[0] = textBoxSerial1.Text;
3139
            }
3140
        }
3141
        private void textBoxSerial1_val1_TextChanged(object sender, TextChangedEventArgs e)
3142
        {
3143
            if (textBoxSerial1_val1.Text.Length > 0 & !_init)
3144
            {
3145
                serChan_sub[0] = Convert.ToInt16(textBoxSerial1_val1.Text);
3146
            }
3147
        }
3148
        private void textBoxSerial1_val2_TextChanged(object sender, TextChangedEventArgs e)
3149
        {
3150
            if (textBoxSerial1_val2.Text.Length > 0 & !_init)
3151
            {
3152
                serChan_sub[1] = Convert.ToInt16(textBoxSerial1_val2.Text);
3153
            }
3154
        }
3155
        private void textBoxSerial1_val3_TextChanged(object sender, TextChangedEventArgs e)
3156
        {
3157
            if (textBoxSerial1_val3.Text.Length > 0 & !_init)
3158
            {
3159
                serChan_sub[2] = Convert.ToInt16(textBoxSerial1_val3.Text);
3160
            }
3161
        }
3162
        private void btnSer1_val1_Click(object sender, RoutedEventArgs e)
3163
        {
3164
            if (textBoxSerial1_val1.Text.Length > 0)
3165
            {
3166
                SerChan1ScaleSlider.Value = Convert.ToInt16(textBoxSerial1_val1.Text);
3167
            }
3168
        }
3169
        private void btnSer1_0_Click(object sender, RoutedEventArgs e)
3170
        {
3171
            SerChan1ScaleSlider.Value = 0;
3172
        }
3173
        private void btnSer1_127_Click(object sender, RoutedEventArgs e)
3174
        {
3175
            SerChan1ScaleSlider.Value = 127;
3176
        }
3177
        private void btnSer1_254_Click(object sender, RoutedEventArgs e)
3178
        {
3179
            SerChan1ScaleSlider.Value = 254;
3180
        }
3181
        private void btnSer1_val2_Click(object sender, RoutedEventArgs e)
3182
        {
3183
            if (textBoxSerial1_val2.Text.Length > 0)
3184
            {
3185
                SerChan1ScaleSlider.Value = Convert.ToInt16(textBoxSerial1_val2.Text);
3186
            }
3187
        }
3188
        private void btnSer1_val3_Click(object sender, RoutedEventArgs e)
3189
        {
3190
            if (textBoxSerial1_val3.Text.Length > 0)
3191
            {
3192
                SerChan1ScaleSlider.Value = Convert.ToInt16(textBoxSerial1_val3.Text);
3193
            }
3194
        }
3195
 
3196
        private void SerChan2ScaleSlider_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
3197
        {
3198
            if (!_init)
3199
            {
3200
                serChan[1] = (int)SerChan2ScaleSlider.Value;
3201
                _sendSerialData();
3202
            }
3203
        }
3204
        private void textBoxSerial2_TextChanged(object sender, TextChangedEventArgs e)
3205
        {
3206
            if (!_init)
3207
            {
3208
                serChanTitle[1] = textBoxSerial2.Text;
3209
            }
3210
        }
3211
        private void textBoxSerial2_val1_TextChanged(object sender, TextChangedEventArgs e)
3212
        {
3213
            if (textBoxSerial2_val1.Text.Length > 0 & !_init)
3214
            {
3215
                serChan_sub[3] = Convert.ToInt16(textBoxSerial2_val1.Text);
3216
            }
3217
        }
3218
        private void textBoxSerial2_val2_TextChanged(object sender, TextChangedEventArgs e)
3219
        {
3220
            if (textBoxSerial2_val2.Text.Length > 0 & !_init)
3221
            {
3222
                serChan_sub[4] = Convert.ToInt16(textBoxSerial2_val2.Text);
3223
            }
3224
        }
3225
        private void textBoxSerial2_val3_TextChanged(object sender, TextChangedEventArgs e)
3226
        {
3227
            if (textBoxSerial2_val3.Text.Length > 0 & !_init)
3228
            {
3229
                serChan_sub[5] = Convert.ToInt16(textBoxSerial2_val3.Text);
3230
            }
3231
        }
3232
        private void btnSer2_0_Click(object sender, RoutedEventArgs e)
3233
        {
3234
            SerChan2ScaleSlider.Value = 0;
3235
        }
3236
        private void btnSer2_127_Click(object sender, RoutedEventArgs e)
3237
        {
3238
            SerChan2ScaleSlider.Value = 127;
3239
        }
3240
        private void btnSer2_254_Click(object sender, RoutedEventArgs e)
3241
        {
3242
            SerChan2ScaleSlider.Value = 254;
3243
        }
3244
        private void btnSer2_val1_Click(object sender, RoutedEventArgs e)
3245
        {
3246
            if (textBoxSerial2_val1.Text.Length > 0)
3247
            {
3248
                SerChan2ScaleSlider.Value = Convert.ToInt16(textBoxSerial2_val1.Text);
3249
            }
3250
        }
3251
        private void btnSer2_val2_Click(object sender, RoutedEventArgs e)
3252
        {
3253
            if (textBoxSerial2_val2.Text.Length > 0)
3254
            {
3255
                SerChan2ScaleSlider.Value = Convert.ToInt16(textBoxSerial2_val2.Text);
3256
            }
3257
        }
3258
        private void btnSer2_val3_Click(object sender, RoutedEventArgs e)
3259
        {
3260
            if (textBoxSerial2_val3.Text.Length > 0)
3261
            {
3262
                SerChan2ScaleSlider.Value = Convert.ToInt16(textBoxSerial2_val3.Text);
3263
            }
3264
        }
2350 - 3265
 
3266
        private void SerChan3ScaleSlider_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
3267
        {
3268
            if (!_init)
3269
            {
3270
                serChan[2] = (int)SerChan3ScaleSlider.Value;
3271
                _sendSerialData();
3272
            }
3273
        }
3274
        private void textBoxSerial3_TextChanged(object sender, TextChangedEventArgs e)
3275
        {
3276
            if (!_init)
3277
            {
3278
                serChanTitle[2] = textBoxSerial3.Text;
3279
            }
3280
        }
3281
        private void textBoxSerial3_val1_TextChanged(object sender, TextChangedEventArgs e)
3282
        {
3283
            if (textBoxSerial3_val1.Text.Length > 0 & !_init)
3284
            {
3285
                serChan_sub[6] = Convert.ToInt16(textBoxSerial3_val1.Text);
3286
            }
3287
        }
3288
        private void textBoxSerial3_val2_TextChanged(object sender, TextChangedEventArgs e)
3289
        {
3290
            if (textBoxSerial3_val2.Text.Length > 0 & !_init)
3291
            {
3292
                serChan_sub[7] = Convert.ToInt16(textBoxSerial3_val2.Text);
3293
            }
3294
        }
3295
        private void textBoxSerial3_val3_TextChanged(object sender, TextChangedEventArgs e)
3296
        {
3297
            if (textBoxSerial3_val3.Text.Length > 0 & !_init)
3298
            {
3299
                serChan_sub[8] = Convert.ToInt16(textBoxSerial3_val3.Text);
3300
            }
3301
        }
3302
        private void btnSer3_0_Click(object sender, RoutedEventArgs e)
3303
        {
3304
            SerChan3ScaleSlider.Value = 0;
3305
        }
3306
        private void btnSer3_127_Click(object sender, RoutedEventArgs e)
3307
        {
3308
            SerChan3ScaleSlider.Value = 127;
3309
        }
3310
        private void btnSer3_254_Click(object sender, RoutedEventArgs e)
3311
        {
3312
            SerChan3ScaleSlider.Value = 254;
3313
        }
3314
        private void btnSer3_val1_Click(object sender, RoutedEventArgs e)
3315
        {
3316
            if (textBoxSerial3_val1.Text.Length > 0)
3317
            {
3318
                SerChan3ScaleSlider.Value = Convert.ToInt16(textBoxSerial3_val1.Text);
3319
            }
3320
        }
3321
        private void btnSer3_val2_Click(object sender, RoutedEventArgs e)
3322
        {
3323
            if (textBoxSerial3_val2.Text.Length > 0)
3324
            {
3325
                SerChan3ScaleSlider.Value = Convert.ToInt16(textBoxSerial3_val2.Text);
3326
            }
3327
        }
3328
        private void btnSer3_val3_Click(object sender, RoutedEventArgs e)
3329
        {
3330
            if (textBoxSerial3_val3.Text.Length > 0)
3331
            {
3332
                SerChan3ScaleSlider.Value = Convert.ToInt16(textBoxSerial3_val3.Text);
3333
            }
3334
        }
2349 - 3335
        /// <summary>
3336
        /// checks the input of a textbox
3337
        /// for valid data
3338
        /// in this case values 0-254
3339
        /// </summary>
3340
        /// <param name="sender"></param>
3341
        /// <param name="e"></param>
3342
        private void textBox_serial_KeyPress(object sender, KeyEventArgs e)
3343
        {
3344
            if ("1234567890,\b".IndexOf(e.Key.ToString()) < 0) //general check for valid chars(0-9) and backspace (\b)
3345
                e.Handled = true;
3346
            else
3347
            if ("\b".IndexOf(e.Key.ToString()) < 0)
3348
                if (Convert.ToInt16(((TextBox)sender).Text + e.Key) > 254) //if valid and not backspace, check for upper limit of the resulting number
3349
                    e.Handled = true;
3350
                else
3351
                {
3352
                    int i = -1;
3353
                    switch (((TextBox)sender).Name)
3354
                    {
3355
                        case "textBoxSerial1_val1":
3356
                            i = 0;
3357
                            break;
3358
                        case "textBoxSerial1_val2":
3359
                            i = 1;
3360
                            break;
3361
                        case "textBoxSerial1_val3":
3362
                            i = 2;
3363
                            break;
3364
                        case "textBoxSerial2_val1":
3365
                            i = 3;
3366
                            break;
3367
                        case "textBoxSerial2_val2":
3368
                            i = 4;
3369
                            break;
3370
                        case "textBoxSerial2_val3":
3371
                            i = 5;
3372
                            break;
3373
                        case "textBoxSerial3_val1":
3374
                            i = 6;
3375
                            break;
3376
                        case "textBoxSerial3_val2":
3377
                            i = 7;
3378
                            break;
3379
                        case "textBoxSerial3_val3":
3380
                            i = 8;
3381
                            break;
3382
                        case "textBoxSerial4_val1":
3383
                            i = 9;
3384
                            break;
3385
                        case "textBoxSerial4_val2":
3386
                            i = 10;
3387
                            break;
3388
                        case "textBoxSerial4_val3":
3389
                            i = 11;
3390
                            break;
3391
                    }
3392
                    if (i > -1)
3393
                        serChan_sub[i] = Convert.ToInt16(((TextBox)sender).Text + e.Key.ToString());
3394
                }
3395
        }
3396
 
3397
        #endregion serial channels
2315 - 3398
        #region WP
2312 - 3399
        void _readWPLFile()
3400
        {
3401
            Microsoft.Win32.OpenFileDialog fd = new Microsoft.Win32.OpenFileDialog();
3402
            fd.Filter = "Waypointlists | *.wpl";
3403
            fd.Multiselect = false;
3404
            if (fd.ShowDialog().Value)
3405
            {
3406
                string file = fd.SafeFileName;
3407
                IniFile ini = new IniFile(fd.SafeFileName);
3408
                ini.path = fd.FileName;
3409
 
3410
                try
3411
                {
3412
                    string sVal = ini.IniReadValue("General", "FileVersion");
3413
                    if (sVal == "")
3414
                        MessageBox.Show("The file has no version declared - can't go on...", "", MessageBoxButton.OK, MessageBoxImage.Information);
3415
                    else
3416
                    {
3417
                        if (Convert.ToInt16(sVal) < 3)
3418
                            MessageBox.Show("The file version is not supported - can't go on...", "", MessageBoxButton.OK, MessageBoxImage.Information);
3419
                        else
3420
                        {
3421
                            sVal = ini.IniReadValue("General", "NumberOfWaypoints");
3422
                            if (sVal == "")
3423
                                MessageBox.Show("The file has no number of waypoints declared - can't go on...", "", MessageBoxButton.OK, MessageBoxImage.Information);
3424
                            else
3425
                            {
3426
                                int wpnum = Convert.ToInt16(sVal);
3427
                                string wp;
3428
                                int i;
2313 - 3429
                                NumberFormatInfo nfi = new NumberFormatInfo();
3430
                                nfi.NumberDecimalSeparator = ".";
2312 - 3431
                                dtWaypoints.Rows.Clear();
2368 - 3432
                                _wpEdit = -1;_wpIndex = -1;
2327 - 3433
                                _clearMapMarkers(typeof(CustomMarkerWP));
2363 - 3434
                                _clearMapMarkers(typeof(CustomMarkerWPActive));
2328 - 3435
                                wpList.Clear();
3436
                                if (mRouteWP != null)
3437
                                    MainMap.Markers.Remove(mRouteWP);
2363 - 3438
                                //if (wpActiveMarker != null)
3439
                                //    MainMap.Markers.Remove(wpActiveMarker);
2328 - 3440
                                Dispatcher.Invoke(() => lblWPRouteDistance.Content = "0 m");
3441
 
2312 - 3442
                                for (int k = 1; k <= wpnum; k++)
3443
                                {
3444
                                    DataRow dr = dtWaypoints.NewRow();
3445
                                    dr.ItemArray = new object[16];
3446
                                    object[] o = new object[16];
3447
                                    i = 0;
3448
                                    wp = "Point" + k.ToString();
3449
                                    o[i] = k;
3450
                                    i++;
3451
                                    sVal = ini.IniReadValue(wp, "Type");
3452
                                    if (sVal != "")
2315 - 3453
                                        o[i] = Convert.ToInt16(sVal) - 1;
2312 - 3454
                                    i++;
3455
                                    sVal = ini.IniReadValue(wp, "Prefix");
3456
                                    if (sVal != "")
2350 - 3457
                                        o[i] = sVal + k.ToString();
3458
                                   //     o[i] = sVal == "0" ? "!" + k.ToString() : sVal + k.ToString();
2312 - 3459
                                    i++;
2313 - 3460
                                    sVal = ini.IniReadValue(wp, "Latitude");
2312 - 3461
                                    if (sVal != "")
2313 - 3462
                                        o[i] = Convert.ToDouble(sVal, nfi);
2312 - 3463
                                    i++;
2313 - 3464
                                    sVal = ini.IniReadValue(wp, "Longitude");
2312 - 3465
                                    if (sVal != "")
2313 - 3466
                                        o[i] = Convert.ToDouble(sVal, nfi);
2312 - 3467
                                    i++;
3468
                                    sVal = ini.IniReadValue(wp, "Altitude");
3469
                                    if (sVal != "")
2313 - 3470
                                        o[i] = Convert.ToDouble(sVal, nfi);
2312 - 3471
                                    i++;
3472
                                    sVal = ini.IniReadValue(wp, "Heading");
3473
                                    if (sVal != "")
3474
                                        o[i] = Convert.ToInt16(sVal);
3475
                                    i++;
3476
                                    sVal = ini.IniReadValue(wp, "Speed");
3477
                                    if (sVal != "")
2315 - 3478
                                        o[i] = Convert.ToInt16(sVal);
2312 - 3479
                                    i++;
3480
                                    sVal = ini.IniReadValue(wp, "ClimbRate");
3481
                                    if (sVal != "")
3482
                                        o[i] = Convert.ToInt16(sVal);
3483
                                    i++;
3484
                                    sVal = ini.IniReadValue(wp, "Radius");
3485
                                    if (sVal != "")
3486
                                        o[i] = Convert.ToInt16(sVal);
3487
                                    i++;
3488
                                    sVal = ini.IniReadValue(wp, "DelayTime");
3489
                                    if (sVal != "")
3490
                                        o[i] = Convert.ToInt16(sVal);
3491
                                    i++;
3492
                                    sVal = ini.IniReadValue(wp, "AutoTrigger");
3493
                                    if (sVal != "")
3494
                                        o[i] = Convert.ToInt16(sVal); ;
3495
                                    i++;
3496
                                    sVal = ini.IniReadValue(wp, "CAM-Nick");
3497
                                    if (sVal != "")
2313 - 3498
                                        o[i] = Convert.ToInt16(sVal);
2312 - 3499
                                    i++;
3500
                                    o[i] = 0;
3501
                                    i++;
3502
                                    sVal = ini.IniReadValue(wp, "WP_Event_Channel_Value");
3503
                                    if (sVal != "")
3504
                                        o[i] = Convert.ToInt16(sVal);
3505
                                    i++;
3506
                                    o[i] = "New";
3507
 
3508
                                    dr.ItemArray = o;
3509
                                    dtWaypoints.Rows.Add(dr);
2363 - 3510
                                    _createWP(new PointLatLng((double)o[3], (double)o[4]), (string)dr[2], (int)o[1]);
2315 - 3511
 
2312 - 3512
                                    Dispatcher.Invoke(() => lblWPIndex.Content = k.ToString());
3513
                                    Dispatcher.Invoke(() => lblWPCount.Content = k.ToString());
3514
                                    Dispatcher.Invoke(() => dgvWP.Items.Refresh());
3515
                                    Thread.Sleep(10);
3516
                                }
2359 - 3517
                                _routeUpdate();
2312 - 3518
                            }
3519
                        }
3520
                    }
3521
 
3522
                }
3523
                catch (Exception e)
3524
                {
3525
 
3526
                    MessageBox.Show("Error parsing wpl-file!" + Environment.NewLine + e.Message, "Read wpl-file", MessageBoxButton.OK, MessageBoxImage.Error);
3527
                }
3528
 
3529
            }
3530
        }
2350 - 3531
        void _saveWPLFile()
3532
        {
3533
            if (dtWaypoints.Rows.Count > 0)
3534
            {
3535
                Microsoft.Win32.SaveFileDialog fd = new Microsoft.Win32.SaveFileDialog();
3536
                fd.Filter = "Waypointlists | *.wpl";
3537
                fd.AddExtension = true;
3538
                if (fd.ShowDialog().Value)
3539
                {
3540
                    string file = fd.SafeFileName;
3541
                    IniFile ini = new IniFile(fd.SafeFileName);
3542
                    ini.path = fd.FileName;
3543
                    NumberFormatInfo nfi = new NumberFormatInfo();
3544
                    nfi.NumberDecimalSeparator = ".";
3545
 
3546
                    try
3547
                    {
3548
                        ini.IniWriteValue("General", "FileVersion", "3");
3549
                        ini.IniWriteValue("General", "NumberOfWaypoints", dtWaypoints.Rows.Count.ToString());
3550
                        ini.IniWriteValue("General", "Mapfile", "");
3551
                        for(int i = 1; i<=dtWaypoints.Rows.Count; i++)
3552
                        {
3553
                            ini.IniWriteValue("Point" + i.ToString(), "Latitude", ((double)(dtWaypoints.Rows[i-1][3])).ToString(nfi));
3554
                            ini.IniWriteValue("Point" + i.ToString(), "Longitude", ((double)(dtWaypoints.Rows[i - 1][4])).ToString(nfi));
3555
                            ini.IniWriteValue("Point" + i.ToString(), "Radius", dtWaypoints.Rows[i - 1][9].ToString());
3556
                            ini.IniWriteValue("Point" + i.ToString(), "Altitude", dtWaypoints.Rows[i - 1][5].ToString());
3557
                            ini.IniWriteValue("Point" + i.ToString(), "ClimbRate", dtWaypoints.Rows[i - 1][8].ToString());
3558
                            ini.IniWriteValue("Point" + i.ToString(), "DelayTime", dtWaypoints.Rows[i - 1][10].ToString());
3559
                            ini.IniWriteValue("Point" + i.ToString(), "WP_Event_Channel_Value", dtWaypoints.Rows[i - 1][14].ToString());
3560
                            ini.IniWriteValue("Point" + i.ToString(), "Heading", dtWaypoints.Rows[i - 1][6].ToString());
3561
                            ini.IniWriteValue("Point" + i.ToString(), "Speed", dtWaypoints.Rows[i - 1][7].ToString());
3562
                            ini.IniWriteValue("Point" + i.ToString(), "CAM-Nick", dtWaypoints.Rows[i - 1][12].ToString());
3563
                            ini.IniWriteValue("Point" + i.ToString(), "Type", ((int)dtWaypoints.Rows[i - 1][1]+1).ToString());
3564
                            ini.IniWriteValue("Point" + i.ToString(), "Prefix", dtWaypoints.Rows[i - 1][2].ToString().Substring(0, 1)); // == "!" ? "0" : dtWaypoints.Rows[i - 1][2].ToString().Substring(0, 1));
3565
                            ini.IniWriteValue("Point" + i.ToString(), "AutoTrigger", dtWaypoints.Rows[i - 1][11].ToString());
3566
                        }
3567
                        MessageBox.Show(dtWaypoints.Rows.Count.ToString() + " points saved to " + file, "Waypointlist saved", MessageBoxButton.OK, MessageBoxImage.Information);
3568
                    }
3569
                    catch { }
3570
                }
3571
            }
3572
            else
3573
                MessageBox.Show("Nothing to save...");
3574
        }
3575
        private void btnSaveWPLFile_Click(object sender, RoutedEventArgs e)
3576
        {
3577
            _saveWPLFile();
3578
        }
3579
        /// <summary>
3580
        /// set the selected color for the route
3581
        /// </summary>
3582
        /// <param name="color"></param>
3583
        /// <returns></returns>
2328 - 3584
        Brush _getBrush(string color)
3585
        {
3586
            switch (color)
3587
            {
3588
                case "red":
3589
                    return Brushes.Red;
3590
                case "green":
3591
                    return Brushes.Lime;
3592
                case "blue":
3593
                    return Brushes.Aqua;
3594
                case "pink":
3595
                    return Brushes.Magenta;
3596
                case "yellow":
3597
                    return Brushes.Yellow;
3598
                default:
3599
                    return Brushes.Magenta;
3600
            }
3601
        }
2359 - 3602
        void _routeUpdate()
3603
        {
3604
            Dispatcher.Invoke(() =>
3605
            {
3606
                if (comboBoxRouteColor.SelectionBoxItem != null)
3607
                {
3608
                    string s = comboBoxRouteColor.SelectionBoxItem.ToString();
3609
                    mRouteWP = new GMapRoute(wpList, _getBrush(s));
3610
                }
3611
                else
3612
                    mRouteWP = new GMapRoute(wpList, null);
3613
 
3614
                if (_bShowWPRoute)
2368 - 3615
                    MainMap.Markers.Add(mRouteWP);
2359 - 3616
            });
3617
 
3618
            MapRoute mr = new MapRoute(wpList, "WPList");
3619
            Dispatcher.Invoke(() => lblWPRouteDistance.Content = (mr.Distance * 1000).ToString("0 m"));
3620
        }
2363 - 3621
        GMapMarker _createWP(PointLatLng p, string name, int type)
3622
        {
3623
            GMapMarker wpMarker = new GMapMarker(p);
2385 - 3624
            Dispatcher.Invoke(()=>
3625
            {
3626
                wpMarker.Shape = new CustomMarkerWP(this, wpMarker, name, type);
3627
                wpMarker.Offset = new System.Windows.Point(-11.5, -11.5);
3628
                wpMarker.ZIndex = 100;
3629
                _setMarkerColor(wpMarker, type);
3630
                MainMap.Markers.Add(wpMarker);
3631
                if (type == 0 || type == 3)
3632
                    wpList.Add(p);
3633
            });
2363 - 3634
            return wpMarker;
3635
        }
2315 - 3636
        void _setMarkerColor(GMapMarker wpMarker,int iType)
3637
        {
2369 - 3638
            if(wpMarker != null)
2315 - 3639
            Dispatcher.Invoke(() =>
3640
            {
3641
                switch (iType)
3642
                {
3643
                    case 0:
3644
                        if (comboBoxWPColor.SelectionBoxItem != null)
3645
                        {
3646
                            string s = comboBoxWPColor.SelectionBoxItem.ToString();
3647
                            ((CustomMarkerWP)(wpMarker.Shape)).setColor(s);
3648
                        }
3649
                        else
2372 - 3650
                            ((CustomMarkerWP)(wpMarker.Shape)).setColor("green");
2315 - 3651
                        break;
3652
                    case 1:
3653
                        if (comboBoxPOIColor.SelectionBoxItem != null)
3654
                        {
3655
                            string s = comboBoxPOIColor.SelectionBoxItem.ToString();
3656
                            ((CustomMarkerWP)(wpMarker.Shape)).setColor(s);
3657
                        }
3658
                        else
2372 - 3659
                            ((CustomMarkerWP)(wpMarker.Shape)).setColor("pink");
2315 - 3660
                        break;
3661
                    case 2:
3662
                        if (comboBoxFSColor.SelectionBoxItem != null)
3663
                        {
3664
                            string s = comboBoxFSColor.SelectionBoxItem.ToString();
3665
                            ((CustomMarkerWP)(wpMarker.Shape)).setColor(s);
3666
                        }
3667
                        else
3668
                            ((CustomMarkerWP)(wpMarker.Shape)).setColor("red");
3669
                        break;
2372 - 3670
                    case 3:
3671
                        if (comboBoxLandingColor.SelectionBoxItem != null)
3672
                        {
3673
                            string s = comboBoxLandingColor.SelectionBoxItem.ToString();
3674
                            ((CustomMarkerWP)(wpMarker.Shape)).setColor(s);
3675
                        }
3676
                        else
3677
                            ((CustomMarkerWP)(wpMarker.Shape)).setColor("blue");
3678
                        break;
2315 - 3679
                    default:
3680
                        ((CustomMarkerWP)(wpMarker.Shape)).setColor("red");
3681
                        break;
3682
                }
3683
            });
2312 - 3684
 
2315 - 3685
        }
2372 - 3686
        void _MarkerColorSelection(object sender,int type)
3687
        {
2315 - 3688
            Dispatcher.Invoke(() =>
3689
            {
2372 - 3690
                if (((ComboBox)sender).SelectionBoxItem != null)
2315 - 3691
                {
3692
                    for (int k = 0; k < MainMap.Markers.Count; k++)
3693
                    {
3694
                        GMapMarker p = MainMap.Markers[k];
2372 - 3695
                        if (p.Shape != null && p.Shape.GetType() == typeof(CustomMarkerWP))
2315 - 3696
                        {
2372 - 3697
                            if (((CustomMarkerWP)p.Shape).WPType == type)
2315 - 3698
                            {
2372 - 3699
                                string s = ((ComboBox)sender).SelectionBoxItem.ToString();
2315 - 3700
                                ((CustomMarkerWP)(p.Shape)).setColor(s);
3701
                            }
3702
                        }
3703
                    }
3704
                }
3705
            });
2287 - 3706
        }
2379 - 3707
        private void comboBoxWPColor_DropDownClosed(object sender, EventArgs e)
2318 - 3708
        {
2376 - 3709
            _MarkerColorSelection(sender, 0);
3710
        }
3711
        private void comboBoxPOIColor_DropDownClosed(object sender, EventArgs e)
3712
        {
3713
            _MarkerColorSelection(sender, 1);
3714
        }
3715
        private void comboBoxFSColor_DropDownClosed(object sender, EventArgs e)
3716
        {
3717
            _MarkerColorSelection(sender, 2);
3718
        }
3719
        private void comboBoxLandingColor_DropDownClosed(object sender, EventArgs e)
3720
        {
3721
            _MarkerColorSelection(sender,3);
3722
        }
2385 - 3723
        private void comboBoxCopterColor_DropDownClosed(object sender, EventArgs e)
2376 - 3724
        {
2318 - 3725
            Dispatcher.Invoke(() => {
3726
                if (comboBoxCopterColor.SelectionBoxItem != null)
3727
                {
3728
                    string s = comboBoxCopterColor.SelectionBoxItem.ToString();
2385 - 3729
                    ((CustomMarkerCopter)(copter.Shape)).setCopterColor(s);
2318 - 3730
                }
3731
                else
2385 - 3732
                    ((CustomMarkerCopter)(copter.Shape)).setCopterColor("red");
2318 - 3733
            });
3734
        }
2385 - 3735
        private void comboBoxCopterHeadingColor_DropDownClosed(object sender, EventArgs e)
3736
        {
3737
            Dispatcher.Invoke(() => {
3738
                if (comboBoxCopterHeadingColor.SelectionBoxItem != null)
3739
                {
3740
                    string s = comboBoxCopterHeadingColor.SelectionBoxItem.ToString();
3741
                    ((CustomMarkerCopter)(copter.Shape)).setHeadingColor(s);
3742
                }
3743
                else
3744
                    ((CustomMarkerCopter)(copter.Shape)).setHeadingColor("red");
3745
            });
3746
        }
2328 - 3747
        private void comboBoxRouteColor_DropDownClosed(object sender, EventArgs e)
3748
        {
3749
            Dispatcher.Invoke(() =>
3750
            {
3751
                if (comboBoxRouteColor.SelectionBoxItem != null)
3752
                {
3753
                    string s = comboBoxRouteColor.SelectionBoxItem.ToString();
3754
                    MainMap.Markers.Remove(mRouteWP);
3755
                    mRouteWP = new GMapRoute(wpList, _getBrush(s));
3756
                    if (_bShowWPRoute)
3757
                        MainMap.Markers.Add(mRouteWP);
3758
                }
3759
            });
3760
        }
2408 - 3761
        private void comboBoxWPMaxRangeColor_DropDownClosed(object sender, EventArgs e)
3762
        {
3763
            Dispatcher.Invoke(() =>
3764
            {
3765
                if (comboBoxWPMaxRangeColor.SelectionBoxItem != null)
3766
                {
3767
                    if (home != null && checkBoxShowWPMaxRange.IsChecked == true && dWPMaxRange > 0)
3768
                    {
3769
                        if (cWPBound != null && cWPBound.Tag != null)
3770
                            MainMap.Markers.Remove(cWPBound.Tag as GMapMarker);
3771
 
3772
                       createCircle(home.Position, dWPMaxRange);
3773
                       string s = comboBoxWPMaxRangeColor.SelectionBoxItem.ToString();
3774
                       cWPBound.setColor(s);
3775
 
3776
                    }
3777
                }
3778
            });
3779
 
3780
        }
2328 - 3781
        private void checkBoxShowWPRoute_Click(object sender, RoutedEventArgs e)
3782
        {
3783
            _bShowWPRoute = (bool)checkBoxShowWPRoute.IsChecked;
3784
            if (_bShowWPRoute)
3785
            {
3786
                if (mRouteWP != null)
3787
                    MainMap.Markers.Add(mRouteWP);
3788
            }
3789
            else
3790
            {
3791
                if (mRouteWP != null)
3792
                    MainMap.Markers.Remove(mRouteWP);
3793
            }
3794
        }
2315 - 3795
        private void btnLoadWPLFile_Click(object sender, RoutedEventArgs e)
2287 - 3796
        {
2315 - 3797
            _readWPLFile();
2287 - 3798
        }
2335 - 3799
        private void btnClearWPList_Click(object sender, RoutedEventArgs e)
3800
        {
3801
            _clearMapMarkers(typeof(CustomMarkerWP));
2347 - 3802
            _clearMapMarkers(typeof(CustomMarkerWPActive));
2335 - 3803
            wpList.Clear();
3804
            if (mRouteWP != null)
3805
                MainMap.Markers.Remove(mRouteWP);
2347 - 3806
            //if (wpActiveMarker != null)
3807
            //    MainMap.Markers.Remove(wpActiveMarker);
2335 - 3808
            dtWaypoints.Rows.Clear();
2356 - 3809
            _wpEdit = -1;
2368 - 3810
            _wpIndex = -1;
2335 - 3811
            Dispatcher.Invoke(() => dgvWP.Items.Refresh());
3812
            Dispatcher.Invoke(() => lblWPIndex.Content = 0);
3813
            Dispatcher.Invoke(() => lblWPCount.Content = 0);
3814
            Dispatcher.Invoke(() => lblWPRouteDistance.Content = "0 m");
3815
        }
2340 - 3816
        private void btnClearCopterList_Click(object sender, RoutedEventArgs e)
3817
        {
3818
            Thread t = new Thread(new ThreadStart(clearCopterWPList));
3819
            t.Start();
3820
        }
2355 - 3821
        private void btnSendActiveWP_Click(object sender, RoutedEventArgs e)
2340 - 3822
        {
3823
            if (dgvWP.SelectedIndex > -1 && dgvWP.SelectedIndex < dtWaypoints.Rows.Count)
3824
            {
2372 - 3825
                if (_wpCount > 0)
2376 - 3826
                    _sendWayPoint(dtWaypoints.Rows[dgvWP.SelectedIndex], -1, 's',false);
2372 - 3827
                else
2376 - 3828
                    _sendWayPoint(dtWaypoints.Rows[dgvWP.SelectedIndex], 1, 's',false);
2363 - 3829
 
2372 - 3830
                //int index = dgvWP.SelectedIndex;
3831
                //Thread t = new Thread(() => _sendWPList(index));
3832
                //t.Start();
2354 - 3833
 
3834
                Dispatcher.Invoke(() => {
3835
                    DataGridRow row;
2368 - 3836
                    if (_wpEdit > -1 && _wpEdit < dgvWP.ItemContainerGenerator.Items.Count)
2354 - 3837
                    {
2368 - 3838
                        row = (DataGridRow)dgvWP.ItemContainerGenerator.ContainerFromIndex(_wpEdit);
2354 - 3839
                        row.Background = new SolidColorBrush(Colors.Transparent);
3840
                        row.BorderBrush = new SolidColorBrush(Colors.Transparent);
3841
                        row.BorderThickness = new Thickness(0);
2376 - 3842
                        dgvWP.UpdateLayout();
2354 - 3843
                    }
2376 - 3844
                    //_wpEdit = dgvWP.SelectedIndex;
3845
                    //row = (DataGridRow)dgvWP.ItemContainerGenerator.ContainerFromIndex(_wpEdit);
3846
                    //row.Background = new SolidColorBrush(Color.FromArgb(80, 0, 255, 100));
3847
                    //row.BorderBrush = new SolidColorBrush(Colors.SpringGreen);
3848
                    //row.BorderThickness = new Thickness(2);
2354 - 3849
                });
2340 - 3850
            }
3851
        }
2385 - 3852
        private void btnEditWPSendToCopter_Click(object sender, RoutedEventArgs e)
3853
        {
3854
            if (dgvWP.SelectedIndex > -1 && dgvWP.SelectedIndex < dtWaypoints.Rows.Count)
3855
            {
3856
 
3857
                object[] o = new object[16];
3858
                o[0] = dgvWP.SelectedIndex + 1;
3859
                o[1] = cbWPEditType.SelectedIndex;
3860
                o[2] = tbWPEditPrefix.Text + (dgvWP.SelectedIndex + 1).ToString();
3861
                o[3] = Convert.ToDouble(tbWPEditLat.Text.Replace('.', ','));
3862
                o[4] = Convert.ToDouble(tbWPEditLon.Text.Replace('.', ','));
3863
                o[5] = tbWPEditAlt.Text;
3864
                switch (cbWPEditHeading.SelectedIndex)
3865
                {
3866
                    case 0:
3867
                        o[6] = "0";
3868
                        break;
3869
                    case 1:
3870
                        o[6] = "-" + tbWPEditHeading.Text;
3871
                        break;
3872
                    case 2:
3873
                        o[6] = tbWPEditHeading.Text;
3874
                        break;
3875
                }
3876
                switch (cbWPEditSpeed.SelectedIndex)
3877
                {
3878
                    case 0:
3879
                        o[7] = "0";
3880
                        break;
3881
                    case 1:
3882
                        o[7] = (System.Convert.ToDouble(tbWPEditSpeed.Text.Replace('.', ',')) * 10).ToString("0");
3883
                        break;
3884
                    case 2:
3885
                        o[7] = (256 - Convert.ToInt16(tbWPEditSpeed.Text)).ToString();
3886
                        break;
3887
                }
3888
                switch (cbWPEditClimbrate.SelectedIndex)
3889
                {
3890
                    case 0:
3891
                        o[8] = "255";
3892
                        break;
3893
                    case 1:
3894
                        o[8] = (System.Convert.ToDouble(tbWPEditClimbrate.Text.Replace('.', ',')) * 10).ToString("0");
3895
                        break;
3896
                }
3897
                o[9] = tbWPEditRadius.Text;
3898
                o[10] = tbWPEditHoldtime.Text;
3899
                o[11] = tbWPEditAutoTrigger.Text;
3900
                switch (cbWPEditCamAngle.SelectedIndex)
3901
                {
3902
                    case 0:
3903
                        o[12] = "0";
3904
                        break;
3905
                    case 1:
3906
                        o[12] = "255";
3907
                        break;
3908
                    case 2:
3909
                        o[12] = tbWPEditCamAngle.Text;
3910
                        break;
3911
                }
3912
                o[13] = 0;
3913
                o[14] = tbWPEditOut1.Text;
3914
                DataRow dr = dtWaypoints.NewRow();
3915
                dr.ItemArray = o;
3916
 
3917
                if (_wpCount > 0)
3918
                    _sendWayPoint(dr, -1, 'w', false);
3919
                else
3920
                    _sendWayPoint(dr, 1, 'w', false);
2399 - 3921
 
3922
                if(_wpIndex > -1 && _wpIndex < dtWaypoints.Rows.Count)
3923
                    _sendWayPoint(dtWaypoints.Rows[_wpIndex], _wpIndex + 1, 's', false);
2385 - 3924
            }
3925
        }
2376 - 3926
        private void btnWPSimulateStart_Click(object sender, RoutedEventArgs e)
3927
        {
3928
            _Simulate = !_Simulate;
3929
            if (dtWaypoints.Rows.Count > 0)
3930
            {
3931
                DataRow dr = dtWaypoints.Rows[0];
3932
                dr[13] = _Simulate ? 3 : 0;
2379 - 3933
                _sendWayPoint(dr, 0, 's', true);
2381 - 3934
                rectSimulate.Visibility = lblSimu.Visibility = _Simulate ? Visibility.Visible : Visibility.Hidden;
2376 - 3935
            }
3936
        }
2355 - 3937
        private void dgvWP_MouseUp(object sender, MouseButtonEventArgs e)
3938
        {
2359 - 3939
            _dgvWPselectEditRow();
3940
        }
3941
        private void dgvWP_MouseDoubleClick(object sender, MouseButtonEventArgs e)
3942
        {
3943
        }
3944
        void _dgvWPselectEditRow()
3945
        {
2355 - 3946
            if (dgvWP.SelectedIndex > -1 && dgvWP.SelectedIndex < dtWaypoints.Rows.Count)
3947
            {
2368 - 3948
               Dispatcher.Invoke(() => {
2355 - 3949
                    DataGridRow row;
2368 - 3950
                    if (_wpEdit > -1 && _wpEdit < dgvWP.ItemContainerGenerator.Items.Count)
2355 - 3951
                    {
3952
                        row = (DataGridRow)dgvWP.ItemContainerGenerator.ContainerFromIndex(_wpEdit);
3953
                        row.Background = new SolidColorBrush(Colors.Transparent);
3954
                        row.BorderBrush = new SolidColorBrush(Colors.Transparent);
3955
                        row.BorderThickness = new Thickness(0);
3956
                    }
3957
                    _wpEdit = dgvWP.SelectedIndex;
3958
                    row = (DataGridRow)dgvWP.ItemContainerGenerator.ContainerFromIndex(_wpEdit);
3959
                    row.Background = new SolidColorBrush(Color.FromArgb(80, 0, 100, 255));
3960
                    row.BorderBrush = new SolidColorBrush(Colors.Aqua);
3961
                    row.BorderThickness = new Thickness(2);
3962
                    dgvWP.UpdateLayout();
2340 - 3963
 
2355 - 3964
                    _setWPEditFields(_wpEdit);
3965
                });
3966
            }
3967
        }
3968
        void _setWPEditFields(int index)
3969
        {
3970
            int iVal;
3971
            cbWPEditType.SelectedIndex = (int)dtWaypoints.Rows[index][1];
3972
            tbWPEditPrefix.Text = dtWaypoints.Rows[index][2].ToString().Substring(0,1);
3973
            tbWPEditLat.Text = dtWaypoints.Rows[index][3].ToString();
3974
            tbWPEditLon.Text = dtWaypoints.Rows[index][4].ToString();
3975
            tbWPEditAlt.Text = dtWaypoints.Rows[index][5].ToString();
3976
            iVal = Convert.ToInt16(dtWaypoints.Rows[index][6]);
3977
            if (iVal == 0)
3978
            {
3979
                cbWPEditHeading.SelectedIndex = 0;
3980
                tbWPEditHeading.Text = " - - -";
3981
                tbWPEditHeading.IsReadOnly = true;
3982
            }
3983
            if (iVal > 0 && iVal < 360)
3984
            {
3985
                cbWPEditHeading.SelectedIndex = 2;
3986
                tbWPEditHeading.Text = iVal.ToString();
3987
                tbWPEditHeading.IsReadOnly = false;
3988
            }
3989
            if (iVal < 0)
3990
            {
3991
                cbWPEditHeading.SelectedIndex = 1;
3992
                tbWPEditHeading.Text = (Math.Abs(iVal).ToString());
3993
                tbWPEditHeading.IsReadOnly = false;
3994
            }
3995
            iVal = Convert.ToInt16(dtWaypoints.Rows[index][7]);
3996
            if (iVal == 0)
3997
            {
3998
                cbWPEditSpeed.SelectedIndex = 0;
3999
                tbWPEditSpeed.Text = "MAX";
4000
                tbWPEditSpeed.IsReadOnly = true;
4001
            }
4002
            if (iVal > 0 && iVal < 248)
4003
            {
4004
                cbWPEditSpeed.SelectedIndex = 1;
4005
                tbWPEditSpeed.Text = ((double)iVal * 0.1).ToString();
4006
                tbWPEditSpeed.IsReadOnly = false;
4007
            }
4008
            if (iVal > 247)
4009
            {
4010
                cbWPEditSpeed.SelectedIndex = 256 - iVal + 1;
4011
                tbWPEditSpeed.Text = "";
4012
                tbWPEditSpeed.IsReadOnly = true;
4013
            }
4014
            iVal = Convert.ToInt16(dtWaypoints.Rows[index][8]);
4015
            if (iVal == 255)
4016
            {
4017
                cbWPEditClimbrate.SelectedIndex = 0;
4018
                tbWPEditClimbrate.Text = "AUTO";
4019
                tbWPEditClimbrate.IsReadOnly = true;
4020
            }
4021
            else
4022
            {
4023
                cbWPEditClimbrate.SelectedIndex = 1;
4024
                tbWPEditClimbrate.Text = (System.Convert.ToDouble(iVal) / 10).ToString("0.0");
4025
                tbWPEditClimbrate.IsReadOnly = false;
4026
            }
4027
            iVal = Convert.ToInt16(dtWaypoints.Rows[index][9]);
4028
            tbWPEditRadius.Text = iVal.ToString();
4029
            iVal = Convert.ToInt16(dtWaypoints.Rows[index][10]);
4030
            tbWPEditHoldtime.Text = iVal.ToString();
4031
            iVal = Convert.ToInt16(dtWaypoints.Rows[index][11]);
4032
            tbWPEditAutoTrigger.Text = iVal.ToString();
4033
            iVal = Convert.ToInt16(dtWaypoints.Rows[index][12]);
4034
            if (iVal == 0)
4035
            {
4036
                cbWPEditCamAngle.SelectedIndex = 0;
4037
                tbWPEditCamAngle.Text = " - - - ";
4038
                tbWPEditCamAngle.IsReadOnly = true;
4039
            }
4040
            if (iVal < 0 | iVal == 255)
4041
            {
4042
                cbWPEditCamAngle.SelectedIndex = 1;
4043
                tbWPEditCamAngle.Text = "AUTO";
4044
                tbWPEditCamAngle.IsReadOnly = true;
4045
            }
4046
            if (iVal > 0 & iVal < 255)
4047
            {
4048
                cbWPEditCamAngle.SelectedIndex = 2;
4049
                tbWPEditCamAngle.Text = iVal.ToString();
4050
                tbWPEditCamAngle.IsReadOnly = false;
4051
            }
4052
            iVal = Convert.ToInt16(dtWaypoints.Rows[index][14]);
4053
            tbWPEditOut1.Text = iVal.ToString();
4054
 
4055
        }
4056
 
2361 - 4057
        private void btnEditWPSave_Click(object sender, RoutedEventArgs e)
4058
        {
2363 - 4059
            if(dgvWP.SelectedIndex > -1 && dgvWP.SelectedIndex < dtWaypoints.Rows.Count)
4060
            {
2369 - 4061
                string oldName = (string)dtWaypoints.Rows[dgvWP.SelectedIndex][2];
2372 - 4062
                int oldType = (int)dtWaypoints.Rows[dgvWP.SelectedIndex][1];
4063
                PointLatLng pOld = new PointLatLng((double)dtWaypoints.Rows[dgvWP.SelectedIndex][3], (double)dtWaypoints.Rows[dgvWP.SelectedIndex][4]);
4064
                int i = wpList.IndexOf(pOld);
2363 - 4065
                dtWaypoints.Rows[dgvWP.SelectedIndex][1] = cbWPEditType.SelectedIndex;
4066
                dtWaypoints.Rows[dgvWP.SelectedIndex][2] = tbWPEditPrefix.Text + (dgvWP.SelectedIndex + 1).ToString();
4067
                dtWaypoints.Rows[dgvWP.SelectedIndex][3] = Convert.ToDouble(tbWPEditLat.Text.Replace('.', ','));
4068
                dtWaypoints.Rows[dgvWP.SelectedIndex][4] = Convert.ToDouble(tbWPEditLon.Text.Replace('.', ','));
2372 - 4069
                if (i > -1)
4070
                {
4071
                    if((int)dtWaypoints.Rows[dgvWP.SelectedIndex][1] == 0 || (int)dtWaypoints.Rows[dgvWP.SelectedIndex][1] == 3)
4072
                        wpList[i] = (new PointLatLng((double)dtWaypoints.Rows[dgvWP.SelectedIndex][3], (double)dtWaypoints.Rows[dgvWP.SelectedIndex][4]));
4073
                    else
4074
                        wpList.Remove(pOld);
4075
                }
4076
                else
4077
                {
4078
                    if ((int)dtWaypoints.Rows[dgvWP.SelectedIndex][1] == 0 || (int)dtWaypoints.Rows[dgvWP.SelectedIndex][1] == 3)
4079
                    {
4080
                        int found = 0;
4081
                        for (int k = 0; k < dgvWP.SelectedIndex; k++)
4082
                            if ((int)dtWaypoints.Rows[k][1] == 0)
4083
                                found++;
4084
                        wpList.Insert(found, new PointLatLng((double)dtWaypoints.Rows[dgvWP.SelectedIndex][3], (double)dtWaypoints.Rows[dgvWP.SelectedIndex][4]));
4085
                    }
4086
                }
2363 - 4087
                dtWaypoints.Rows[dgvWP.SelectedIndex][5] = tbWPEditAlt.Text;
4088
                switch (cbWPEditHeading.SelectedIndex)
4089
                {
4090
                    case 0:
4091
                        dtWaypoints.Rows[dgvWP.SelectedIndex][6] = "0";
4092
                        break;
4093
                    case 1:
4094
                        dtWaypoints.Rows[dgvWP.SelectedIndex][6] = "-" + tbWPEditHeading.Text;
4095
                        break;
4096
                    case 2:
4097
                        dtWaypoints.Rows[dgvWP.SelectedIndex][6] = tbWPEditHeading.Text;
4098
                        break;
4099
                }
4100
                switch (cbWPEditSpeed.SelectedIndex)
4101
                {
4102
                    case 0:
4103
                        dtWaypoints.Rows[dgvWP.SelectedIndex][7] = "0";
4104
                        break;
4105
                    case 1:
4106
                        dtWaypoints.Rows[dgvWP.SelectedIndex][7] = (System.Convert.ToDouble(tbWPEditSpeed.Text.Replace('.', ',')) * 10).ToString("0");
4107
                        break;
4108
                    case 2:
4109
                        dtWaypoints.Rows[dgvWP.SelectedIndex][7] = (256 - Convert.ToInt16(tbWPEditSpeed.Text)).ToString();
4110
                        break;
4111
                }
4112
                switch (cbWPEditClimbrate.SelectedIndex)
4113
                {
4114
                    case 0:
4115
                        dtWaypoints.Rows[dgvWP.SelectedIndex][8] = "255";
4116
                        break;
4117
                    case 1:
4118
                        dtWaypoints.Rows[dgvWP.SelectedIndex][8] = (System.Convert.ToDouble(tbWPEditClimbrate.Text.Replace('.',',')) * 10).ToString("0");
4119
                        break;
4120
                }
4121
                dtWaypoints.Rows[dgvWP.SelectedIndex][9] = tbWPEditRadius.Text;
4122
                dtWaypoints.Rows[dgvWP.SelectedIndex][10] = tbWPEditHoldtime.Text;
4123
                dtWaypoints.Rows[dgvWP.SelectedIndex][11] = tbWPEditAutoTrigger.Text;
4124
                switch (cbWPEditCamAngle.SelectedIndex)
4125
                {
4126
                    case 0:
4127
                        dtWaypoints.Rows[dgvWP.SelectedIndex][12] = "0";
4128
                        break;
4129
                    case 1:
4130
                        dtWaypoints.Rows[dgvWP.SelectedIndex][12] = "255";
4131
                        break;
4132
                    case 2:
4133
                        dtWaypoints.Rows[dgvWP.SelectedIndex][12] = tbWPEditCamAngle.Text;
4134
                        break;
4135
                }
4136
                dtWaypoints.Rows[dgvWP.SelectedIndex][14] = tbWPEditOut1.Text;
2361 - 4137
 
2369 - 4138
                // _clearMapMarkers(typeof(CustomMarkerWP));
4139
                _repositionWPMarker(new PointLatLng((double)dtWaypoints.Rows[dgvWP.SelectedIndex][3], (double)dtWaypoints.Rows[dgvWP.SelectedIndex][4]),oldName);
4140
                _renameWPMarker(oldName, (string)dtWaypoints.Rows[dgvWP.SelectedIndex][2]);
2363 - 4141
                _clearMapMarkers(typeof(CustomMarkerWPActive));
2369 - 4142
                _setMarkerColor(_findWPMarker((string)dtWaypoints.Rows[dgvWP.SelectedIndex][2]), (int)dtWaypoints.Rows[dgvWP.SelectedIndex][1]);
2372 - 4143
                _WPMarkerSetType((string)dtWaypoints.Rows[dgvWP.SelectedIndex][2], (int)dtWaypoints.Rows[dgvWP.SelectedIndex][1]);
2369 - 4144
               // wpList.Clear();
2363 - 4145
                if (mRouteWP != null)
4146
                    MainMap.Markers.Remove(mRouteWP);
4147
 
2369 - 4148
                //for (int k = 0; k < dtWaypoints.Rows.Count; k++)
4149
                //{
4150
                //    _createWP(new PointLatLng((double)dtWaypoints.Rows[k][3], (double)dtWaypoints.Rows[k][4]), (string)dtWaypoints.Rows[k][2], (int)dtWaypoints.Rows[k][1]);
4151
                //}
2363 - 4152
                _routeUpdate();
4153
                dgvWP.Items.Refresh();
4154
 
4155
            }
4156
 
2361 - 4157
        }
4158
        private void btnEditWPDel_Click(object sender, RoutedEventArgs e)
4159
        {
2368 - 4160
            if (dgvWP.SelectedIndex > -1 && dgvWP.SelectedIndex < dtWaypoints.Rows.Count)
4161
            {
4162
                int index = dgvWP.SelectedIndex;
4163
                Dispatcher.Invoke(() => {
4164
                    DataGridRow row;
4165
                    if (_wpEdit > -1 && _wpEdit < dgvWP.ItemContainerGenerator.Items.Count)
4166
                    {
4167
                        row = (DataGridRow)dgvWP.ItemContainerGenerator.ContainerFromIndex(_wpEdit);
4168
                        row.Background = new SolidColorBrush(Colors.Transparent);
4169
                        row.BorderBrush = new SolidColorBrush(Colors.Transparent);
4170
                        row.BorderThickness = new Thickness(0);
4171
                    }
2372 - 4172
                    if ((int)dtWaypoints.Rows[index][1] == 0 || (int)dtWaypoints.Rows[index][1] == 3)
2368 - 4173
                        wpList.Remove(new PointLatLng((double)dtWaypoints.Rows[index][3], (double)dtWaypoints.Rows[index][4]));
4174
                    _clearWPMarker((string)dtWaypoints.Rows[index][2]);
2369 - 4175
                    if (wpActiveMarker != null)
4176
                        MainMap.Markers.Remove(wpActiveMarker);
2368 - 4177
                    dtWaypoints.Rows[index].Delete();
4178
                    _wpIndex = -1;
4179
                    _wpEdit = -1;
4180
                    for (int i = index; i < dtWaypoints.Rows.Count; i++) //change the index of points behind deleted point + rename to new index
4181
                    {
4182
                        dtWaypoints.Rows[i][0] = i + 1;
4183
                        string s1 = (string)dtWaypoints.Rows[i][2]; //old name of WP (Prefix + index)
4184
                        string s2 = s1.Substring(0, 1) + (i + 1).ToString(); //new name of WP
4185
                        _renameWPMarker(s1, s2);
4186
                        dtWaypoints.Rows[i][2] = s2;
4187
                    }
4188
                    lblWPCount.Content = dtWaypoints.Rows.Count;
4189
                    if (mRouteWP != null)
4190
                        MainMap.Markers.Remove(mRouteWP);
4191
                    _routeUpdate();
2361 - 4192
 
2368 - 4193
                    dgvWP.UpdateLayout();
4194
                });
4195
            }
2361 - 4196
        }
2366 - 4197
        private void tbWPEdit_TouchDown(object sender, TouchEventArgs e)
4198
        {
4199
            _wpWEdit(sender);
4200
        }
2361 - 4201
        private void tbWPEdit_KeyDown(object sender, KeyEventArgs e)
4202
        {
2366 - 4203
            _wpWEdit(sender);
4204
        }
2369 - 4205
        private void tbWPEdit_MouseDown(object sender, MouseButtonEventArgs e)
4206
        {
4207
            _wpWEdit(sender);
4208
        }
2366 - 4209
        void _wpWEdit(object sender)
4210
        {
2369 - 4211
           // if (!((TextBox)sender).IsReadOnly)
2361 - 4212
            {
4213
                KeyPad.Keypad k = new KeyPad.Keypad(this);
4214
 
2363 - 4215
                switch (((TextBox)sender).Name)
4216
                {
4217
                    case "tbWPEditLat":
4218
                        k.Title = "Latitude";
4219
                        k.LENGTH = 17;
4220
                        k.MAX = 359.9;
4221
                        break;
4222
                    case "tbWPEditLon":
4223
                        k.Title = "Longitude";
4224
                        k.LENGTH = 17;
4225
                        k.MAX = 359.9;
4226
                        break;
4227
                    case "tbWPEditAlt":
4228
                        k.Title = "Altitude";
4229
                        k.LENGTH = 3;
4230
                        k.MAX = 254;
4231
                        k.disableDecimal();
4232
                        break;
4233
                    case "tbWPEditHeading":
4234
                        k.Title = "Heading";
4235
                        k.LENGTH = 3;
4236
                        k.MAX = 359;
4237
                        k.MIN = 1;
4238
                        k.disableDecimal();
4239
                        break;
4240
                    case "tbWPEditSpeed":
4241
                        k.Title = "Speed";
4242
                        k.LENGTH = 4;
4243
                        k.MAX = 24.7;
4244
                        k.MIN = 0.1;
4245
                        break;
4246
                    case "tbWPEditClimbrate":
4247
                        k.Title = "Climbrate";
4248
                        k.LENGTH = 4;
4249
                        k.MAX = 25.4;
4250
                        k.MIN = 0.1;
4251
                        break;
4252
                    case "tbWPEditRadius":
4253
                        k.Title = "Radius";
4254
                        k.LENGTH = 3;
4255
                        k.MAX = 254;
4256
                        k.disableDecimal();
4257
                        break;
4258
                    case "tbWPEditHoldtime":
4259
                        k.Title = "Holdtime";
4260
                        k.LENGTH = 3;
4261
                        k.MAX = 254;
4262
                        break;
4263
                    case "tbWPEditAutoTrigger":
4264
                        k.Title = "Autotrigger";
4265
                        k.LENGTH = 3;
4266
                        k.MAX = 254;
4267
                        k.disableDecimal();
4268
                        break;
4269
                    case "tbWPEditCamAngle":
4270
                        k.Title = "Camera angle";
4271
                        k.LENGTH = 3;
4272
                        k.MAX = 254;
4273
                        k.MIN = 1;
4274
                        k.disableDecimal();
4275
                        break;
4276
                    case "tbWPEditOut1":
4277
                        k.Title = "OUT1 timer interval";
4278
                        k.LENGTH = 3;
4279
                        k.MAX = 254;
4280
                        k.disableDecimal();
4281
                        break;
4282
                }
4283
                k.Result = ((TextBox)sender).Text;
2366 - 4284
                if (k.ShowDialog() == true && k.Result.Length > 0)
2363 - 4285
                    ((TextBox)sender).Text = k.Result;
2361 - 4286
            }
2366 - 4287
 
2361 - 4288
        }
4289
        private void btnWPAddCurrentPos_Click(object sender, RoutedEventArgs e)
2356 - 4290
        {
2359 - 4291
            object[] o = new object[16];
2356 - 4292
 
2359 - 4293
            o[0] = dgvWP.ItemContainerGenerator.Items.Count+1;
4294
            o[1] = 0;
4295
           //     cbWPEditType.SelectedIndex = 0;
4296
          //  tbWPEditPrefix.Text = "P";
4297
            o[2] = "P" + o[0].ToString();
4298
         //   tbWPEditLat.Text = copter.Position.Lat.ToString();
4299
            o[3] = copter.Position.Lat;
4300
          //  tbWPEditLon.Text = copter.Position.Lng.ToString();
4301
            o[4] = copter.Position.Lng;            
4302
         //   tbWPEditAlt.Text = ((double)iAnalogData[4] / (double)10).ToString();
4303
            o[5] = iAnalogData[4].ToString();
2356 - 4304
 
2359 - 4305
        //    cbWPEditHeading.SelectedIndex = 2;
4306
            o[6] = tbWPEditHeading.Text = iAnalogData[10].ToString();
4307
        //    tbWPEditHeading.IsReadOnly = false;
2356 - 4308
 
2359 - 4309
       //     cbWPEditSpeed.SelectedIndex = 1;
4310
       //     tbWPEditSpeed.Text = "5.0";
4311
       //     tbWPEditSpeed.IsReadOnly = false;
2372 - 4312
            o[7] = "10";
2356 - 4313
 
2359 - 4314
      //      cbWPEditClimbrate.SelectedIndex = 1;
4315
     //       tbWPEditClimbrate.Text = "5.0";
4316
     //       tbWPEditClimbrate.IsReadOnly = false;
2372 - 4317
            o[8] = "10";
2356 - 4318
 
2359 - 4319
     //       tbWPEditRadius.Text = "10";
2372 - 4320
            o[9] = "5";
2359 - 4321
     //       tbWPEditHoldtime.Text = "5";
4322
            o[10] = "5";
4323
      //      tbWPEditAutoTrigger.Text = "0";
4324
            o[11] = "0";
4325
     //       cbWPEditCamAngle.SelectedIndex = 1;
4326
     //       tbWPEditCamAngle.Text = "AUTO";
4327
     //       tbWPEditCamAngle.IsReadOnly = true;
4328
            o[12] = "255";
2356 - 4329
 
2359 - 4330
            o[13] = "0";
4331
           //     tbWPEditOut1.Text = "0";
4332
            o[14] = "0";
4333
            o[15] = "0";
4334
 
4335
            dtWaypoints.Rows.Add(o);
2368 - 4336
            _createWP(new PointLatLng((double)o[3], (double)o[4]), (string)o[2], (int)o[1]);
2359 - 4337
            Dispatcher.Invoke(() => lblWPCount.Content = o[0].ToString());
4338
            if (mRouteWP != null)
4339
                MainMap.Markers.Remove(mRouteWP);
4340
            _routeUpdate();
4341
            Dispatcher.Invoke(() => {
4342
                dgvWP.Items.Refresh();
4343
                dgvWP.SelectedIndex = (int)o[0] -1;
4344
                dgvWP.UpdateLayout();
4345
                _dgvWPselectEditRow();
4346
                });
2356 - 4347
        }
2405 - 4348
        private void checkBoxShowWPStatus_Click(object sender, RoutedEventArgs e)
4349
        {
4350
            if (WPStatus.Visibility == Visibility.Visible)
4351
                GridOSD.Margin = new Thickness(GridOSD.Margin.Left, 36 * UIScaleTopSlider.Value + 36, GridOSD.Margin.Right, GridOSD.Margin.Bottom);
4352
            else
4353
                GridOSD.Margin = new Thickness(GridOSD.Margin.Left, 36 * UIScaleTopSlider.Value, GridOSD.Margin.Right, GridOSD.Margin.Bottom);
4354
        }
4355
        private void checkBoxShowWPMaxRange_click(object sender, RoutedEventArgs e)
4356
        {
4357
            if (home != null && checkBoxShowWPMaxRange.IsChecked == true && dWPMaxRange > 0)
4358
            {
4359
                if (cWPBound != null && cWPBound.Tag != null)
4360
                    MainMap.Markers.Remove(cWPBound.Tag as GMapMarker);
2356 - 4361
 
2408 - 4362
                createCircle(home.Position, dWPMaxRange);
4363
                string s = comboBoxWPMaxRangeColor.SelectionBoxItem.ToString();
4364
                cWPBound.setColor(s);
4365
 
2405 - 4366
            }
2408 - 4367
 
2405 - 4368
            if (checkBoxShowWPMaxRange.IsChecked == false && (cWPBound != null && cWPBound.Tag != null))
4369
                MainMap.Markers.Remove(cWPBound.Tag as GMapMarker);
4370
        }
2315 - 4371
        #endregion WP
2324 - 4372
        #region GPX
4373
        private void checkBoxGPXLog_Click(object sender, RoutedEventArgs e)
4374
        {
4375
            _bGPXLog = (bool)checkBoxGPXLog.IsChecked;
4376
        }
4377
        void _gpxAdd(double lat,double lon, int elevation)
4378
        {
4379
            DataRow dr = dtGPX.NewRow();
4380
            dr[0] = dtGPX.Rows.Count - 1;
4381
            dr[1] = lat;
4382
            dr[2] = lon;
4383
            dr[3] = elevation;
4384
            dr[4] = DateTime.UtcNow.ToString("s", System.Globalization.CultureInfo.InvariantCulture); //2011-01-14T01:59:01Z
4385
            dtGPX.Rows.Add(dr);
4386
        }
4387
        void _saveGPXLog()
4388
        {
4389
            if (!Directory.Exists("GPXLog"))
4390
                Directory.CreateDirectory("GPXLog");
4391
            string SaveFileName = "GPXLog\\" + DateTime.Now.ToString("yyyyMMdd_HHmm") + ".gpx";
4392
            XmlTextWriter myXmlTextWriter = null;
4393
            myXmlTextWriter = new XmlTextWriter(SaveFileName, null);
4394
            NumberFormatInfo nfi = new NumberFormatInfo();
4395
            nfi.NumberDecimalSeparator = ".";
2315 - 4396
 
2324 - 4397
            try
4398
            {
4399
                myXmlTextWriter.Formatting = Formatting.Indented;
4400
 
4401
                myXmlTextWriter.WriteStartDocument();
4402
 
4403
                myXmlTextWriter.WriteStartElement("gpx");
4404
 
4405
                myXmlTextWriter.WriteAttributeString("version", "1.0");
4406
                myXmlTextWriter.WriteAttributeString("creator", "MKLiveView v1.0");
4407
                myXmlTextWriter.WriteAttributeString("xmlns:xsi", "http://www.w3.org/2001/XMLSchema-instance");
4408
                myXmlTextWriter.WriteAttributeString("xmlns", "http://www.topografix.com/GPX/1/1");
4409
                myXmlTextWriter.WriteAttributeString("xsi:schemaLocation", "http://www.topografix.com/GPX/1/1/gpx.xsd");
4410
 
4411
                myXmlTextWriter.WriteElementString("time", DateTime.UtcNow.ToString("u", System.Globalization.CultureInfo.InvariantCulture));
4412
 
4413
                myXmlTextWriter.WriteStartElement("trk");
4414
                myXmlTextWriter.WriteStartElement("trkseg");
4415
                for(int i = 0; i< dtGPX.Rows.Count;i++)
4416
                {
4417
                    myXmlTextWriter.WriteStartElement("trkpt");
4418
                    myXmlTextWriter.WriteAttributeString("lat", dtGPX.Rows[i][1].ToString() != "" ? ((double)dtGPX.Rows[i][1]).ToString(nfi) : "");
4419
                    myXmlTextWriter.WriteAttributeString("lon", dtGPX.Rows[i][2].ToString() != "" ? ((double)dtGPX.Rows[i][2]).ToString(nfi) : "");
4420
                    myXmlTextWriter.WriteElementString("ele", dtGPX.Rows[i][3].ToString());
4421
                    myXmlTextWriter.WriteElementString("time", dtGPX.Rows[i][4].ToString());
4422
                    myXmlTextWriter.WriteEndElement();
4423
                }
4424
                myXmlTextWriter.WriteEndElement();
4425
                myXmlTextWriter.WriteEndElement();
4426
                myXmlTextWriter.WriteEndElement();
4427
            }
4428
            catch (Exception e)
4429
            {
4430
                Console.WriteLine("Exception: {0}", e.ToString());
4431
            }
4432
            finally
4433
            {
4434
                if (myXmlTextWriter != null)
4435
                {
4436
                    myXmlTextWriter.Close();
4437
                }
4438
            }
4439
        }
4440
        private void btnLoadGPXLog_Click(object sender, RoutedEventArgs e)
4441
        {
4442
            _loadGPXLog();
4443
        }
2327 - 4444
        private void btnClearRoute_Click(object sender, RoutedEventArgs e)
4445
        {
4446
            _clearMapMarkers(typeof(GMapRoute));
4447
        }
2324 - 4448
        void _loadGPXLog()
4449
        {
4450
 
4451
            Microsoft.Win32.OpenFileDialog fd = new Microsoft.Win32.OpenFileDialog();
4452
            fd.Filter = "GPX-Logfile | *.gpx";
4453
            fd.Multiselect = false;
4454
            if (fd.ShowDialog().Value)
4455
            {
4456
                string file = fd.FileName;
4457
                try
4458
                {
4459
                    XDocument gpxDoc = XDocument.Load(file);
4460
                    XNamespace gpx = XNamespace.Get("http://www.topografix.com/GPX/1/1");
4461
 
4462
                    NumberFormatInfo nfi = new NumberFormatInfo();
4463
                    nfi.NumberDecimalSeparator = ".";
4464
 
4465
                    var tracks = from track in gpxDoc.Descendants(gpx + "trk")
4466
                                 select new
4467
                                 {
4468
                                     Name = track.Element(gpx + "name") != null ? track.Element(gpx + "name").Value : null,
4469
                                     Segs = (
4470
                                         from trackpoint in track.Descendants(gpx + "trkpt")
4471
                                         select new
4472
                                         {
4473
                                             Latitude = trackpoint.Attribute("lat").Value,
4474
                                             Longitude = trackpoint.Attribute("lon").Value,
4475
                                             Elevation = trackpoint.Element(gpx + "ele") != null ?
4476
                                             trackpoint.Element(gpx + "ele").Value : null,
4477
                                             Time = trackpoint.Element(gpx + "time") != null ?
4478
                                             trackpoint.Element(gpx + "time").Value : null
4479
                                         }
4480
                                     )
4481
                                 };
4482
 
4483
                    List<PointLatLng> wpl = new List<PointLatLng>();
4484
                    foreach(var trk in tracks)
4485
                    {
4486
                        foreach(var trkseg in trk.Segs)
4487
                        {
4488
                            if(trkseg.Latitude != "" && trkseg.Longitude !="")
4489
                            wpl.Add(new PointLatLng(Convert.ToDouble(trkseg.Latitude, nfi), Convert.ToDouble(trkseg.Longitude, nfi)));
4490
                        }
4491
 
4492
                    }
4493
                    if(wpl.Count() > 0)
4494
                    {
2327 - 4495
                        _clearMapMarkers(typeof(GMapRoute));
2324 - 4496
                        MapRoute mr = new MapRoute(wpl, "flying");
2328 - 4497
                        Dispatcher.Invoke(() =>
4498
                        {
4499
                            GMapRoute mRoute;
4500
                            if (comboBoxRouteColor.SelectionBoxItem != null)
4501
                            {
4502
                                string s = comboBoxRouteColor.SelectionBoxItem.ToString();
2366 - 4503
                                mRoute = new GMapRoute(wpl, _getBrush(s));
2328 - 4504
                            }
4505
                            else
2366 - 4506
                                mRoute = new GMapRoute(wpl, null);
2324 - 4507
 
2328 - 4508
                            MainMap.Markers.Add(mRoute);
4509
                        });
2324 - 4510
                    }
4511
 
4512
                }
4513
                catch (Exception e)
4514
                {
4515
                    Console.WriteLine("Exception: {0}", e.ToString());
4516
                }
4517
            }
4518
        }
4519
        #endregion GPX
2315 - 4520
        #endregion functions
2287 - 4521
    }
2315 - 4522
     /// <summary>
4523
    /// formats the wp datatable values for display in datagrid - this is bound in the datagrid as a converter
4524
    /// </summary>
2313 - 4525
    public class waypointsConverter : IValueConverter
4526
    {
4527
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
4528
        {
4529
            if (value != null)
4530
            {
4531
                switch ((string)parameter)
4532
                {
4533
                    case "Latitude":
4534
                        return value.ToString() + " °";
4535
                    case "Longitude":
4536
                        return value.ToString() + " °";
4537
                    case "Radius":
4538
                        return value.ToString() + " m";
4539
                    case "Altitude":
4540
                        return value.ToString() + " m";
4541
                    case "ClimbRate":
4542
                        return value.ToString() == "255" ? "Auto" : (System.Convert.ToDouble(value) / 10).ToString("0.0 m/s");
4543
                    case "DelayTime":
4544
                        return value.ToString() + " s";
4545
                    case "Heading":
4546
                        return Waypoints.Heading(System.Convert.ToInt32(value));
4547
                    case "Speed":
4548
                        return Waypoints.WPSpeed(System.Convert.ToInt16(value));
4549
                    case "CamAngle":
4550
                        return Waypoints.CAMAngle(System.Convert.ToInt16(value));
4551
                    case "Type":
4552
                        return ((Waypoints.pointType)(System.Convert.ToInt16(value))).ToString();
4553
                    case "AutoTrigger":
4554
                        return value.ToString() == "0" ? "- - -" : value.ToString() + " m";
4555
                    case "Status":
2355 - 4556
                        return (Waypoints.status)(System.Convert.ToInt16(value));
2313 - 4557
                }
4558
 
4559
                return value.ToString();
4560
            }
4561
            else return value;
4562
        }
4563
 
4564
        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
4565
        {
4566
            throw new NotImplementedException();
4567
        }
4568
    }
4569
 
2287 - 4570
    public class IniFile
4571
    {
4572
        public string path;
4573
 
4574
        [DllImport("kernel32")]
4575
        private static extern long WritePrivateProfileString(string section,
4576
          string key, string val, string filePath);
4577
 
4578
        [DllImport("kernel32.dll", CharSet = CharSet.Auto)]
4579
        static extern uint GetPrivateProfileSectionNames(IntPtr lpszReturnBuffer,
4580
               uint nSize, string lpFileName);
4581
 
4582
        [DllImport("kernel32")]
4583
        private static extern int GetPrivateProfileString(string section,
4584
          string key, string def, StringBuilder retVal,
4585
          int size, string filePath);
4586
 
4587
        public IniFile(string INIPath)
4588
        {
4589
            path = INIPath;
4590
        }
4591
 
4592
        public void IniWriteValue(string Section, string Key, string Value)
4593
        {
4594
            WritePrivateProfileString(Section, Key, Value, this.path);
4595
        }
4596
 
4597
        public string IniReadValue(string Section, string Key)
4598
        {
4599
            StringBuilder temp = new StringBuilder(255);
4600
            int i = GetPrivateProfileString(Section, Key, "", temp, 255, this.path);
4601
            return temp.ToString();
4602
        }
4603
        //Ini_sections auslesen in String-Array
4604
        public string[] IniSectionNames()
4605
        {
4606
 
4607
            //  uint MAX_BUFFER = 32767;
4608
            uint MAX_BUFFER = 8388608;
4609
            IntPtr pReturnedString = Marshal.AllocCoTaskMem((int)MAX_BUFFER);
4610
            uint bytesReturned = GetPrivateProfileSectionNames(pReturnedString, MAX_BUFFER, this.path);
4611
            if (bytesReturned == 0)
4612
            {
4613
                Marshal.FreeCoTaskMem(pReturnedString);
4614
                return null;
4615
            }
4616
            string local = Marshal.PtrToStringAuto(pReturnedString, (int)bytesReturned).ToString();
4617
            Marshal.FreeCoTaskMem(pReturnedString);
4618
            //use of Substring below removes terminating null for split
4619
            return local.Substring(0, local.Length - 1).Split('\0');
4620
 
4621
 
4622
        }
4623
    }
4624
 
4625
    /// <summary>
4626
    /// Selected Win AI Function Calls
4627
    /// </summary>
4628
    public class WinApi
4629
    {
4630
        [DllImport("user32.dll", EntryPoint = "GetSystemMetrics")]
4631
        public static extern int GetSystemMetrics(int which);
4632
        [DllImport("user32.dll")]
4633
        public static extern void
4634
                SetWindowPos(IntPtr hwnd, IntPtr hwndInsertAfter,
4635
                             int X, int Y, int width, int height, uint flags);
4636
 
4637
        private const int SM_CXSCREEN = 0;
4638
        private const int SM_CYSCREEN = 1;
4639
        private static IntPtr HWND_TOP = IntPtr.Zero;
4640
        private const int SWP_SHOWWINDOW = 64; // 0x0040
4641
 
4642
        public static int ScreenX
4643
        {
4644
            get { return GetSystemMetrics(SM_CXSCREEN); }
4645
        }
4646
 
4647
        public static int ScreenY
4648
        {
4649
            get { return GetSystemMetrics(SM_CYSCREEN); }
4650
        }
4651
 
4652
        public static void SetWinFullScreen(IntPtr hwnd)
4653
        {
4654
            SetWindowPos(hwnd, HWND_TOP, -8, -7, ScreenX+15, ScreenY+14, SWP_SHOWWINDOW);
4655
        }
4656
    }
4657
    /// <summary>
4658
    /// Class used to preserve / restore state of the window
4659
    /// </summary>
4660
    public class WinState
4661
    {
4662
        private WindowState winState;
4663
        private WindowStyle brdStyle;
4664
        private bool topMost;
4665
        private Rect restore;
4666
        private bool IsMaximized = false;
4667
 
4668
        public bool isMaximized
4669
        {
4670
            get { return IsMaximized; }
4671
        }
4672
        public void Maximize(Window targetForm)
4673
        {
4674
            if (!IsMaximized)
4675
            {
4676
                IsMaximized = true;
4677
                Save(targetForm);
4678
                targetForm.WindowState = WindowState.Maximized;
4679
                targetForm.WindowStyle = WindowStyle.None;
4680
                targetForm.Topmost = true;
4681
                WinApi.SetWinFullScreen(new WindowInteropHelper(targetForm).Handle);
4682
            }
4683
        }
4684
 
4685
        public void Save(Window targetForm)
4686
        {
4687
            winState = targetForm.WindowState;
4688
            brdStyle = targetForm.WindowStyle;
4689
            topMost = targetForm.Topmost;
4690
            restore = targetForm.RestoreBounds;
4691
        }
4692
        public void Restore(Window targetForm)
4693
        {
4694
            targetForm.WindowState = winState;
4695
            targetForm.WindowStyle = brdStyle;
4696
            targetForm.Topmost = topMost;
4697
 
4698
            targetForm.Left = restore.Left;
4699
            targetForm.Top = restore.Top;
4700
            targetForm.Height = restore.Height;
4701
            targetForm.Width = restore.Width;
4702
            IsMaximized = false;
4703
        }
4704
    }
4705
 
4706
}