Subversion Repositories Projects

Rev

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