Subversion Repositories Projects

Rev

Rev 2434 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

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