Subversion Repositories Projects

Rev

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