Subversion Repositories Projects

Rev

Details | Last modification | View Log | RSS feed

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