Subversion Repositories Projects

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
2545 - 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[] _UILanguage = new string[] { "en-EN","de-DE"};
284
        string[] _colors = new string[] { "red", "green", "blue", "yellow", "pink" };
285
 
286
        string[] _voiceLanguage = new string[] { "EN","DE"};
287
        int _iVoiceIndex = 0;
288
 
289
        bool _bSatFix = false;
290
        Storyboard stbSatFixLostAnim;
291
        bool _bAnimSatFixActive = false;
292
        bool _bVoiceSatFixActive = false;
293
        bool _bVoiceSatFixPlay = true;
294
        int _iSatsLast = 0;
295
        int _iSatsJitter = 0;
296
 
297
        bool _bMagneticFieldOK = false;
298
        Storyboard stbMagneticFieldAnim;
299
        bool _bAnimMagneticFieldActive = false;
300
        bool _bVoiceMagneticFieldActive = false;
301
        bool _bVoiceMagneticFieldPlay = true;
302
        int _iMagneticFieldLast = 0;
303
        int _iMagneticFieldJitter = 0;
304
 
305
        int _iThresholdBLCTRLTempWarn = 80;
306
        Storyboard stbBLCTRLTempAnim;
307
        bool _bAnimBLCTRLTempActive = false;
308
        bool _bVoiceBLCTRLTempActive = false;
309
        bool _bVoiceBLCTRLTempPlay = true;
310
        int[] _iBLCTRLTempLast = new int[12];
311
        int[] _iBLCTRLTempJitter = new int[12];
312
 
313
        bool _bRCLevelOK = false;
314
        Storyboard stbRCLevelAnim;
315
        bool _bAnimRCLevelActive = false;
316
        bool _bVoiceRCLevelActive = false;
317
        bool _bVoiceRCLevelPlay = true;
318
        int _iRCLevelLast = 0;
319
        int _iRCLevelJitter = 0;
320
 
321
        int _iMotors = 4;
322
        int _LipoCells = 3;
323
        bool _bLiPoAutoDetect = true;
324
 
325
        double _dLipoVMax = 16.88;
326
        double _dLipoVMin = 12;
327
        double _dThresholdVoltageWarn = 0;
328
        double _dThresholdVoltageCrit = 0;
329
        Storyboard stbVoltageCritAnim;
330
        bool _bCritAnimVoltActive = false;
331
        bool _bCritVoiceVoltActive = false;
332
        bool _bWarnVoiceVoltActive = false;
333
        bool _bVoiceVoltPlay = true;
334
        double _dVoltLast = 0;
335
        int _iVoltJitter = 0;
336
 
337
        double _dThresholdDistanceWarn = 100;
338
        Storyboard stbDistanceWarnAnim;
339
        bool _bAnimDistanceActive = false;
340
        bool _bVoiceDistanceActive = false;
341
        bool _bVoiceDistancePlay = true;
342
        double _dDistanceLast = 0;
343
        int _iDistanceJitter = 0;
344
 
345
        double _dThresholdDistanceMax = 1000;
346
        int _iThresholdRC = 160;
347
        int _iThresholdMagField = 15;
348
 
349
        bool _bAutoHome = true;
350
        bool _bFirstSatFix = false;
351
        int _iFirstSatFix = 0;
352
 
353
        double _dTopHeight = 36;
354
 
355
        int[] serChan = new int[12] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
356
        int[] serChan_sub = new int[12] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
357
        string[] serChanTitle = new string[12];
358
 
359
        string[] sAnalogLabel = new string[32];
360
        string[] sAnalogData = new string[32];
361
        int[] iAnalogData = new int[32];
362
 
363
        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 };
364
        int[] iMotors = new int[] { 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 };
365
        string[] sLiPoCells = new string[] { "3s", "4s", "5s", "6s" };
366
        /// <summary>
367
        /// interval for sending debugdata (multiplied by 10ms)
368
        /// </summary>
369
        byte debugInterval = 10; //(=> 100ms)
370
        /// <summary>
371
        /// interval for sending BL-CTRL status (multiplied by 10ms)
372
        /// </summary>
373
        byte blctrlInterval = 75;
374
        /// <summary>
375
        /// interval for sending NAV-CTRL status (multiplied by 10ms)
376
        /// </summary>
377
        byte navctrlInterval = 20;
378
        /// <summary>
379
        /// interval for sending OSD page update (multiplied by 10ms)
380
        /// </summary>
381
        byte OSDInterval = 85;
382
        /// <summary>
383
        /// datatable for the debug data array - displayed on settings tabpage in datagridview
384
        /// </summary>
385
        DataTable dtAnalog = new DataTable();
386
        /// <summary>
387
        /// datatable for motordata (current,temp)
388
        /// </summary>
389
        DataTable dtMotors = new DataTable();
390
 
391
        DataTable dtWaypoints = new DataTable();
392
        static volatile int _iWPCount = -1;
393
        static volatile int _iWPIndex = -1;
394
        int _iWPTimeout = 1000;
395
        bool _bGetWP = false;
396
        bool _bShowWPRoute = true;
397
        bool _bAutoWPEdit = true;
398
        static volatile bool _bGetWPCount = false;
399
        DataTable dtGPX = new DataTable();
400
        DataRow drGPX;
401
        bool _bAirborne = false;
402
        int _wpIndex = -1, _wpCount = 0, _wpEdit = -1;
403
 
404
        string _wpDefPrefix = "P";
405
        int _wpDefAltitude = 20;
406
        int _wpDefHeading = 0;
407
        int _wpDefCBoxHeading = 0;
408
        int _wpDefSpeed = 10;
409
        int _wpDefCBoxSpeed = 0;
410
        int _wpDefClimb = 10;
411
        int _wpDefCBoxClimb = 0;
412
        int _wpDefRadius = 5;
413
        int _wpDefHoldtime = 5;
414
        int _wpDefAutotrig = 0;
415
        int _wpDefCamangle = 0;
416
        int _wpDefCBoxCamangle = 0;
417
        int _wpDefOut1 = 0;
418
 
419
        bool _wpAddCopterHeight = true;
420
        bool _wpAddCopterHeading = true;
421
 
422
        DispatcherTimer timer = new DispatcherTimer();
423
        DispatcherTimer camTimer = new DispatcherTimer();
424
        BitmapSource _camImageSource;
425
        Storyboard stbCamActiveAnim;
426
        bool _bCamAnim;
427
        /// <summary>
428
        /// stuff for enabeling touch zoom for the map
429
        /// </summary>
430
        Point pTouch1 = new Point(0, 0), pTouch2 = new Point(0, 0);
431
        int iFirstStylusID = -1;
432
 
433
        WinState winState = new WinState();
434
        int _iUILanguage = 0;
435
        #endregion declarations
436
        public MainWindow()
437
        {
438
            String path = Environment.ExpandEnvironmentVariables("%SystemRoot%") + "\\System32\\VCRUNTIME140.DLL";
439
            if (!File.Exists(path))
440
            {
441
                MessageBoxResult dr = MessageBox.Show("Visual C++ Redistributable for Visual Studio 2015 seems not to be installed..." +
442
                    Environment.NewLine + "Please download the file for x86 (32bit) @ https://www.microsoft.com/de-de/download/details.aspx?id=48145" +
443
                    Environment.NewLine + Environment.NewLine + "Do You want me to take You there, now?", "Visual C++ Redistributable for Visual Studio 2015 missing ...",
444
                    MessageBoxButton.YesNo,
445
                    MessageBoxImage.Stop,MessageBoxResult.No, MessageBoxOptions.DefaultDesktopOnly);
446
 
447
                if (dr == MessageBoxResult.Yes)
448
                    System.Diagnostics.Process.Start("https://www.microsoft.com/de-de/download/details.aspx?id=48145");
449
 
450
                Application.Current.Shutdown();
451
            }
452
            InitializeComponent();
453
            _initForm();
454
            _dataTablesInit();
455
            _setupMap();
456
            _init = false;
457
            timer.Tick += new EventHandler(timerEvent);
458
            timer.Interval = new TimeSpan(0, 0, 1);
459
            timer.Start();
460
            camTimer.Tick += new EventHandler(camTimer_Tick);
461
            camTimer.Interval = new TimeSpan(0, 0, 0, 0, 5);
462
          //  camTimer.Start();
463
        }
464
 
465
        #region init
466
        void _initForm()
467
        {
468
            _readIni();
469
            if (_bSaveWinStateNormal)
470
                _setScaleSliders(false);
471
            cBoxTimingsDebug.ItemsSource =
472
                cBoxTimingsNav.ItemsSource =
473
                cBoxTimingsBl.ItemsSource =
474
                cBoxTimingsOSD.ItemsSource =
475
                iTimings;
476
            cBoxLiPoCells.ItemsSource = sLiPoCells;
477
            cBoxLiPoCells.SelectedItem = _LipoCells.ToString() + "s";
478
            _LipoMinMax();
479
            sliderThresholdVoltageWarn.Value = _dThresholdVoltageWarn;
480
            sliderThresholdVoltageCrit.Value = _dThresholdVoltageCrit;
481
            checkBoxThresholdVoltageVoice.IsChecked = _bVoiceVoltPlay;
482
            checkBoxSatfixLost.IsChecked = _bVoiceSatFixPlay;
483
            checkBoxMagneticField.IsChecked = _bVoiceMagneticFieldPlay;
484
            checkBoxThresholdDistanceVoice.IsChecked = _bVoiceDistancePlay;
485
            sliderThresholdDistanceWarn.Value = _dThresholdDistanceWarn;
486
            checkBoxRClevel.IsChecked = _bVoiceRCLevelPlay;
487
            sliderThresholdDistanceWarn.Maximum = _dThresholdDistanceMax;
488
            sliderThresholdBLCtrlTempWarn.Value = _iThresholdBLCTRLTempWarn;
489
            checkBoxBLCtrlTempVoice.IsChecked = _bVoiceBLCTRLTempPlay;
490
            comboBoxVoiceLanguage.SelectedIndex = _iVoiceIndex;
491
 
492
            cBoxMotors.ItemsSource = iMotors;
493
            cBoxMotors.SelectedItem = _iMotors;
494
 
495
            serialPortCtrl.PortClosed += serialPortCtrl_PortClosed;
496
            serialPortCtrl.PortOpened += serialPortCtrl_PortOpened;
497
            serialPortCtrl.DataReceived += processMessage;
498
 
499
            chkbAutoBL.IsChecked = _blctrlDataAutorefresh;
500
            chkbAutoDbg.IsChecked = _debugDataAutorefresh;
501
            chkbAutoNav.IsChecked = _navCtrlDataAutorefresh;
502
            chkbAutoOSD.IsChecked = _OSDAutorefresh;
503
            chkbAutoLiPoDetect.IsChecked = _bLiPoAutoDetect;
504
 
505
            cBoxTimingsDebug.SelectedItem = debugInterval * 10;
506
            cBoxTimingsNav.SelectedItem = navctrlInterval * 10;
507
            cBoxTimingsBl.SelectedItem = blctrlInterval * 10;
508
            cBoxTimingsOSD.SelectedItem = OSDInterval * 10;
509
            checkBoxAutoSetHP.IsChecked = _bAutoHome;
510
            checkBoxFollowCopter.IsChecked = _bFollowCopter;
511
            checkBoxGPXLog.IsChecked = _bGPXLog;
512
            checkBoxShowWPRoute.IsChecked = _bShowWPRoute;
513
            checkBoxAutoShowWPEdit.IsChecked = _bAutoWPEdit;
514
            checkBoxWPAddUseCopterHeight.IsChecked = _wpAddCopterHeight;
515
            checkBoxWPAddUseCopterHeading.IsChecked = _wpAddCopterHeading;
516
            GridSettings.Visibility = Visibility.Visible;
517
            GridCam.Visibility = GridData.Visibility = GridWP.Visibility = GridWPEdit.Visibility = Visibility.Collapsed;
518
            _initSerialCtrl();
519
            ChangeLanguage(_UILanguage[_iUILanguage]);
520
            cbLang.SelectedIndex = _iUILanguage;
521
        }
522
        /// <summary>
523
        /// initialize the datatables
524
        /// with columnnames etc
525
        /// </summary>
526
        void _dataTablesInit()
527
        {
528
            dtMotors.Columns.Add("#");
529
            if (Thread.CurrentThread.CurrentUICulture.Name == "de-DE")
530
                dtMotors.Columns.Add("Strom");
531
            else
532
                dtMotors.Columns.Add("Current");
533
            dtMotors.Columns.Add("Temp");
534
            dgvMotors1.DataContext = dtMotors.DefaultView;
535
            _initDTMotors();
536
 
537
            Setter setter = new Setter(ContentControl.PaddingProperty, new Thickness(5, 0, 5, 0));
538
            Style style = new Style(typeof(System.Windows.Controls.Primitives.DataGridColumnHeader));
539
            style.Setters.Add(setter);
540
            setter = new Setter(ContentControl.BackgroundProperty, new SolidColorBrush(Colors.Transparent));
541
            style.Setters.Add(setter);
542
            setter = new Setter(ContentControl.ForegroundProperty, new SolidColorBrush(Colors.White));
543
            style.Setters.Add(setter);
544
 
545
            dtWaypoints.Columns.Add("Index", typeof(int));
546
            dtWaypoints.Columns.Add("Type", typeof(int));
547
            dtWaypoints.Columns.Add("Name", typeof(string));
548
            dtWaypoints.Columns.Add("Latitude", typeof(double));
549
            dtWaypoints.Columns.Add("Longitude", typeof(double));
550
            dtWaypoints.Columns.Add("Altitude", typeof(string));
551
            dtWaypoints.Columns.Add("Heading", typeof(string));
552
            dtWaypoints.Columns.Add("Speed", typeof(string));
553
            dtWaypoints.Columns.Add("ClimbRate", typeof(string));
554
            dtWaypoints.Columns.Add("Radius", typeof(string));
555
            dtWaypoints.Columns.Add("HoldTime", typeof(string));
556
            dtWaypoints.Columns.Add("AutoTrigger", typeof(string));
557
            dtWaypoints.Columns.Add("CamAngle", typeof(string));
558
            dtWaypoints.Columns.Add("Event", typeof(string));
559
            dtWaypoints.Columns.Add("Out1Timer", typeof(string));
560
            dtWaypoints.Columns.Add("Status", typeof(string));
561
            dtWaypoints.PrimaryKey = new DataColumn[] { dtWaypoints.Columns["Index"] };
562
            dgvWP.ItemsSource = dtWaypoints.DefaultView;
563
            dgvWP.ColumnHeaderStyle = new Style();
564
            dgvWP.ColumnHeaderStyle = style;
565
 
566
            dtGPX.Columns.Add("Index", typeof(int));
567
            dtGPX.Columns.Add("Latitude", typeof(double));
568
            dtGPX.Columns.Add("Longitude", typeof(double));
569
            dtGPX.Columns.Add("Elevation", typeof(int));
570
            dtGPX.Columns.Add("Time", typeof(string));
571
            dtGPX.PrimaryKey = new DataColumn[] { dtGPX.Columns["Index"] };
572
            drGPX = dtGPX.NewRow();
573
 
574
        }
575
        /// <summary>
576
        /// initialize the datatable dtMotors for motor values
577
        /// DataGridView dgvMotors1 is bound to dtMotors1
578
        /// </summary>
579
        void _initDTMotors()
580
        {
581
            for (int i = 0; i < 12; i++)
582
            {
583
                if (dtMotors.Rows.Count < 12)
584
                    dtMotors.Rows.Add((i + 1).ToString(), "NA", "NA");
585
                else
586
                {
587
                    dtMotors.Rows[i].SetField(1, "NA");
588
                    dtMotors.Rows[i].SetField(2, "NA");
589
                }
590
            }
591
        }
592
 
593
        #endregion init
594
 
595
        #region events
596
        private void serialPortCtrl_PortOpened()
597
        {
598
            Dispatcher.Invoke(() => imageWiFi.Source = new BitmapImage(new Uri("Images/WiFi_G.png", UriKind.Relative)));
599
            _getVersion();
600
            Thread.Sleep(100);
601
            _getLic();
602
            //_OSDMenue(0);
603
            //Thread.Sleep(200);
604
            //_sendSerialData();
605
            _readCont(true);
606
        }
607
        private void serialPortCtrl_PortClosed()
608
        {
609
            Dispatcher.Invoke(() => imageWiFi.Source = new BitmapImage(new Uri("Images/WiFi_W.png", UriKind.Relative)));
610
            _readCont(false);
611
        }
612
        bool _bToggle = false;
613
        void timerEvent(object sender, EventArgs e)
614
        {
615
            if (bReadContinously)
616
            {
617
                if (_debugDataAutorefresh) { _readDebugData(true); Thread.Sleep(10); }
618
 
619
                if (_blctrlDataAutorefresh) { _readBLCtrl(true); Thread.Sleep(10); }
620
 
621
                if (_navCtrlDataAutorefresh && _iCtrlAct == 2) { _readNavData(true); Thread.Sleep(10); }
622
                check_HWError = true;
623
                _getVersion();
624
                Thread.Sleep(10);
625
                if (_OSDAutorefresh)
626
                {
627
                    if (iOSDMax == 0 | cbOSD.Items.Count != iOSDMax)
628
                        _initOSDCB();
629
                    _OSDMenueAutoRefresh();
630
                }
631
                if (_iLifeCounter > 0)
632
                {
633
                    Dispatcher.Invoke(() => imageConn.Source = new BitmapImage(new Uri("Images/Data_G.png", UriKind.Relative)));
634
                    //  Dispatcher.Invoke((Action)(() => rctConnection.Fill = Brushes.LightGreen));
635
                    _iLifeCounter = 0;
636
                    _bConnErr = false;
637
                    if (_bAirborne && _bGPXLog)
638
                    {
639
                        drGPX[0] = dtGPX.Rows.Count;
640
                        dtGPX.Rows.Add(new object[] { drGPX[0], drGPX[1], drGPX[2], drGPX[3], drGPX[4] });
641
                    }
642
                    Dispatcher.Invoke((Action)(() => tbSideBarGPXLog.Background = (_bAirborne && _bGPXLog && _bToggle) ? new SolidColorBrush(Colors.LightSeaGreen) : new SolidColorBrush(Colors.Transparent)));
643
                    Dispatcher.Invoke((Action)(() => tbSideBarGPXLog.Foreground = (_bAirborne && _bGPXLog) ? new SolidColorBrush(Colors.White) : new SolidColorBrush(Color.FromArgb(255, 211, 210, 210))));
644
                    Dispatcher.Invoke((Action)(() => tbSideBarGPXLog.BorderBrush = (_bAirborne && _bGPXLog) ? new SolidColorBrush(Colors.White) : new SolidColorBrush(Color.FromArgb(255, 211, 210, 210))));
645
                    _bToggle = !_bToggle;
646
                }
647
                else
648
                {
649
                    if (!_bConnErr)
650
                    {
651
                        Log(LogMsgType.Error, "No communication to NC/FC!");
652
                        Dispatcher.Invoke(() => imageConn.Source = new BitmapImage(new Uri("Images/Data_R.png", UriKind.Relative)));
653
                        // Dispatcher.Invoke((Action)(() => rctConnection.Fill = Brushes.Red));
654
                        _bConnErr = true;
655
                    }
656
                }
657
            }
658
        }
659
        private void camTimer_Tick(object sender, EventArgs e)
660
        {
661
            if (_camImageSource != null && _frameSource != null && _camImage.Visibility == Visibility.Visible)
662
                _camImage.Source = _camImageSource;
663
            camTimer.IsEnabled = false;
664
        }
665
 
666
        #region menues
667
        private void labelData_MouseDown(object sender, MouseButtonEventArgs e)
668
        {
669
            GridData.Visibility = GridData.Visibility == Visibility.Collapsed ? Visibility.Visible : Visibility.Collapsed;
670
            GridSettings.Visibility = GridWP.Visibility = Visibility.Collapsed;
671
        }
672
        private void labelMotorData_MouseDown(object sender, MouseButtonEventArgs e)
673
        {
674
            GridMotors.Visibility = GridMotors.Visibility == Visibility.Hidden ? Visibility.Visible : Visibility.Hidden;
675
            if (GridMotors.IsVisible)
676
                _setMotorGridSize();
677
        }
678
        private void labelSettings_MouseDown(object sender, MouseButtonEventArgs e)
679
        {
680
            GridData.Visibility = GridWP.Visibility = Visibility.Collapsed;
681
            GridSettings.Visibility = GridSettings.Visibility == Visibility.Collapsed ? Visibility.Visible : Visibility.Collapsed;
682
        }
683
        private void labelLog_MouseDown(object sender, MouseButtonEventArgs e)
684
        {
685
            GridLog.Visibility = GridLog.Visibility == Visibility.Collapsed ? Visibility.Visible : Visibility.Collapsed;
686
        }
687
        private void labelOSD_MouseDown(object sender, MouseButtonEventArgs e)
688
        {
689
            GridOSD.Visibility = GridOSD.Visibility == Visibility.Hidden ? Visibility.Visible : Visibility.Hidden;
690
        }
691
        private void labelWaypoints_MouseDown(object sender, MouseButtonEventArgs e)
692
        {
693
            GridData.Visibility = GridSettings.Visibility = Visibility.Collapsed;
694
            GridWP.Visibility = GridWP.Visibility == Visibility.Collapsed ? Visibility.Visible : Visibility.Collapsed;
695
        }
696
        private void labelWPEdit_MouseDown(object sender, MouseButtonEventArgs e)
697
        {
698
            GridWPEdit.Visibility = GridWPEdit.Visibility == Visibility.Collapsed ? Visibility.Visible : Visibility.Collapsed;
699
        }
700
        private void labelCamera_MouseDown(object sender, MouseButtonEventArgs e)
701
        {
702
            GridCam.Visibility = GridCam.Visibility == Visibility.Collapsed ? Visibility.Visible : Visibility.Collapsed;
703
        }
704
        #endregion menues
705
 
706
        private void btnGetWP_Click(object sender, RoutedEventArgs e)
707
        {
708
            Thread t = new Thread(new ThreadStart(_getWP));
709
            t.Start();
710
        }
711
        private void btnSendWPList_Click(object sender, RoutedEventArgs e)
712
        {
713
            Thread t = new Thread(new ThreadStart(_sendWPList));
714
            t.Start();
715
        }
716
        private void btnConnectToCopter_Click(object sender, RoutedEventArgs e)
717
        {
718
            if (!serialPortCtrl.Port.IsOpen)
719
                serialPortCtrl.Connect(true);
720
            else
721
                _readCont(!bReadContinously);
722
        }
723
        private void btnSetHP_Click(object sender, RoutedEventArgs e)
724
        {
725
            _setHomePos();
726
        }
727
        private void btnClearHP_Click(object sender, RoutedEventArgs e)
728
        {
729
            _clearHomePos();
730
        }
731
        private void btnGotoHP_Click(object sender, RoutedEventArgs e)
732
        {
733
            if (home != null && MainMap.Markers.Contains(home))
734
                MainMap.Position = home.Position;
735
        }
736
        private void checkBoxAutoSetHP_Click(object sender, RoutedEventArgs e)
737
        {
738
            _bAutoHome = (bool)checkBoxAutoSetHP.IsChecked;
739
        }
740
        private void chkBoxSaveNormalState_Click(object sender, RoutedEventArgs e)
741
        {
742
            _bSaveWinStateNormal = (bool)chkBoxSaveNormalState.IsChecked;
743
        }
744
        private void chkBoxSaveFullScreenState_Click(object sender, RoutedEventArgs e)
745
        {
746
            _bSaveWinStateFull = (bool)chkBoxSaveFullScreenState.IsChecked;
747
        }
748
 
749
        #region thresholds
750
        private void sliderThresholdVoltageWarn_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
751
        {
752
            if (!_init)
753
            {
754
                _dThresholdVoltageWarn = sliderThresholdVoltageWarn.Value;
755
                _dThresholdVoltageCrit = sliderThresholdVoltageCrit.Value;
756
            }
757
        }
758
        private void sliderThresholdVoltageCrit_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
759
        {
760
            if (!_init)
761
                _dThresholdVoltageCrit = sliderThresholdVoltageCrit.Value;
762
        }
763
        private void checkBoxThresholdVoltageVoice_Click(object sender, RoutedEventArgs e)
764
        {
765
            _bVoiceVoltPlay = (bool)checkBoxThresholdVoltageVoice.IsChecked;
766
        }
767
 
768
        private void sliderThresholdDistanceWarn_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
769
        {
770
            if (!_init)
771
                _dThresholdDistanceWarn = sliderThresholdDistanceWarn.Value;
772
        }
773
        private void sliderThresholdBLCtrlTempWarn_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
774
        {
775
            if (!_init)
776
                _iThresholdBLCTRLTempWarn = (int)sliderThresholdBLCtrlTempWarn.Value;
777
        }
778
        private void checkBoxThresholdDistanceVoice_Click(object sender, RoutedEventArgs e)
779
        {
780
            _bVoiceDistancePlay = (bool)checkBoxThresholdDistanceVoice.IsChecked;
781
        }
782
 
783
        private void checkBoxSatfixLost_Click(object sender, RoutedEventArgs e)
784
        {
785
            _bVoiceSatFixPlay = (bool)checkBoxSatfixLost.IsChecked;
786
        }
787
        private void checkBoxMagneticField_Click(object sender, RoutedEventArgs e)
788
        {
789
            _bVoiceMagneticFieldPlay = (bool)checkBoxMagneticField.IsChecked;
790
        }
791
        private void checkBoxRClevel_Click(object sender, RoutedEventArgs e)
792
        {
793
            _bVoiceRCLevelPlay = (bool)checkBoxRClevel.IsChecked;
794
        }
795
        private void checkBoxBLCtrlTempVoice_Click(object sender, RoutedEventArgs e)
796
        {
797
            _bVoiceBLCTRLTempPlay = (bool)checkBoxBLCtrlTempVoice.IsChecked;
798
        }
799
        private void comboBoxVoiceLanguage_DropDownClosed(object sender, EventArgs e)
800
        {
801
            if (comboBoxVoiceLanguage.SelectedIndex > -1)
802
            {
803
                _iVoiceIndex = comboBoxVoiceLanguage.SelectedIndex;
804
            }
805
        }
806
        #endregion thresholds
807
 
808
        private void buttonSwitchNC_Click(object sender, RoutedEventArgs e)
809
        {
810
            _switchToNC();
811
        }
812
 
813
        private void Window_Loaded(object sender, RoutedEventArgs e)
814
        {
815
            stbVoltageCritAnim = TryFindResource("VoltageCritAnim") as Storyboard;
816
            stbSatFixLostAnim = TryFindResource("SatFixLostAnim") as Storyboard;
817
            stbMagneticFieldAnim = TryFindResource("MagneticFieldCritAnim") as Storyboard;
818
            stbDistanceWarnAnim = TryFindResource("DistanceCritAnim") as Storyboard;
819
            stbRCLevelAnim = TryFindResource("RCCritAnim") as Storyboard;
820
            stbCamActiveAnim = TryFindResource("CamActiveAnim") as Storyboard;
821
            stbBLCTRLTempAnim = TryFindResource("BLCtrlCritAnim") as Storyboard;
822
             _setMotorGridSize();
823
            // Refresh the list of available cameras
824
            comboBoxCameras.Items.Clear();
825
 
826
            foreach (Camera cam in CameraService.AvailableCameras)
827
                comboBoxCameras.Items.Add(cam);
828
 
829
            if (comboBoxCameras.Items.Count > 0)
830
                comboBoxCameras.SelectedIndex = 0;
831
        }
832
        private void Window_Closing(object sender, CancelEventArgs e)
833
        {
834
            _writeIni();
835
            if (_bGPXLog && dtGPX.Rows.Count > 0)
836
                _saveGPXLog();
837
            thrashOldCamera();
838
        }
839
        private void Window_Closed(object sender, EventArgs e)
840
        {
841
            Application.Current.Shutdown();
842
        }
843
 
844
        #region contextmenue add point
845
        Point pWPAdd;
846
        private void GridGMapControl_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
847
        {
848
            if(e.ClickCount == 2)
849
            {
850
                double x = 0, y = 0;
851
                var titleHeight = SystemParameters.WindowCaptionHeight + SystemParameters.ResizeFrameHorizontalBorderHeight;
852
 
853
                pWPAdd = new Point(e.GetPosition(this).X, e.GetPosition(this).Y);
854
                if (pWPAdd.X + canvasAddPoint.Width > Width)
855
                    x = pWPAdd.X - canvasAddPoint.Width;
856
                else
857
                    x = pWPAdd.X;
858
                if (pWPAdd.Y + canvasAddPoint.Height > Height - titleHeight)
859
                    y = pWPAdd.Y - canvasAddPoint.Height;
860
                else
861
                    y = pWPAdd.Y;
862
 
863
                canvasAddPoint.Margin = new Thickness(x, y, canvasAddPoint.Margin.Left, canvasAddPoint.Margin.Bottom);
864
                canvasAddPoint.Visibility = Visibility.Visible;
865
            }
866
 
867
        }
868
        private void canvasAddPoint_LostFocus(object sender, RoutedEventArgs e)
869
        {
870
            canvasAddPoint.Visibility = Visibility.Collapsed;
871
        }
872
        private void canvasAddPoint_MouseLeave(object sender, MouseEventArgs e)
873
        {
874
            canvasAddPoint.Visibility = Visibility.Collapsed;
875
        }
876
        private void btnCmAddWP_Click(object sender, RoutedEventArgs e)
877
        {
878
            if (pWPAdd != null)
879
            {
880
                PointLatLng p = MainMap.FromLocalToLatLng((int)pWPAdd.X, (int)pWPAdd.Y);
881
                _addWP(p,0);
882
                canvasAddPoint.Visibility = Visibility.Collapsed;
883
            }
884
        }
885
        private void btnCmAddPOI_Click(object sender, RoutedEventArgs e)
886
        {
887
            if (pWPAdd != null)
888
            {
889
                PointLatLng p = MainMap.FromLocalToLatLng((int)pWPAdd.X, (int)pWPAdd.Y);
890
                _addWP(p,1);
891
                canvasAddPoint.Visibility = Visibility.Collapsed;
892
            }
893
        }
894
        private void btnCmAddFailsave_Click(object sender, RoutedEventArgs e)
895
        {
896
            if (pWPAdd != null)
897
            {
898
                PointLatLng p = MainMap.FromLocalToLatLng((int)pWPAdd.X, (int)pWPAdd.Y);
899
                _addWP(p,2);
900
                canvasAddPoint.Visibility = Visibility.Collapsed;
901
            }
902
        }
903
        private void btnCmAddLanding_Click(object sender, RoutedEventArgs e)
904
        {
905
            if (pWPAdd != null)
906
            {
907
                PointLatLng p = MainMap.FromLocalToLatLng((int)pWPAdd.X, (int)pWPAdd.Y);
908
                _addWP(p,3);
909
                canvasAddPoint.Visibility = Visibility.Collapsed;
910
            }
911
        }
912
        #endregion contextmenue add point
913
 
914
        #endregion events
915
 
916
        #region cam
917
        private CameraFrameSource _frameSource;
918
 
919
        private void btnCamStart_Click(object sender, RoutedEventArgs e)
920
        {
921
            if (_frameSource != null && _frameSource.Camera == comboBoxCameras.SelectedItem)
922
                return;
923
 
924
            thrashOldCamera();
925
            startCapturing();
926
        }
927
        private void btnCamStop_Click(object sender, RoutedEventArgs e)
928
        {
929
            thrashOldCamera();
930
            _camImage.Visibility = Visibility.Collapsed;
931
            if (stbCamActiveAnim != null && _bCamAnim)
932
            {
933
                Dispatcher.Invoke(() => stbCamActiveAnim.Stop());
934
                _bCamAnim = false;
935
                rectCamStart.Visibility = Visibility.Collapsed;
936
            }
937
        }
938
        private void btnCamSettings_Click(object sender, RoutedEventArgs e)
939
        {
940
            if (_frameSource != null && _frameSource.Camera != null)
941
            {
942
                _frameSource.Camera.ShowPropertiesDialog();
943
            }
944
        }
945
        private void btnCamListRefresh_Click(object sender, RoutedEventArgs e)
946
        {
947
            comboBoxCameras.Items.Clear();
948
            CameraService.ClearCameraList();
949
            foreach (Camera cam in CameraService.AvailableCameras)
950
                comboBoxCameras.Items.Add(cam);
951
 
952
            if (comboBoxCameras.Items.Count > 0)
953
                comboBoxCameras.SelectedIndex = 0;
954
            //if (_frameSource != null && comboBoxCameras.Items.Count > 0 && comboBoxCameras.Items.Contains(_frameSource.Camera.ToString()))
955
            //    comboBoxCameras.SelectedItem = (Camera)_frameSource.Camera;
956
 
957
        }
958
 
959
        private void lblCam_Click(object sender, RoutedEventArgs e)
960
        {
961
            if (_frameSource != null && _frameSource.Camera != null)
962
            {
963
                _camImage.Visibility = _camImage.Visibility == Visibility.Collapsed ? Visibility.Visible : Visibility.Collapsed;
964
            }
965
        }
966
 
967
        void _setCamPicStretch(Stretch type)
968
        {
969
            if(_camImage.Stretch == Stretch.None)
970
                _camImageMargin = _camImage.Margin;
971
            if(type != Stretch.None)
972
                _camImage.Margin = new Thickness(0);
973
            _camImage.Stretch = type;
974
        }
975
        private void btnCamPicStretchNone_Click(object sender, RoutedEventArgs e)
976
        {
977
            _setCamPicStretch(Stretch.None);
978
            _camImage.Margin = _camImageMargin;
979
        }
980
        private void btnCamResetZoom_Click(object sender, RoutedEventArgs e)
981
        {
982
            _setCamPicStretch(Stretch.None);
983
            _camImage.Margin = _camImageMargin = new Thickness(0);
984
            SliderCamZoom.Value = 1;
985
        }
986
        private void btnCamPicStretchFill_Click(object sender, RoutedEventArgs e)
987
        {
988
            _setCamPicStretch(Stretch.Fill);
989
        }
990
        private void btnCamPicStretchUniform_Click(object sender, RoutedEventArgs e)
991
        {
992
            _setCamPicStretch(Stretch.Uniform);
993
        }
994
        private void btnCamPicStretchUFill_Click(object sender, RoutedEventArgs e)
995
        {
996
            _setCamPicStretch(Stretch.UniformToFill);
997
        }
998
        private Camera CurrentCamera
999
        {
1000
            get
1001
            {
1002
                return comboBoxCameras.SelectedItem as Camera;
1003
            }
1004
        }
1005
        private void startCapturing()
1006
        {
1007
            try
1008
            {
1009
                Camera c = (Camera)comboBoxCameras.SelectedItem;
1010
                setFrameSource(new CameraFrameSource(c));
1011
                _frameSource.Camera.CaptureWidth = 640;
1012
                _frameSource.Camera.CaptureHeight = 480;
1013
                _frameSource.Camera.Fps = 25;
1014
                _frameSource.NewFrame += OnImageCaptured;
1015
                _frameSource.StartFrameCapture();
1016
                _camImage.Visibility = Visibility.Visible;
1017
                _camImage.Margin = _camImageMargin;
1018
                if (stbCamActiveAnim != null && !_bCamAnim)
1019
                {
1020
                    Dispatcher.Invoke(() => stbCamActiveAnim.Begin());
1021
                    _bCamAnim = true;
1022
                    rectCamStart.Visibility = Visibility.Visible;
1023
                }
1024
            }
1025
            catch (Exception ex)
1026
            {
1027
                comboBoxCameras.Text = "Select A Camera";
1028
                MessageBox.Show(ex.Message);
1029
            }
1030
        }
1031
 
1032
        public void OnImageCaptured(Touchless.Vision.Contracts.IFrameSource frameSource, Touchless.Vision.Contracts.Frame frame, double fps)
1033
        {
1034
            _camImageSource = BitmapConversion.ToWpfBitmap(frame.Image);
1035
            camTimer.IsEnabled = true;
1036
        }
1037
        private void setFrameSource(CameraFrameSource cameraFrameSource)
1038
        {
1039
            if (_frameSource == cameraFrameSource)
1040
                return;
1041
 
1042
            _frameSource = cameraFrameSource;
1043
        }
1044
        private void thrashOldCamera()
1045
        {
1046
 
1047
            // Trash the old camera
1048
            if (_frameSource != null)
1049
            {
1050
                _frameSource.NewFrame -= OnImageCaptured;
1051
                Dispatcher.Invoke(() => {
1052
                    _camImage.Source = null;
1053
                    _camImage.InvalidateVisual();
1054
                });
1055
                using (Dispatcher.DisableProcessing())
1056
                {
1057
                    _frameSource.StopFrameCapture();
1058
                    setFrameSource(null);
1059
                    Thread.Sleep(10);
1060
                }
1061
            }
1062
        }
1063
 
1064
        Point pOffset,mouse_pos;
1065
        Thickness _camImageMargin = new Thickness(0);
1066
        private void _CamImage_MouseMove(object sender, System.Windows.Input.MouseEventArgs e)
1067
        {
1068
            if (e.LeftButton == System.Windows.Input.MouseButtonState.Pressed && _camImage.Stretch == Stretch.None)
1069
            {
1070
                mouse_pos = Mouse.GetPosition(this);
1071
                mouse_pos.Offset(-pOffset.X, -pOffset.Y);
1072
                pOffset = Mouse.GetPosition(this);
1073
                _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);
1074
            }
1075
        }
1076
        private void _CamImage_MouseDown(object sender, MouseButtonEventArgs e)
1077
        {
1078
            if (e.LeftButton == System.Windows.Input.MouseButtonState.Pressed && _camImage.Stretch == Stretch.None)
1079
                pOffset = Mouse.GetPosition(this);
1080
        }
1081
 
1082
        #endregion cam
1083
 
1084
        #region GMap
1085
        string _mapPosition = "Landshut";
1086
        void _setupMap()
1087
        {
1088
            MainMap.Manager.Mode = AccessMode.ServerAndCache;
1089
            MainMap.MapProvider = GMapProviders.BingHybridMap;
1090
            textBoxGeo.Text = _mapPosition;
1091
            MainMap.SetPositionByKeywords(_mapPosition);
1092
            textBoxLat_currentPos.Text = MainMap.Position.Lat.ToString() + "°";
1093
            textBoxLng_currentPos.Text = MainMap.Position.Lng.ToString() + "°";
1094
            MainMap.MinZoom = 0;
1095
            MainMap.MaxZoom = 24;
1096
            MainMap.Zoom = 16;
1097
            MainMap.ShowCenter = true;
1098
            MainMap.ShowTileGridLines = false;
1099
            sliderMapZoom.Value = 16;
1100
            comboBoxMapType.ItemsSource = providerList;
1101
            comboBoxMapType.DisplayMemberPath = "Name";
1102
            comboBoxMapType.SelectedItem = MainMap.MapProvider;
1103
 
1104
            // acccess mode
1105
            comboBoxMode.ItemsSource = Enum.GetValues(typeof(AccessMode));
1106
            comboBoxMode.SelectedItem = MainMap.Manager.Mode;
1107
 
1108
        }
1109
 
1110
        /// <summary>
1111
        /// selection of relevant map providers --> if You need more, You can change the line:
1112
        ///     comboBoxMapType.ItemsSource = providerList; 
1113
        /// to:
1114
        ///     comboBoxMapType.ItemsSource = GMapProviders.List;
1115
        /// in _setupMap()
1116
        /// or add items here:
1117
        /// </summary>
1118
        List<GMap.NET.MapProviders.GMapProvider> providerList = new List<GMap.NET.MapProviders.GMapProvider>
1119
        { GMap.NET.MapProviders.GMapProviders.OpenCycleMap, GMap.NET.MapProviders.GMapProviders.OpenCycleLandscapeMap, GMap.NET.MapProviders.GMapProviders.OpenCycleTransportMap,
1120
        GMap.NET.MapProviders.GMapProviders.BingMap,GMap.NET.MapProviders.GMapProviders.BingSatelliteMap,GMap.NET.MapProviders.GMapProviders.BingHybridMap,
1121
        GMap.NET.MapProviders.GMapProviders.GoogleMap,GMap.NET.MapProviders.GMapProviders.GoogleSatelliteMap,GMap.NET.MapProviders.GMapProviders.GoogleHybridMap,GMap.NET.MapProviders.GMapProviders.GoogleTerrainMap,
1122
        GMap.NET.MapProviders.GMapProviders.OviMap,GMap.NET.MapProviders.GMapProviders.OviSatelliteMap,GMap.NET.MapProviders.GMapProviders.OviHybridMap,GMap.NET.MapProviders.GMapProviders.OviTerrainMap};
1123
 
1124
        private void MainMap_Loaded(object sender, RoutedEventArgs e)
1125
        {
1126
            MainMap.Manager.Mode = AccessMode.ServerAndCache;
1127
            copter = new GMapMarker(MainMap.Position);
1128
 
1129
            copter.Shape = new CustomMarkerCopter(this, copter, MainMap.Position.Lat.ToString("0.#######°") + System.Environment.NewLine + MainMap.Position.Lng.ToString("0.#######°"), "red");
1130
            if (comboBoxCopterColor.SelectionBoxItem != null)
1131
            {
1132
                string s = _colors[comboBoxCopterColor.SelectedIndex];
1133
                ((CustomMarkerCopter)(copter.Shape)).setCopterColor(s);
1134
            }
1135
            Dispatcher.Invoke(() => {
1136
                if (comboBoxCopterHeadingColor.SelectionBoxItem != null)
1137
                {
1138
                    string s = _colors[comboBoxCopterHeadingColor.SelectedIndex];
1139
                    ((CustomMarkerCopter)(copter.Shape)).setHeadingColor(s);
1140
                }
1141
            });
1142
            copter.Offset = new System.Windows.Point(-26, -26);
1143
            copter.ZIndex = int.MaxValue;
1144
            MainMap.Markers.Add(copter);
1145
            copter.Position = MainMap.Position;
1146
            _setMapItemsSize("Copter", SliderCopterZoom.Value);
1147
        }
1148
        void _setHomePos()
1149
        {
1150
            pHome = MainMap.Position;
1151
            if (!MainMap.Markers.Contains(home))
1152
            {
1153
                home = new GMapMarker(MainMap.Position);
1154
                home.Shape = new CustomMarkerHome(this, home, MainMap.Position.Lat.ToString("0.#######°") + System.Environment.NewLine + MainMap.Position.Lng.ToString("0.#######°"));
1155
                home.Offset = new System.Windows.Point(-16.5, -16.5);
1156
                // home.ZIndex = int.MaxValue;
1157
                MainMap.Markers.Add(home);
1158
            }
1159
            home.Position = MainMap.Position;
1160
            ((CustomMarkerHome)(home.Shape)).setText(MainMap.Position.Lat.ToString("0.#######°") + System.Environment.NewLine + MainMap.Position.Lng.ToString("0.#######°"));
1161
            _setMapItemsSize("Home", SliderHPZoom.Value);
1162
            if (checkBoxShowWPMaxRange.IsChecked == true)
1163
            {
1164
                if (cWPBound != null && cWPBound.Tag != null)
1165
                    MainMap.Markers.Remove(cWPBound.Tag as GMapMarker);
1166
 
1167
                createCircle(home.Position, dWPMaxRange);
1168
                Dispatcher.Invoke(() =>
1169
                {
1170
                    if (comboBoxWPMaxRangeColor.SelectionBoxItem != null)
1171
                    {
1172
                        string s = _colors[comboBoxWPMaxRangeColor.SelectedIndex];
1173
                        cWPBound.setColor(s);
1174
                    }
1175
                });
1176
            }
1177
 
1178
        }
1179
        void _setActiveWP(int iIndex)
1180
        {
1181
            if (iIndex < wpList.Count)
1182
            {
1183
                if (wpActiveMarker == null || !MainMap.Markers.Contains(wpActiveMarker))
1184
                {
1185
                    Dispatcher.Invoke(() =>
1186
                    {
1187
                        wpActiveMarker = new GMapMarker(wpList[iIndex]);
1188
                        wpActiveMarker.Shape = new CustomMarkerWPActive(this, wpActiveMarker, "wpActive", 0);
1189
                        wpActiveMarker.Offset = new Point(-17.5, -17.5);
1190
                        MainMap.Markers.Add(wpActiveMarker);
1191
                    });
1192
                }
1193
                else
1194
                    Dispatcher.Invoke(() => wpActiveMarker.Position = wpList[iIndex]);
1195
            }
1196
 
1197
            Dispatcher.Invoke(() => tbWPStatusHeight.Text = dtWaypoints.Rows[iIndex][5].ToString() + " m");
1198
        }
1199
        void _clearHomePos()
1200
        {
1201
            MainMap.Markers.Remove(home);
1202
            if (cWPBound != null && cWPBound.Tag != null)
1203
                MainMap.Markers.Remove(cWPBound.Tag as GMapMarker);
1204
        }
1205
        void _clearMapMarkers(Type markerType)
1206
        {
1207
            for (int k = 0; k < MainMap.Markers.Count;)
1208
            {
1209
                GMapMarker p = MainMap.Markers[k];
1210
                if (p.GetType() == markerType | (p.Shape != null && p.Shape.GetType() == markerType))
1211
                    MainMap.Markers.Remove(p);
1212
                else
1213
                    k++;
1214
            }
1215
            _WPisMouseCaptured = false;
1216
        }
1217
 
1218
        GMapMarker _findWPMarker(string name)
1219
        {
1220
            for (int k = 0; k < MainMap.Markers.Count;)
1221
            {
1222
                GMapMarker p = MainMap.Markers[k];
1223
                if (p.GetType() == typeof(CustomMarkerWP) | (p.Shape != null && p.Shape.GetType() == typeof(CustomMarkerWP)))
1224
                    if (((CustomMarkerWP)p.Shape).WPText == name)
1225
                        return p;
1226
                    else
1227
                        k++;
1228
                else
1229
                    k++;
1230
            }
1231
            return null;
1232
        }
1233
        void _clearWPMarker(string name)
1234
        {
1235
            GMapMarker p = _findWPMarker(name);
1236
            if (p != null)
1237
                MainMap.Markers.Remove(p);
1238
        }
1239
        void _renameWPMarker(string s1, string s2)
1240
        {
1241
            GMapMarker p = _findWPMarker(s1);
1242
            if (p != null)
1243
                ((CustomMarkerWP)p.Shape).WPText = s2;
1244
        }
1245
        void _WPMarkerSetType(string text, int type)
1246
        {
1247
            GMapMarker p = _findWPMarker(text);
1248
            if (p != null)
1249
                ((CustomMarkerWP)p.Shape).WPType = type;
1250
        }
1251
        void _repositionWPMarker(PointLatLng point, string name)
1252
        {
1253
            GMapMarker p = _findWPMarker(name);
1254
            if (p != null)
1255
                p.Position = point;
1256
        }
1257
 
1258
        void createCircle(PointLatLng center, double distance)
1259
        {
1260
 
1261
            GMapMarker it = new GMapMarker(center);
1262
            it.ZIndex = -1;
1263
 
1264
            cWPBound.Center = center;
1265
            cWPBound.Bound = GMap.NET.PureProjection.GetPointFromDistance(center, distance);
1266
            cWPBound.Tag = it;
1267
            cWPBound.IsHitTestVisible = false;
1268
            UpdateCircle(cWPBound);
1269
            it.Shape = cWPBound;
1270
            MainMap.Markers.Add(it);
1271
        }
1272
        // calculates circle radius
1273
        void UpdateCircle(Circle c)
1274
        {
1275
            var pxCenter = MainMap.FromLatLngToLocal(c.Center);
1276
            var pxBounds = MainMap.FromLatLngToLocal(c.Bound);
1277
 
1278
            double a = (double)(pxBounds.X - pxCenter.X);
1279
            double b = (double)(pxBounds.Y - pxCenter.Y);
1280
            var pxCircleRadius = Math.Sqrt(a * a + b * b);
1281
 
1282
            c.Width = c.Height = pxCircleRadius * 2;
1283
            //c.Width = 55 + pxCircleRadius * 2;
1284
            //c.Height = 55 + pxCircleRadius * 2;
1285
            (c.Tag as GMapMarker).Offset = new System.Windows.Point(-c.Width / 2, -c.Height / 2);
1286
        }
1287
 
1288
        // access mode
1289
        private void comboBoxMode_DropDownClosed(object sender, EventArgs e)
1290
        {
1291
            MainMap.Manager.Mode = (AccessMode)comboBoxMode.SelectedItem;
1292
            MainMap.ReloadMap();
1293
        }
1294
        // zoom up
1295
        private void czuZoomUp_Click(object sender, RoutedEventArgs e)
1296
        {
1297
            MainMap.Zoom = ((int)MainMap.Zoom) + 1;
1298
        }
1299
 
1300
        // zoom down
1301
        private void czuZoomDown_Click(object sender, RoutedEventArgs e)
1302
        {
1303
            MainMap.Zoom = ((int)(MainMap.Zoom + 0.99)) - 1;
1304
        }
1305
 
1306
        // prefetch
1307
        private void buttonPrefetch_Click(object sender, RoutedEventArgs e)
1308
        {
1309
            RectLatLng area = MainMap.SelectedArea;
1310
            if (!area.IsEmpty)
1311
            {
1312
                for (int i = (int)MainMap.Zoom; i <= MainMap.MaxZoom; i++)
1313
                {
1314
                    MessageBoxResult res = MessageBox.Show("Ready ripp at Zoom = " + i + " ?", "GMap.NET", MessageBoxButton.YesNoCancel);
1315
 
1316
                    if (res == MessageBoxResult.Yes)
1317
                    {
1318
                        TilePrefetcher obj = new TilePrefetcher();
1319
                        obj.Owner = this;
1320
                        obj.ShowCompleteMessage = true;
1321
                        obj.Start(area, i, MainMap.MapProvider, 100);
1322
                    }
1323
                    else if (res == MessageBoxResult.No)
1324
                    {
1325
                        continue;
1326
                    }
1327
                    else if (res == MessageBoxResult.Cancel)
1328
                    {
1329
                        break;
1330
                    }
1331
                }
1332
            }
1333
            else
1334
            {
1335
                MessageBox.Show("Select map area holding ALT", "GMap.NET", MessageBoxButton.OK, MessageBoxImage.Exclamation);
1336
            }
1337
        }
1338
 
1339
        // goto by geocoder
1340
        private void buttonGeoCoding_Click(object sender, RoutedEventArgs e)
1341
        {
1342
            _goto_byGeoCoder();
1343
        }
1344
        // goto by geocoder
1345
        private void textBoxGeo_KeyUp(object sender, System.Windows.Input.KeyEventArgs e)
1346
        {
1347
            if (e.Key == System.Windows.Input.Key.Enter)
1348
                _goto_byGeoCoder();
1349
        }
1350
        void _goto_byGeoCoder()
1351
        {
1352
            GeoCoderStatusCode status = MainMap.SetPositionByKeywords(textBoxGeo.Text);
1353
            _mapPosition = textBoxGeo.Text;
1354
            if (status != GeoCoderStatusCode.G_GEO_SUCCESS)
1355
            {
1356
                MessageBox.Show("Geocoder can't find: '" + textBoxGeo.Text + "', reason: " + status.ToString(), "GMap.NET", MessageBoxButton.OK, MessageBoxImage.Exclamation);
1357
            }
1358
        }
1359
        private void buttonGeoLoc_Click(object sender, RoutedEventArgs e)
1360
        {
1361
            try
1362
            {
1363
                double lat = double.Parse(textBoxLat.Text, System.Globalization.CultureInfo.InvariantCulture);
1364
                double lng = double.Parse(textBoxLng.Text, System.Globalization.CultureInfo.InvariantCulture);
1365
 
1366
                MainMap.Position = new PointLatLng(lat, lng);
1367
            }
1368
            catch (Exception ex)
1369
            {
1370
                MessageBox.Show("incorrect coordinate format: " + ex.Message);
1371
            }
1372
 
1373
        }
1374
 
1375
        private void ReloadMap_Click(object sender, RoutedEventArgs e)
1376
        {
1377
            MainMap.ReloadMap();
1378
        }
1379
 
1380
        private void MainMap_OnPositionChanged(PointLatLng point)
1381
        {
1382
            if (_bFollowCopter)
1383
                _setCopterData(MainMap.Position);
1384
        }
1385
 
1386
        private void MainMap_OnMapZoomChanged()
1387
        {
1388
            if (_bFollowCopter)
1389
                _setCopterData(MainMap.Position);
1390
            if ((int)sliderMapZoom.Value != MainMap.Zoom)
1391
                sliderMapZoom.Value = MainMap.Zoom;
1392
            if (cWPBound != null && cWPBound.Tag != null)
1393
                UpdateCircle(cWPBound);
1394
        }
1395
 
1396
        void _setCopterData(PointLatLng p)
1397
        {
1398
            Dispatcher.Invoke(() =>
1399
            {
1400
                copter.Position = p;
1401
                ((CustomMarkerCopter)(copter.Shape)).setText(p.Lat.ToString("0.#######°") + System.Environment.NewLine + p.Lng.ToString("0.#######°"));
1402
                textBoxLat_currentPos.Text = p.Lat.ToString() + "°";
1403
                textBoxLng_currentPos.Text = p.Lng.ToString() + "°";
1404
            });
1405
            if (home != null && MainMap.Markers.Contains(home))
1406
            {
1407
                Dispatcher.Invoke(() => ArtHor.rotateHome = GMapProviders.EmptyProvider.Projection.GetBearing(copter.Position, home.Position));
1408
                double d = GMapProviders.EmptyProvider.Projection.GetDistance(home.Position, copter.Position);
1409
                Dispatcher.Invoke(() => tbTopDistanceHP.Text = (d * 1000).ToString("0.0 m"));
1410
 
1411
                if (d * 1000 < _dThresholdDistanceWarn)
1412
                {
1413
                    _iDistanceJitter = 0; _bVoiceDistanceActive = false;
1414
                    if (stbDistanceWarnAnim != null && _bAnimDistanceActive)
1415
                    {
1416
                        Dispatcher.Invoke(() => stbDistanceWarnAnim.Stop());
1417
                        _bAnimDistanceActive = false;
1418
                    }
1419
                }
1420
                else
1421
                {
1422
                    if (_iDistanceJitter < 20)
1423
                    { _iDistanceJitter++; }
1424
                    if (_iDistanceJitter == 20)
1425
                    {
1426
                        if (stbDistanceWarnAnim != null && !_bAnimDistanceActive)
1427
                        {
1428
                            Dispatcher.Invoke(() => stbDistanceWarnAnim.Begin());
1429
                            _bAnimDistanceActive = true;
1430
                        }
1431
                        if (_bVoiceDistancePlay && !_bVoiceDistanceActive)
1432
                        {
1433
                            ThreadPool.QueueUserWorkItem(new WaitCallback(_mediaPlayer), "Voice\\" + _voiceLanguage[_iVoiceIndex] + "\\Distance.mp3");
1434
                            //Thread t = new Thread(()=>_mediaPlayer("Voice\\Distance.mp3"));
1435
                            //t.Start();
1436
                            _bVoiceDistanceActive = true;
1437
                        }
1438
                        _iDistanceJitter++;
1439
                    }
1440
                }
1441
            }
1442
        }
1443
 
1444
        void _setMapItemsSize(string item, double value)
1445
        {
1446
            ScaleTransform scaleTransform = new ScaleTransform();
1447
            scaleTransform.ScaleY = value;
1448
            scaleTransform.ScaleX = value;
1449
            TransformGroup transformGroup = new TransformGroup();
1450
            transformGroup.Children.Add(scaleTransform);
1451
 
1452
            switch (item)
1453
            {
1454
                case "Copter":
1455
                    if (copter != null && copter.Shape != null)
1456
                    {
1457
                        ((ScaleTransform)transformGroup.Children[0]).CenterX = 26;
1458
                        ((ScaleTransform)transformGroup.Children[0]).CenterY = 26;
1459
                        copter.Shape.RenderTransform = transformGroup;
1460
                    }
1461
                    break;
1462
                case "Home":
1463
                    if (home != null && MainMap.Markers.Contains(home))
1464
                    {
1465
                        ((ScaleTransform)transformGroup.Children[0]).CenterX = 16.5;
1466
                        ((ScaleTransform)transformGroup.Children[0]).CenterY = 16.5;
1467
                        home.Shape.RenderTransform = transformGroup;
1468
                        home.Shape.InvalidateVisual();
1469
                    }
1470
                    break;
1471
                case "WP":
1472
                    Dispatcher.Invoke(() =>
1473
                    {
1474
                        ((ScaleTransform)transformGroup.Children[0]).CenterX = 11.5;
1475
                        ((ScaleTransform)transformGroup.Children[0]).CenterY = 11.5;
1476
                        for (int k = 0; k < MainMap.Markers.Count;)
1477
                        {
1478
                            GMapMarker p = MainMap.Markers[k];
1479
                            if (p.Shape != null && (p.Shape.GetType() == typeof(CustomMarkerWP) || p.Shape.GetType() == typeof(CustomMarkerWPActive)))
1480
                            {
1481
                                ((CustomMarkerWP)(p.Shape)).RenderTransform = transformGroup;
1482
                            }
1483
                            k++;
1484
                        }
1485
                    });
1486
                    break;
1487
            }
1488
 
1489
        }
1490
 
1491
        private void checkBoxFollowCopter_Click(object sender, RoutedEventArgs e)
1492
        {
1493
            _bFollowCopter = (bool)checkBoxFollowCopter.IsChecked;
1494
        }
1495
 
1496
        private void sliderMapZoom_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
1497
        {
1498
            if (MainMap.Zoom != sliderMapZoom.Value)
1499
                MainMap.Zoom = (int)sliderMapZoom.Value;
1500
        }
1501
 
1502
        private void SliderCopterZoom_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
1503
        {
1504
            if (copter != null && copter.Shape != null)
1505
                _setMapItemsSize("Copter",SliderCopterZoom.Value);
1506
        }
1507
        private void SliderWPZoom_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
1508
        {
1509
            if (MainMap.Markers.Count > 2)
1510
                _setMapItemsSize("WP",SliderWPZoom.Value);
1511
        }
1512
        private void SliderHomeZoom_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
1513
        {
1514
            if (home != null && MainMap.Markers.Contains(home))
1515
                _setMapItemsSize("Home",SliderHPZoom.Value);
1516
        }
1517
 
1518
 
1519
 
1520
        #region Touch zooming hackattack ;) 
1521
        /// <summary>
1522
        /// inspired by http://www.codeproject.com/Articles/692286/WPF-and-multi-touch
1523
        /// </summary>
1524
        bool bFirstAccess = true;
1525
        double dDistance = 0;
1526
        int iZoom;
1527
        private void MainMap_StylusDown(object sender, StylusDownEventArgs e)
1528
        {
1529
            if (!_WPisMouseCaptured)
1530
            {
1531
                var id = e.StylusDevice.Id;
1532
                e.StylusDevice.Capture(MainMap);
1533
                if (iFirstStylusID == -1)
1534
                {
1535
                    iFirstStylusID = id;
1536
                }
1537
                else
1538
                {
1539
 
1540
                    MainMap.CanDragMap = false;
1541
                }
1542
            }
1543
        }
1544
        private void MainMap_StylusUp(object sender, StylusEventArgs e)
1545
        {
1546
            MainMap.ReleaseStylusCapture();
1547
            iFirstStylusID = -1;
1548
            bFirstAccess = true;
1549
            MainMap.CanDragMap = true;
1550
            iZoom = 0;
1551
        }
1552
        private void MainMap_StylusMove(object sender, StylusEventArgs e)
1553
        {
1554
            var id = e.StylusDevice.Id;
1555
            var tp = e.GetPosition(MainMap);
1556
 
1557
            // This is the first Stylus point; just record its position. 
1558
            if (id == iFirstStylusID)
1559
            {
1560
                pTouch1.X = tp.X;
1561
                pTouch1.Y = tp.Y;
1562
            }
1563
            else
1564
            if (iFirstStylusID > -1)
1565
            {
1566
                pTouch2.X = tp.X;
1567
                pTouch2.Y = tp.Y;
1568
                double distance = Point.Subtract(pTouch1, pTouch2).Length;
1569
                if (!bFirstAccess)
1570
                {
1571
                    if (distance > dDistance)
1572
                        iZoom++;
1573
                    else
1574
                        if (distance < dDistance)
1575
                        iZoom--;
1576
                }
1577
                if (iZoom > 30)
1578
                {
1579
                    iZoom = 0;
1580
                    Dispatcher.Invoke(() => sliderMapZoom.Value += 1);
1581
                }
1582
                if (iZoom < -30)
1583
                {
1584
                    iZoom = 0;
1585
                    Dispatcher.Invoke(() => sliderMapZoom.Value -= 1);
1586
                }
1587
                dDistance = distance;
1588
                bFirstAccess = false;
1589
            }
1590
        }
1591
        #endregion Touch zooming hackattack ;)
1592
 
1593
        #endregion GMap
1594
 
1595
        #region settings
1596
        private void cBoxTimingsDebug_DropDownClosed(object sender, EventArgs e)
1597
        {
1598
            if (!_bCBInit && cBoxTimingsDebug.SelectedIndex > -1)
1599
                debugInterval = (byte)(Convert.ToInt16(cBoxTimingsDebug.SelectedItem) / 10);
1600
        }
1601
        private void cBoxTimingsNav_DropDownClosed(object sender, EventArgs e)
1602
        {
1603
            if (!_bCBInit && cBoxTimingsNav.SelectedIndex > -1)
1604
                navctrlInterval = (byte)(Convert.ToInt16(cBoxTimingsNav.SelectedItem) / 10);
1605
        }
1606
        private void cBoxTimingsBl_DropDownClosed(object sender, EventArgs e)
1607
        {
1608
            if (!_bCBInit && cBoxTimingsBl.SelectedIndex > -1)
1609
                blctrlInterval = (byte)(Convert.ToInt16(cBoxTimingsBl.SelectedItem) / 10);
1610
        }
1611
        private void cBoxTimingsOSD_DropDownClosed(object sender, EventArgs e)
1612
        {
1613
            if (!_bCBInit && cBoxTimingsOSD.SelectedIndex > -1)
1614
                OSDInterval = (byte)(Convert.ToInt16(cBoxTimingsOSD.SelectedItem) / 10);
1615
        }
1616
        private void chkbAutoDbg_Click(object sender, RoutedEventArgs e)
1617
        {
1618
            if (!_init) _debugDataAutorefresh = (bool)chkbAutoDbg.IsChecked;
1619
        }
1620
        private void chkbAutoNav_Click(object sender, RoutedEventArgs e)
1621
        {
1622
            if (!_init) _navCtrlDataAutorefresh = (bool)chkbAutoNav.IsChecked;
1623
        }
1624
        private void chkbAutoBL_Click(object sender, RoutedEventArgs e)
1625
        {
1626
            if (!_init) _blctrlDataAutorefresh = (bool)chkbAutoBL.IsChecked;
1627
        }
1628
        private void chkbAutoOSD_Click(object sender, RoutedEventArgs e)
1629
        {
1630
            if (!_init) _OSDAutorefresh = (bool)chkbAutoOSD.IsChecked;
1631
        }
1632
 
1633
        private void cBoxLiPoCells_DropDownClosed(object sender, EventArgs e)
1634
        {
1635
            if (cBoxLiPoCells.SelectedIndex > -1)
1636
            {
1637
                _LipoCells = cBoxLiPoCells.SelectedIndex + 3;
1638
                _LipoMinMax();
1639
            }
1640
        }
1641
        private void chkbAutoLiPo_Click(object sender, RoutedEventArgs e)
1642
        {
1643
            _bLiPoAutoDetect = (bool)chkbAutoLiPoDetect.IsChecked;
1644
        }
1645
 
1646
        void _LipoMinMax()
1647
        {
1648
            _dLipoVMax = (double)(_LipoCells) * 4.22;
1649
            _dLipoVMin = (double)_LipoCells * 3;
1650
            pbTopVoltage.Maximum = _dLipoVMax;
1651
            pbTopVoltage.Minimum = _dLipoVMin;
1652
            sliderThresholdVoltageWarn.Maximum = _dLipoVMax;
1653
            sliderThresholdVoltageWarn.Minimum = _dLipoVMin;
1654
        }
1655
        private void cBoxMotors_DropDownClosed(object sender, EventArgs e)
1656
        {
1657
            if (cBoxMotors.SelectedIndex > -1)
1658
            {
1659
                _iMotors = cBoxMotors.SelectedIndex + 3;
1660
                Dispatcher.Invoke(() =>
1661
                {
1662
                    dgvMotors1.Height = (272 / 12.6) * (_iMotors + 1);  //272 / 12.6 --> Workaround, cause the headerheight = NaN...?
1663
                    GridMotors.Height = dgvMotors1.Height + 10;
1664
                });
1665
            }
1666
        }
1667
        void _setMotorGridSize()
1668
        {
1669
            if (dgvMotors1.Columns.Count > 2)
1670
            {
1671
                dgvMotors1.Columns[0].Width = 24;
1672
                dgvMotors1.Columns[1].Width = 50;
1673
                dgvMotors1.Columns[2].Width = 50;
1674
                dgvMotors1.Height = (272 / 12.6) * (_iMotors + 1);
1675
                GridMotors.Height = dgvMotors1.Height + 10;
1676
            }
1677
 
1678
        }
1679
        #endregion settings
1680
 
1681
        #region functions  
1682
 
1683
        #region logging      
1684
        /// <summary> Log data to the terminal window. </summary>
1685
        /// <param name="msgtype"> The type of message to be written. </param>
1686
        /// <param name="msg"> The string containing the message to be shown. </param>
1687
        private void Log(LogMsgType msgtype, string msg)
1688
        {
1689
            Dispatcher.Invoke(() =>
1690
            {
1691
                // rtfTerminal.CaretPosition = rtfTerminal.CaretPosition.DocumentEnd;
1692
                // rtfTerminal.Foreground = new SolidColorBrush(LogMsgTypeColor[(int)msgtype]);
1693
                //                rtfTerminal.AppendText(msg + "\r");
1694
                TextRange tr = new TextRange(rtfTerminal.Document.ContentEnd, rtfTerminal.Document.ContentEnd);
1695
                tr.Text = msg;
1696
                tr.ApplyPropertyValue(TextElement.ForegroundProperty, new SolidColorBrush(LogMsgTypeColor[(int)msgtype]));
1697
                rtfTerminal.AppendText("\r");
1698
                rtfTerminal.ScrollToEnd();
1699
            });
1700
        }
1701
        private void ErrorLog(LogMsgType msgtype, string msg, string linkURL, string linkName)
1702
        {
1703
 
1704
            Dispatcher.Invoke(() =>
1705
            {
1706
                Paragraph para = new Paragraph();
1707
                para.Margin = new Thickness(0); // remove indent between paragraphs
1708
 
1709
                Hyperlink link = new Hyperlink();
1710
                if (linkURL != "" && linkName != "")
1711
                {
1712
                    link.IsEnabled = true;
1713
                    link.Inlines.Add(linkName);
1714
                    link.NavigateUri = new Uri(linkURL);
1715
                    link.RequestNavigate += (sender, args) => Process.Start(args.Uri.ToString());
1716
                }
1717
                //msg = DateTime.Now.ToLongTimeString() + msg;
1718
                para.Foreground = new SolidColorBrush(LogMsgTypeColor[(int)msgtype]);
1719
                Run r = new Run("[" + DateTime.Now.ToLongTimeString() + "]: ");
1720
                r.Foreground = new SolidColorBrush(Colors.Black);
1721
                para.Inlines.Add(r);
1722
                para.Inlines.Add(msg);
1723
                para.Inlines.Add(link);
1724
                rtfError.Document.Blocks.Add(para);
1725
                //TextRange tr = new TextRange(rtfError.Document.ContentEnd, rtfError.Document.ContentEnd);
1726
                //tr.Text = msg + link;
1727
                //tr.ApplyPropertyValue(TextElement.ForegroundProperty, new SolidColorBrush(LogMsgTypeColor[(int)msgtype]));
1728
                //rtfError.AppendText("\r");
1729
                rtfError.ScrollToEnd();
1730
 
1731
                //_bErrorLog = true;
1732
            });
1733
        }
1734
        /// <summary>
1735
        /// Clear the line in the  errorlog window 
1736
        /// containing the error string when error has ceased
1737
        /// </summary>
1738
        /// <param name="s">substring of errrormessage</param>
1739
        void _clearErrorLog(string s)
1740
        {
1741
            Dispatcher.Invoke((Action)(() =>
1742
            {
1743
                TextRange searchRange = new TextRange(rtfError.Document.ContentStart, rtfError.Document.ContentEnd);
1744
                TextRange foundRange = FindTextInRange(searchRange, s);
1745
 
1746
                int iStart = searchRange.Text.IndexOf(s, StringComparison.OrdinalIgnoreCase);
1747
 
1748
 
1749
                if (iStart > -1)
1750
                {
1751
                    int iLength = 0;
1752
                    int iEnd = searchRange.Text.IndexOf('\r', iStart);
1753
                    if (iEnd > 0)
1754
                    {
1755
                        iLength = iEnd + 1;
1756
                        int iHttp = searchRange.Text.IndexOf("http", iEnd);
1757
                        if (iHttp == iLength)
1758
                        {
1759
                            int iEnd2 = searchRange.Text.IndexOf('\r', iLength);
1760
                            if (iEnd2 > iLength)
1761
                            {
1762
                                iLength = iEnd2 + 1;
1763
                                //  TextRange result = new TextRange(rtfError.Document.ContentStart.GetPositionAtOffset(iStart), GetTextPositionAtOffset(rtfError.Document.ContentStart.GetPositionAtOffset(iStart), iLength));
1764
 
1765
                                rtfError.Selection.Select(rtfError.Document.ContentStart.GetPositionAtOffset(iStart), GetTextPositionAtOffset(rtfError.Document.ContentStart.GetPositionAtOffset(iStart), iLength));
1766
                                rtfError.Selection.Text = string.Empty;
1767
                                if (rtfError.Document.ContentEnd.GetTextRunLength(LogicalDirection.Backward) < 2) _bErrorLog = false;
1768
                            }
1769
 
1770
                        }
1771
                        else
1772
                        {
1773
                            rtfError.Selection.Select(rtfError.Document.ContentStart.GetPositionAtOffset(iStart), GetTextPositionAtOffset(rtfError.Document.ContentStart.GetPositionAtOffset(iStart), iLength));
1774
                            rtfError.Selection.Text = string.Empty;
1775
                            if (rtfError.Document.ContentEnd.GetTextRunLength(LogicalDirection.Backward) < 2) _bErrorLog = false;
1776
                        }
1777
                    }
1778
                }
1779
            }));
1780
 
1781
        }
1782
        public TextRange FindTextInRange(TextRange searchRange, string searchText)
1783
        {
1784
            int offset = searchRange.Text.IndexOf(searchText, StringComparison.OrdinalIgnoreCase);
1785
            if (offset < 0)
1786
                return null;  // Not found
1787
 
1788
            var start = GetTextPositionAtOffset(searchRange.Start, offset);
1789
            TextRange result = new TextRange(start, GetTextPositionAtOffset(start, searchText.Length));
1790
 
1791
            return result;
1792
        }
1793
        TextPointer GetTextPositionAtOffset(TextPointer position, int characterCount)
1794
        {
1795
            while (position != null)
1796
            {
1797
                if (position.GetPointerContext(LogicalDirection.Forward) == TextPointerContext.Text)
1798
                {
1799
                    int count = position.GetTextRunLength(LogicalDirection.Forward);
1800
                    if (characterCount <= count)
1801
                    {
1802
                        return position.GetPositionAtOffset(characterCount);
1803
                    }
1804
 
1805
                    characterCount -= count;
1806
                }
1807
 
1808
                TextPointer nextContextPosition = position.GetNextContextPosition(LogicalDirection.Forward);
1809
                if (nextContextPosition == null)
1810
                    return position;
1811
 
1812
                position = nextContextPosition;
1813
            }
1814
 
1815
            return position;
1816
        }
1817
        #endregion logging
1818
 
1819
        #region processing received data
1820
 
1821
        private void processMessage(byte[] message)
1822
        {
1823
            if (message.Length > 0)
1824
            {
1825
                _iLifeCounter++;
1826
                //Log(LogMsgType.Incoming, BitConverter.ToString(message));
1827
                //Log(LogMsgType.Incoming, message.Length.ToString());
1828
                string s = new string(ASCIIEncoding.ASCII.GetChars(message, 0, message.Length));
1829
                char cmdID;
1830
                byte adr;
1831
                byte[] data;
1832
                byte[] tmp = null;
1833
                if (message[0] != '#')
1834
                {
1835
                    int iFound = -1;
1836
                    for (int i = 0; i < message.Length; i++)   //Sometimes the FC/NC sends strings without termination (like WP messages)
1837
                    {                                   //so this is a workaround to not spam the log box
1838
                        if (message[i] == 35)
1839
                        {
1840
                            iFound = i;
1841
                            break;
1842
                        }
1843
                    }
1844
                    if (iFound > 0)
1845
                    {
1846
                        s = new string(ASCIIEncoding.ASCII.GetChars(message, 0, iFound));
1847
                        tmp = new byte[message.Length - iFound];
1848
                        Buffer.BlockCopy(message, iFound, tmp, 0, message.Length - iFound);
1849
                    }
1850
                    s = s.Trim('\0', '\n', '\r');
1851
                    if (s.Length > 0)
1852
                        Log(LogMsgType.Normal, s);
1853
                    if (tmp != null)
1854
                    {
1855
                        s = new string(ASCIIEncoding.ASCII.GetChars(tmp, 0, tmp.Length));
1856
                        processMessage(tmp);
1857
                    }
1858
                }
1859
                //Debug.Print(s);
1860
                else
1861
                {
1862
                    FlightControllerMessage.ParseMessage(message, out cmdID, out adr, out data);
1863
 
1864
                    if (adr == 255) { crcError++; }
1865
                    else crcError = 0;
1866
                    Dispatcher.Invoke(() => tbCrc.Text = crcError.ToString());
1867
                    //display the active controller (FC / NC) 
1868
                    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...???
1869
                    {
1870
                        _iCtrlAct = adr;
1871
                        switch (adr)
1872
                        {
1873
                            case 1:
1874
                                Dispatcher.Invoke(() => tbCtrl.Text = "FC");
1875
                                Dispatcher.Invoke(() => buttonSwitchNC.Visibility = Visibility.Visible);
1876
                                Dispatcher.Invoke(() => labelSwitchToNavi.Visibility = Visibility.Visible);
1877
                                //  _setFieldsNA(); //display fields NA for FC 
1878
                                break;
1879
                            case 2:
1880
                                Dispatcher.Invoke(() => tbCtrl.Text = "NC");
1881
                                Dispatcher.Invoke(() => buttonSwitchNC.Visibility = Visibility.Hidden);
1882
                                Dispatcher.Invoke(() => labelSwitchToNavi.Visibility = Visibility.Hidden);
1883
                                break;
1884
                            //case 3:
1885
                            //    lblCtrl.Invoke((Action)(() => lblCtrl.Text = "MK3MAG"));
1886
                            //    break;
1887
                            //case 4:
1888
                            //    lblCtrl.Invoke((Action)(() => lblCtrl.Text = "BL-CTRL"));
1889
                            //    break;
1890
                            default:
1891
                                Dispatcher.Invoke(() => tbCtrl.Text = "NA");
1892
                                break;
1893
                        }
1894
                        // _loadLabelNames();
1895
                    }
1896
                    // else
1897
                    //     Debug.Print("Address == 0?");
1898
 
1899
                    if (data != null && data.Length > 0)
1900
                    {
1901
                        s = new string(ASCIIEncoding.ASCII.GetChars(data, 1, data.Length - 1));
1902
                        s = s.Trim('\0', '\n');
1903
 
1904
                        switch (cmdID)
1905
                        {
1906
                            //case 'A': //Label names
1907
                            //    _processLabelNames(s);
1908
                            //    break;
1909
 
1910
                            case 'D': //Debug data
1911
                                _processDebugVals(adr, data);
1912
                                break;
1913
 
1914
                            case 'V': //Version
1915
                                _processVersion(adr, data);
1916
                                break;
1917
 
1918
                            case 'K'://BL-CTRL data
1919
                                _processBLCtrl(data);
1920
                                break;
1921
 
1922
                            case 'M'://License info
1923
                                _processLicense(data);
1924
                                break;
1925
 
1926
                            case 'O': //NC Data
1927
                                if (data[0] < 10)
1928
                                    _processNCData(data);
1929
                                else
1930
                                    _processNCDataV2(data);
1931
                                break;
1932
 
1933
                            //case 'E': //NC error-string
1934
                            //    ErrorLog(LogMsgType.Error, "NC Error: " + s);
1935
                            //    break;
1936
 
1937
                            case 'L': //OSD Menue (called by pagenumber)
1938
                                _processOSDSingle(data);
1939
                                break;
1940
 
1941
                            case 'H': //OSD Menue (with autoupdate - called by Key)
1942
                                _processOSDAuto(data);
1943
                                break;
1944
 
1945
                            case 'X': //Waypoint data
1946
                                _processWPData(data);
1947
                                break;
1948
 
1949
                            case 'W': //return new Waypoint items count after sending waypoint to copter
1950
                                _iWPCount = data[0];
1951
                                break;
1952
                                //default:
1953
                                //    Log(LogMsgType.Incoming, "cmd: " + cmdID.ToString());
1954
                                //    Log(LogMsgType.Incoming, BitConverter.ToString(data));
1955
                                //    break;
1956
                        }
1957
                    }
1958
                    //else
1959
                    //{
1960
                    //    Log(LogMsgType.Incoming, "cmd: " + cmdID.ToString());
1961
                    //    Log(LogMsgType.Incoming, BitConverter.ToString(data));
1962
                    //}
1963
                }
1964
            }
1965
        }
1966
        /// <summary>
1967
        /// Analog label names 'A'
1968
        /// each label name is returned as a single string 
1969
        /// and added to string array sAnalogLabel[]
1970
        /// and the datatable dtAnalog
1971
        /// </summary>
1972
        /// <param name="s">the label name</param>
1973
        void _processLabelNames(string s)
1974
        {
1975
            //if (iLableIndex < 32)
1976
            //{
1977
            //    sAnalogLabel[iLableIndex] = s;
1978
            //    if (dtAnalog.Rows.Count < 32)
1979
            //        dtAnalog.Rows.Add(s, "");
1980
            //    else
1981
            //        dtAnalog.Rows[iLableIndex].SetField(0, s);
1982
 
1983
            //  //  _getAnalogLabels(iLableIndex + 1);
1984
            //}
1985
            //Debug.Print(s);
1986
        }
1987
        /// <summary>
1988
        /// Debug values 'D'
1989
        /// </summary>
1990
        /// <param name="adr">adress of the active controller (1-FC, 2-NC)</param>
1991
        /// <param name="data">the received byte array to process</param>
1992
        void _processDebugVals(byte adr, byte[] data)
1993
        {
1994
            if (data.Length == 66)
1995
            {
1996
 
1997
                double v;
1998
                int index = 0;
1999
                Int16 i16 = 0;
2000
                double dTemp = 0;
2001
                for (int i = 2; i < 66; i += 2)
2002
                {
2003
                    i16 = data[i + 1];
2004
                    i16 = (Int16)(i16 << 8);
2005
                    iAnalogData[index] = data[i] + i16;
2006
                    sAnalogData[index] = (data[i] + i16).ToString();
2007
                    // dtAnalog.Rows[index].SetField(1, sAnalogData[index]);
2008
 
2009
                    if (adr == 2) //NC
2010
                    {
2011
                        switch (index)
2012
                        {
2013
                            case 0: //pitch (German: nick)
2014
                                Dispatcher.Invoke(() => ArtHor.Pitch = ((double)iAnalogData[index] / (double)10));
2015
                                Dispatcher.Invoke((Action)(() => tbPitch.Text = ((double)iAnalogData[index] / (double)10).ToString("0.0°")));
2016
                                break;
2017
                            case 1: //roll
2018
                                Dispatcher.Invoke(() => ArtHor.Roll = ((double)iAnalogData[index] / (double)10));
2019
                                Dispatcher.Invoke((Action)(() => tbRoll.Text = ((double)iAnalogData[index] / (double)10).ToString("0.0°")));
2020
                                break;
2021
                            case 4: //altitude
2022
                                Dispatcher.Invoke(() => tbAlt.Text = ((double)iAnalogData[index] / (double)10).ToString("0.0 m"));
2023
                                Dispatcher.Invoke(() => tbTopHeight.Text = ((double)iAnalogData[index] / (double)10).ToString("0.0 m"));
2024
                                Dispatcher.Invoke(() => { drGPX[3] = (double)iAnalogData[index] / (double)10; });
2025
                                break;
2026
                            case 7: //Voltage
2027
                                v = (double)iAnalogData[index] / (double)10;
2028
                                Dispatcher.Invoke(() => tbVolt.Text = v.ToString("0.0 V"));
2029
                                Dispatcher.Invoke(() => tbTopVoltage.Text = v.ToString("0.0 V"));
2030
                                Dispatcher.Invoke(() => pbTopVoltage.Value = v);
2031
                                if (v - _dLipoVMin < 1 | v < _dThresholdVoltageWarn)
2032
                                {
2033
                                    if (v == _dVoltLast)
2034
                                        if (_iVoltJitter < 20) _iVoltJitter++;
2035
                                        else
2036
                                        {
2037
                                            _iVoltJitter = 0;
2038
                                            _dVoltLast = v;
2039
                                        }
2040
                                    _dVoltLast = v;
2041
                                    if (_iVoltJitter == 20)
2042
                                    {
2043
                                        Dispatcher.Invoke(() => pbTopVoltage.Foreground = Brushes.Orange);
2044
 
2045
                                        if (v - _dLipoVMin < 1 | v < _dThresholdVoltageCrit)
2046
                                        {
2047
                                            Dispatcher.Invoke(() => pbTopVoltage.Foreground = Brushes.Red);
2048
                                            if (stbVoltageCritAnim != null && !_bCritAnimVoltActive)
2049
                                            {
2050
                                                Dispatcher.Invoke(() => stbVoltageCritAnim.Begin());
2051
                                                _bCritAnimVoltActive = true;
2052
                                            }
2053
                                            if (_bVoiceVoltPlay && !_bCritVoiceVoltActive)
2054
                                            {
2055
                                                ThreadPool.QueueUserWorkItem(new WaitCallback(_mediaPlayer), "Voice\\" + _voiceLanguage[_iVoiceIndex] + "\\CriticalBattery.mp3");
2056
                                                //Thread t = new Thread(() => _mediaPlayer("Voice\\CriticalBattery.mp3"));
2057
                                                //t.Start();
2058
                                                _bCritVoiceVoltActive = true;
2059
                                            }
2060
                                        }
2061
                                        else
2062
                                        {
2063
                                            if (stbVoltageCritAnim != null && _bCritAnimVoltActive)
2064
                                            {
2065
                                                Dispatcher.Invoke(() => stbVoltageCritAnim.Stop());
2066
                                                _bCritAnimVoltActive = false;
2067
                                            }
2068
                                            _bCritVoiceVoltActive = false;
2069
 
2070
                                            if (_bVoiceVoltPlay && !_bWarnVoiceVoltActive)
2071
                                            {
2072
                                                ThreadPool.QueueUserWorkItem(new WaitCallback(_mediaPlayer), "Voice\\" + _voiceLanguage[_iVoiceIndex] + "\\LowBattery.mp3");
2073
                                                //Thread t = new Thread(() => _mediaPlayer("Voice\\LowBattery.mp3"));
2074
                                                //t.Start();
2075
                                                _bWarnVoiceVoltActive = true;
2076
                                            }
2077
                                        }
2078
                                    }
2079
                                }
2080
                                else
2081
                                {
2082
                                    Dispatcher.Invoke(() => pbTopVoltage.Foreground = new SolidColorBrush(Color.FromArgb(255, 107, 195, 123)));
2083
                                    if (stbVoltageCritAnim != null && _bCritAnimVoltActive)
2084
                                    {
2085
                                        Dispatcher.Invoke(() => stbVoltageCritAnim.Stop());
2086
                                        _bCritAnimVoltActive = false;
2087
                                    }
2088
                                    _bCritVoiceVoltActive = false;
2089
                                    _bWarnVoiceVoltActive = false;
2090
                                    _iVoltJitter = 0;
2091
                                }
2092
                                break;
2093
                            case 8: // Current
2094
                                Dispatcher.Invoke(() => tbCur.Text = ((double)iAnalogData[index] / (double)10).ToString("0.0 A"));
2095
                                Dispatcher.Invoke(() => tbTopCurrent.Text = ((double)iAnalogData[index] / (double)10).ToString("0.0 A"));
2096
                                break;
2097
                            case 10: //heading
2098
                                Dispatcher.Invoke((Action)(() => tbHeading.Text = sAnalogData[index] + "°"));
2099
                                if (!_Simulate) //use NavData for simulation
2100
                                {
2101
                                    Dispatcher.Invoke(() => ArtHor.rotate = iAnalogData[index]);
2102
                                    Dispatcher.Invoke(() => ((CustomMarkerCopter)(copter.Shape)).rotate = iAnalogData[index]);
2103
                                }
2104
                                break;
2105
                            case 12: // SPI error
2106
                                Dispatcher.Invoke((Action)(() => tbSPI.Text = sAnalogData[index]));
2107
                                break;
2108
                            case 14: //i2c error
2109
                                Dispatcher.Invoke((Action)(() => tbI2C.Text = sAnalogData[index]));
2110
                                break;
2111
                            case 20: //Earthmagnet field
2112
                                Dispatcher.Invoke((Action)(() => tbMagF.Text = sAnalogData[index] + "%"));
2113
                                Dispatcher.Invoke((Action)(() => tbTopEarthMag.Text = sAnalogData[index] + "%"));
2114
 
2115
                                if (Math.Abs(100 - iAnalogData[index]) < _iThresholdMagField)
2116
                                {
2117
                                    Dispatcher.Invoke(() => imageEarthMag.Source = new BitmapImage(new Uri("Images/EarthMag.png", UriKind.Relative)));
2118
                                    _iMagneticFieldJitter = 0; _bVoiceMagneticFieldActive = false;
2119
                                    if (stbMagneticFieldAnim != null && _bAnimMagneticFieldActive)
2120
                                    {
2121
                                        Dispatcher.Invoke(() => stbMagneticFieldAnim.Stop());
2122
                                        _bAnimMagneticFieldActive = false;
2123
                                    }
2124
                                }
2125
                                else
2126
                                {
2127
                                    Dispatcher.Invoke(() => imageEarthMag.Source = new BitmapImage(new Uri("Images/EarthMag_R.png", UriKind.Relative)));
2128
                                    if (_iMagneticFieldLast >= Math.Abs(100 - iAnalogData[index]))
2129
                                    {
2130
                                        if (_iMagneticFieldJitter < 20)
2131
                                            _iMagneticFieldJitter++;
2132
                                    }
2133
                                    else
2134
                                    {
2135
                                        _iMagneticFieldJitter = 0;
2136
                                        _iMagneticFieldLast = Math.Abs(100 - iAnalogData[index]);
2137
                                    }
2138
                                    if (_iMagneticFieldJitter == 20)
2139
                                    {
2140
                                        if (stbMagneticFieldAnim != null && !_bAnimMagneticFieldActive)
2141
                                        {
2142
                                            Dispatcher.Invoke(() => stbMagneticFieldAnim.Begin());
2143
                                            _bAnimMagneticFieldActive = true;
2144
                                        }
2145
                                        if (_bVoiceMagneticFieldPlay && !_bVoiceMagneticFieldActive)
2146
                                        {
2147
                                            ThreadPool.QueueUserWorkItem(new WaitCallback(_mediaPlayer), "Voice\\" + _voiceLanguage[_iVoiceIndex] + "\\MagneticField.mp3");
2148
                                            //Thread t = new Thread(() => _mediaPlayer("Voice\\MagneticField.mp3"));
2149
                                            //t.Start();
2150
                                            _bVoiceMagneticFieldActive = true;
2151
                                        }
2152
                                    }
2153
                                }
2154
                                break;
2155
                            case 21: //GroundSpeed
2156
                                Dispatcher.Invoke((Action)(() => tbSpeed.Text = ((double)iAnalogData[index] / (double)100).ToString("0.00 m/s")));
2157
                                if (!_Simulate)
2158
                                    Dispatcher.Invoke((Action)(() => tbTopSpeed.Text = ((double)iAnalogData[index] / (double)100).ToString("0.00 m/s")));
2159
                                break;
2160
 
2161
                            ///**********   needs testing --> not sure what position this is  ***************
2162
                            case 28: //Distance East from saved home position -> calculate distance with distance N + height
2163
                                dTemp = Math.Pow((double)iAnalogData[index], 2) + Math.Pow((double)iAnalogData[index - 1], 2);
2164
                                dTemp = Math.Sqrt(dTemp) / (double)10; //'flat' distance from HP with N/E
2165
                                                                       //  lblNCDist.Invoke((Action)(() => lblNCDist.Text = dTemp.ToString("0.00")));
2166
                                dTemp = Math.Pow(dTemp, 2) + Math.Pow(((double)iAnalogData[4] / (double)10), 2); //adding 'height' into calculation
2167
                                dTemp = Math.Sqrt(dTemp) / (double)10;
2168
                                //     Dispatcher.Invoke((Action)(() => tbTopDistanceHP.Text = dTemp.ToString("0.0 m")));
2169
                                Dispatcher.Invoke((Action)(() => tbHP1.Text = dTemp.ToString("0.0 m")));
2170
                                break;
2171
 
2172
                            case 31: //Sats used
2173
                                Dispatcher.Invoke((Action)(() => tbSats.Text = sAnalogData[index]));
2174
                                // Dispatcher.Invoke((Action)(() => tbTopSats.Text = sAnalogData[index]));                                   
2175
                                break;
2176
                        }
2177
                    }
2178
                    index++;
2179
                }
2180
            }
2181
            else
2182
                Debug.Print("wrong data-length (66): " + data.Length.ToString());
2183
        }
2184
        /// <summary>
2185
        /// Version string 'V'
2186
        /// </summary>
2187
        /// <param name="adr">adress of the active controller (1-FC, 2-NC)</param>
2188
        /// <param name="data">the received byte array to process</param>
2189
        void _processVersion(byte adr, byte[] data)
2190
        {
2191
            if (data.Length == 12)
2192
            {
2193
                if (!check_HWError)
2194
                {
2195
                    string[] sVersionStruct = new string[10] { "SWMajor: ", "SWMinor: ", "ProtoMajor: ", "LabelTextCRC: ", "SWPatch: ", "HardwareError 1: ", "HardwareError 2: ", "HWMajor: ", "BL_Firmware: ", "Flags: " };
2196
                    string sVersion = "";
2197
                    //sbyte[] signed = Array.ConvertAll(data, b => unchecked((sbyte)b));
2198
                    Log(LogMsgType.Warning, (adr == 1 ? "FC-" : "NC-") + "Version: ");
2199
                    sVersion = "HW V" + (data[7] / 10).ToString() + "." + (data[7] % 10).ToString();
2200
                    Log(LogMsgType.Incoming, sVersion);
2201
                    sVersion = "SW V" + (data[0]).ToString() + "." + (data[1]).ToString() + ((char)(data[4] + 'a')).ToString();
2202
                    Log(LogMsgType.Incoming, sVersion);
2203
                    Log(LogMsgType.Incoming, "BL-Firmware: V" + (data[8] / 100).ToString() + "." + (data[8] % 100).ToString());
2204
                }
2205
                if (data[5] > 0) //error0 
2206
                {
2207
                    if (adr == 1)
2208
                        ErrorLog(LogMsgType.Error, " FC - HW-Error " + data[5].ToString() + ": " + ((FC_HWError0)data[5]).ToString(), "", "");
2209
                    if (adr == 2)
2210
                        ErrorLog(LogMsgType.Error, " NC - HW-Error " + data[5].ToString() + ": " + ((NC_HWError0)data[5]).ToString(), "", "");
2211
                }
2212
                if (data[6] > 0) //error1 
2213
                {
2214
                    if (adr == 1)
2215
                        ErrorLog(LogMsgType.Error, " FC - HW-Error " + data[6].ToString() + ": " + ((FC_HWError1)data[6]).ToString(), "", "");
2216
                    if (adr == 2)
2217
                        ErrorLog(LogMsgType.Error, " NC - Unknown HW-ERROR: " + data[6].ToString(), "", ""); //@moment NC has only one error field
2218
                }
2219
                //if ((data[5] + data[6] == 0) && _bErrorLog)
2220
                //    _clearErrorLog(adr == 1 ? "FC - HW-Error" : "NC - HW-Error");
2221
 
2222
            }
2223
            check_HWError = false;
2224
        }
2225
 
2226
        void _processLicense(byte[] data)
2227
        {
2228
            if (data.Length > 480)
2229
            {
2230
                Dispatcher.Invoke(() => {
2231
                    tbDataLicenseUser.Text = new string(ASCIIEncoding.ASCII.GetChars(data, 1, 127));
2232
                    tbDataLicenseMail.Text = new string(ASCIIEncoding.ASCII.GetChars(data, 129, 127));
2233
                    tbDataLicenseFeature.Text = new string(ASCIIEncoding.ASCII.GetChars(data, 257, 127));
2234
                    tbDataLicenseExpire.Text = new string(ASCIIEncoding.ASCII.GetChars(data, 385, 11));
2235
                    tbDataLicenseLicense.Text = new string(ASCIIEncoding.ASCII.GetChars(data, 397, 16));
2236
                });
2237
            }
2238
        }
2239
        /// <summary>
2240
        /// BL-Ctrl data 'K'
2241
        /// for FC you have to use a customized firmware
2242
        /// </summary>
2243
        /// <param name="data">the received byte array to process</param>
2244
        void _processBLCtrl(byte[] data)
2245
        {
2246
            if (data.Length % 6 == 0) //data.Length up to 96 (16 motors x 6 byte data) --> new datastruct in FC -> not standard!
2247
            {
2248
                bool bAvailable = false;
2249
                bool bTempError = false;
2250
                for (int i = 0; i < data.Length && data[i] < _iMotors; i += 6) // data[i] < _iMotors -- only show set number of motors (12 max @ moment)
2251
                {
2252
 
2253
                    if ((data[i + 4] & 128) == 128) //Status bit at pos 7 = 128 dec -- if true, motor is available
2254
                        bAvailable = true;
2255
                    else
2256
                        bAvailable = false;
2257
 
2258
                    if (data[i] < _iMotors)
2259
                    {
2260
                        if (bAvailable)
2261
                        {
2262
                            dtMotors.Rows[data[i]].SetField(1, ((double)data[i + 1] / (double)10).ToString("0.0 A"));
2263
                            dtMotors.Rows[data[i]].SetField(2, data[i + 2].ToString("0 °C"));
2264
                            int temp = data[i + 2];
2265
                            if (temp < _iThresholdBLCTRLTempWarn)
2266
                            {
2267
                                _iBLCTRLTempJitter[data[i]] = 0;
2268
                            }
2269
                            else
2270
                            {
2271
                                if (_iBLCTRLTempLast[data[i]] > _iThresholdBLCTRLTempWarn)
2272
                                {
2273
                                    if (_iBLCTRLTempJitter[data[i]] < 12)
2274
                                        _iBLCTRLTempJitter[data[i]]++;
2275
                                }
2276
                                else
2277
                                {
2278
                                    _iBLCTRLTempJitter[data[i]] = 0;
2279
                                }
2280
                                _iBLCTRLTempLast[data[i]] = temp;
2281
                                if (_iBLCTRLTempJitter[data[i]] == 12)
2282
                                {
2283
                                    bTempError = true;
2284
                                    Dispatcher.Invoke(() =>
2285
                                    {
2286
                                        DataGridRow row = (DataGridRow)dgvMotors1.ItemContainerGenerator.ContainerFromIndex(data[i]);
2287
                                        if (row != null)
2288
                                        {
2289
                                            DataGridCell cell = dgvMotors1.Columns[2].GetCellContent(row).Parent as DataGridCell;
2290
                                            if(cell != null)
2291
                                                cell.Background = new SolidColorBrush(Colors.Red);
2292
                                        }
2293
                                    });
2294
                                    if (stbBLCTRLTempAnim != null && !_bAnimBLCTRLTempActive)
2295
                                    {
2296
                                        Dispatcher.Invoke(() => stbBLCTRLTempAnim.Begin());
2297
                                        _bAnimBLCTRLTempActive = true;
2298
                                    }
2299
                                    if (_bVoiceBLCTRLTempPlay && !_bVoiceBLCTRLTempActive)
2300
                                    {
2301
                                        ThreadPool.QueueUserWorkItem(new WaitCallback(_mediaPlayer), "Voice\\" + _voiceLanguage[_iVoiceIndex] + "\\BLCtrlTemp.mp3");
2302
                                        _bVoiceBLCTRLTempActive = true;
2303
                                    }
2304
                                }
2305
                            }
2306
                            if(_iBLCTRLTempJitter.All(x=>x<12))
2307
                            {
2308
                                _bVoiceBLCTRLTempActive = false;
2309
                                if (stbBLCTRLTempAnim != null && _bAnimBLCTRLTempActive)
2310
                                {
2311
                                    Dispatcher.Invoke(() => stbBLCTRLTempAnim.Stop());
2312
                                    _bAnimBLCTRLTempActive = false;
2313
                                    Dispatcher.Invoke(() =>
2314
                                    {
2315
                                        for (int k = 0; k < _iMotors; k++)
2316
                                        {
2317
                                            dgvMotors1.Items.Refresh();
2318
                                            dgvMotors1.UpdateLayout();
2319
 
2320
                                            DataGridRow row = (DataGridRow)dgvMotors1.ItemContainerGenerator.ContainerFromIndex(data[k]);
2321
                                            if (row != null)
2322
                                            {
2323
                                                DataGridCell cell = dgvMotors1.Columns[2].GetCellContent(row).Parent as DataGridCell;
2324
                                                if (cell != null)
2325
                                                    cell.Background = new SolidColorBrush(Colors.Transparent);
2326
                                            }
2327
                                        }
2328
                                    });
2329
                                }
2330
                            }
2331
                        }
2332
                        else
2333
                        {
2334
                            dtMotors.Rows[data[i]].SetField(1, "NA");
2335
                            dtMotors.Rows[data[i]].SetField(2, "NA");
2336
                        }
2337
                    }
2338
                    //if (data[i] > 3 && data[i] < 8)
2339
                    //{
2340
                    //    if (bAvailable)
2341
                    //    {
2342
                    //        dtMotors2.Rows[data[i] - 4].SetField(1, ((double)data[i + 1] / (double)10).ToString("0.0 A"));
2343
                    //        dtMotors2.Rows[data[i] - 4].SetField(2, data[i + 2].ToString("0 °C"));
2344
                    //    }
2345
                    //    else
2346
                    //    {
2347
                    //        dtMotors2.Rows[data[i] - 4].SetField(1, "NA");
2348
                    //        dtMotors2.Rows[data[i] - 4].SetField(2, "NA");
2349
                    //    }
2350
                    //}
2351
                }
2352
            }
2353
        }
2354
        /// <summary>
2355
        /// Navi-Ctrl data 'O'
2356
        /// GPS-Position, capacatiy, flying time...
2357
        /// </summary>
2358
        /// <param name="data">the received byte array to process</param>
2359
 
2360
 
2361
        byte OSDSTATUSFLAGS1 = 0;
2362
        byte OSDSTATUSFLAGS2 = 0;
2363
        void _processNCDataV2(byte[] data)
2364
        {
2365
            if ((int)data[0] < 17)
2366
            {
2367
                int i_32, i_16, iVal;
2368
                double d;
2369
                OSD_Base_Data_t osd = new OSD_Base_Data_t(data);
2370
                OSDSTATUSFLAGS1 = osd.OSDSTATUSFLAGS1();
2371
                Dispatcher.Invoke(() => { drGPX[2] = osd.Pos().Lng; });
2372
                Dispatcher.Invoke(() => { drGPX[1] = osd.Pos().Lat; });
2373
                Dispatcher.Invoke(() => { drGPX[4] = DateTime.UtcNow.ToString("u", System.Globalization.CultureInfo.InvariantCulture); }); //2011-01-14T01:59:01Z });
2374
                Dispatcher.Invoke((Action)(() => tbNCGrSpeed.Text = osd.Speed().ToString("0.0 m/s")));
2375
                if (_Simulate)
2376
                    Dispatcher.Invoke((Action)(() => tbTopSpeed.Text = osd.Speed().ToString("0.0 m/s")));
2377
 
2378
                switch ((int)data[0])
2379
                {
2380
                    case 10:
2381
                        char[] c = Encoding.ASCII.GetChars(new byte[] { data[13] });
2382
                        Dispatcher.Invoke((Action)(() => tbCamCtrl.Text = c[0].ToString()));
2383
                        break;
2384
                    case 11:
2385
                        OSDSTATUSFLAGS2 = osd.OSDSTATUSFLAGS2();
2386
                        //---------------NC-Flags--------------------------
2387
                        Dispatcher.Invoke((Action)(() => NC1_2.Background = ((data[14] & 2) == 2) ? new SolidColorBrush(Colors.LightSeaGreen) : new SolidColorBrush(Colors.Transparent)));// NC_FLAG_PH                                 0x02
2388
                        Dispatcher.Invoke((Action)(() => NC1_3.Background = ((data[14] & 4) == 4) ? new SolidColorBrush(Colors.LightSeaGreen) : new SolidColorBrush(Colors.Transparent)));// NC_FLAG_CH                                 0x04
2389
                        Dispatcher.Invoke((Action)(() => NC1_4.Background = ((data[14] & 8) == 8) ? new SolidColorBrush(Colors.LightCoral) : new SolidColorBrush(Colors.Transparent)));// NC_FLAG_RANGE_LIMIT                           0x08
2390
                        Dispatcher.Invoke((Action)(() => NC1_5.Background = ((data[14] & 16) == 16) ? new SolidColorBrush(Colors.LightCoral) : new SolidColorBrush(Colors.Transparent)));// NC_FLAG_NOSERIALLINK                                0x10
2391
                        Dispatcher.Invoke((Action)(() => NC1_6.Background = ((data[14] & 32) == 32) ? new SolidColorBrush(Colors.LightSeaGreen) : new SolidColorBrush(Colors.Transparent)));// NC_FLAG_TARGET_REACHED                           0x20
2392
                        Dispatcher.Invoke((Action)(() => NC1_7.Background = ((data[14] & 64) == 64) ? new SolidColorBrush(Colors.DodgerBlue) : new SolidColorBrush(Colors.Transparent)));// NC_FLAG_MANUAL_CONTROL                              0x40
2393
                        Dispatcher.Invoke((Action)(() => NC1_8.Background = ((data[14] & 128) == 128) ? new SolidColorBrush(Colors.LightSeaGreen) : new SolidColorBrush(Colors.Transparent)));// NC_FLAG_GPS_OK                                 0x80
2394
 
2395
                        Dispatcher.Invoke((Action)(() => tbSideBarStatusPH.Text = ((data[14] & 4) == 4) ? "CH" : "PH"));// NC_FLAG_PH 0x02 / NC_FLAG_CH 0x04
2396
                        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
2397
                        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
2398
                        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
2399
 
2400
                        //--------------- NC Error ------------------------
2401
                        Dispatcher.Invoke((Action)(() => tbNCErr.Text = data[16].ToString()));  //NC Errornumber
2402
                        if (data[16] > 0)
2403
                            _readNCError();
2404
                        if (data[16] > 0 & data[16] < 44)
2405
                            ErrorLog(LogMsgType.Error, " NC Error [" + data[16].ToString() + "]: ", NC_Error_Link[data[16]], NC_Error[data[16]]);
2406
 
2407
                        break;
2408
                    case 12:
2409
                        //--------------- RC quality ------------------------
2410
                        Dispatcher.Invoke((Action)(() => tbRCQ.Text = data[23].ToString()));
2411
                        Dispatcher.Invoke((Action)(() => tbTopRC.Text = data[23].ToString()));
2412
 
2413
                        if (data[23] > _iThresholdRC)
2414
                        {
2415
                            _iRCLevelJitter = 0; _bVoiceRCLevelActive = false;
2416
                            if (stbRCLevelAnim != null && _bAnimRCLevelActive)
2417
                            {
2418
                                Dispatcher.Invoke(() => stbRCLevelAnim.Stop());
2419
                                _bAnimRCLevelActive = false;
2420
                            }
2421
                        }
2422
                        else
2423
                        {
2424
                            if (_iRCLevelJitter < 20) _iRCLevelJitter++;
2425
                            if (_iRCLevelJitter == 20)
2426
                            {
2427
                                if (stbRCLevelAnim != null && !_bAnimRCLevelActive)
2428
                                {
2429
                                    Dispatcher.Invoke(() => stbRCLevelAnim.Begin());
2430
                                    _bAnimRCLevelActive = true;
2431
                                }
2432
                                if (_bVoiceRCLevelPlay && !_bVoiceRCLevelActive)
2433
                                {
2434
                                    _bVoiceRCLevelActive = true;
2435
                                    ThreadPool.QueueUserWorkItem(new WaitCallback(_mediaPlayer), "Voice\\" + _voiceLanguage[_iVoiceIndex] + "\\RCLevel.mp3");
2436
                                    //Thread th = new Thread(() => _mediaPlayer("Voice\\RCLevel.mp3"));
2437
                                    //th.Start();
2438
                                }
2439
                                _iRCLevelJitter++;
2440
                            }
2441
                        }
2442
                        break;
2443
                    case 13:
2444
                        //-------------------------Waypoint max range (by license)------------------------------
2445
                        i_32 = data[24];
2446
                        iVal = i_32 << 8;
2447
                        iVal += data[23];
2448
 
2449
                        if (dWPMaxRange != iVal)
2450
                        {
2451
                            dWPMaxRange = iVal;
2452
                            if (home != null && checkBoxShowWPMaxRange.IsChecked == true)
2453
                            {
2454
                                if (cWPBound != null && cWPBound.Tag != null)
2455
                                    MainMap.Markers.Remove(cWPBound.Tag as GMapMarker);
2456
 
2457
                                createCircle(home.Position, dWPMaxRange);
2458
                                Dispatcher.Invoke(() =>
2459
                                {
2460
                                    if (comboBoxWPMaxRangeColor.SelectionBoxItem != null)
2461
                                    {
2462
                                        string s = _colors[comboBoxWPMaxRangeColor.SelectedIndex];
2463
                                        cWPBound.setColor(s);
2464
                                    }
2465
                                });
2466
                            }
2467
                            Dispatcher.Invoke((Action)(() => tbWPMaxRange.Text = iVal.ToString() + " m"));
2468
                        }
2469
                        //--------------- LiPoCell count ------------------------
2470
                        Dispatcher.Invoke((Action)(() => tbLiPoCells.Text = data[25].ToString()));
2471
                        Dispatcher.Invoke((Action)(() => {
2472
                            if (_bLiPoAutoDetect == true)
2473
                            {
2474
                                if(data[25] > 2 && data[25] < 7 && _LipoCells != data[25])
2475
                                {
2476
                                    cBoxLiPoCells.SelectedIndex = data[25] - 3;
2477
                                    _LipoCells = data[25];
2478
                                    _LipoMinMax();
2479
                                }
2480
                            }
2481
                        }));
2482
 
2483
                        break;
2484
 
2485
                    case 14:
2486
                        //--------------- Flying time ------------------------
2487
                        i_16 = data[14];
2488
                        i_16 = (Int16)(i_16 << 8);
2489
                        iVal = data[13] + i_16;
2490
                        TimeSpan t = TimeSpan.FromSeconds(iVal);
2491
                        string Text = t.Hours.ToString("D2") + ":" + t.Minutes.ToString("D2") + ":" + t.Seconds.ToString("D2");
2492
                        Dispatcher.Invoke((Action)(() => tbFTime.Text = Text.ToString()));
2493
                        Dispatcher.Invoke((Action)(() => tbTopFTime.Text = Text.ToString()));
2494
 
2495
                        //--------------------------------Distance HP------------------------------------
2496
                        i_16 = data[16];
2497
                        i_16 = (Int16)(i_16 << 8);
2498
                        iVal = data[15] + i_16;
2499
                        Dispatcher.Invoke((Action)(() => tbHP.Text = ((double)iVal / (double)10).ToString("0.0 m")));
2500
 
2501
                        //--------------------------Distance to next WP--------------------------------
2502
                        i_16 = data[19];
2503
                        i_16 = (Int16)(i_16 << 8);
2504
                        iVal = data[18] + i_16;
2505
                        Dispatcher.Invoke((Action)(() => tbWP.Text = ((double)iVal / (double)10).ToString("0.0 m")));
2506
                        Dispatcher.Invoke((Action)(() => lblWPRouteDistanceWP.Content = ((double)iVal / (double)10).ToString("0.0 m")));
2507
                        Dispatcher.Invoke((Action)(() => tbWPStatusDistanceWP.Text = ((double)iVal / (double)10).ToString("0.0 m")));
2508
 
2509
                        //-------------------Satellites----------------------------------
2510
                        Dispatcher.Invoke((Action)(() => tbTopSats.Text = data[23].ToString()));
2511
 
2512
                        if (data[23] > 4)//if more than 4 sats in use . otherwise the map would jump and scroll insane at beginning
2513
                        {
2514
                            _bSatFix = true; _iSatsJitter = 0; _bVoiceSatFixActive = false;
2515
                            if (_bAutoHome && !_bFirstSatFix)
2516
                            {
2517
                                if (_iFirstSatFix < 3)
2518
                                    _iFirstSatFix++;
2519
                                else
2520
                                {
2521
                                    _bFirstSatFix = true;
2522
                                    Dispatcher.Invoke(() => _setHomePos());
2523
                                }
2524
                            }
2525
                            if (stbSatFixLostAnim != null && _bAnimSatFixActive)
2526
                            {
2527
                                Dispatcher.Invoke(() => stbSatFixLostAnim.Stop());
2528
                                _bAnimSatFixActive = false;
2529
                            }
2530
                            if (!_bFollowCopter)
2531
                            {
2532
                                _setCopterData(osd.Pos());
2533
                                if (!MainMap.ViewArea.Contains(osd.Pos()))
2534
                                    Dispatcher.Invoke(() => MainMap.Position = osd.Pos());
2535
 
2536
                            }
2537
                            else
2538
                                Dispatcher.Invoke(() => MainMap.Position = osd.Pos());
2539
                        }
2540
                        else
2541
                        {
2542
                            if (_bSatFix)
2543
                            {
2544
                                if (data[23] == _iSatsLast)
2545
                                {
2546
                                    if (_iSatsJitter < 20) _iSatsJitter++;
2547
                                }
2548
                                else
2549
                                {
2550
                                    _iSatsJitter = 0;
2551
                                    _iSatsLast = data[23];
2552
                                }
2553
 
2554
                                if (_iSatsJitter == 20)
2555
                                {
2556
                                    if (stbSatFixLostAnim != null && !_bAnimSatFixActive)
2557
                                    {
2558
                                        Dispatcher.Invoke(() => stbSatFixLostAnim.Begin());
2559
                                        _bAnimSatFixActive = true;
2560
                                    }
2561
                                    if (_bVoiceSatFixPlay && !_bVoiceSatFixActive)
2562
                                    {
2563
                                        _bVoiceSatFixActive = true;
2564
                                        ThreadPool.QueueUserWorkItem(new WaitCallback(_mediaPlayer), "Voice\\" + _voiceLanguage[_iVoiceIndex] + "\\SatFixLost.mp3");
2565
                                        //Thread th = new Thread(() => _mediaPlayer("Voice\\SatFixLost.mp3"));
2566
                                        //th.Start();
2567
                                    }
2568
 
2569
                                    _bSatFix = false;
2570
                                }
2571
                            }
2572
                        }
2573
 
2574
                        break;
2575
 
2576
                    case 15:
2577
                        //--------------------------------Waypoint index------------------------------------
2578
                        Dispatcher.Invoke((Action)(() => tbWPIndex.Text = data[13].ToString()));
2579
                        Dispatcher.Invoke((Action)(() => lblWPIndexNC.Content = data[13].ToString()));
2580
                        Dispatcher.Invoke((Action)(() => lblWPStatusIndexNC.Content = data[13].ToString()));
2581
                        if (data[13] > 0 && _wpIndex != data[13] - 1 && wpList.Count > data[13] - 1)
2582
                        {
2583
                            _setActiveWP(data[13] - 1);
2584
                            if ((OSDSTATUSFLAGS2 & 2) == 2)
2585
                                Dispatcher.Invoke(() =>
2586
                                {
2587
                                    DataGridRow row;
2588
                                    if (_wpIndex > -1)
2589
                                    {
2590
                                        row = (DataGridRow)dgvWP.ItemContainerGenerator.ContainerFromIndex(wpOffset[_wpIndex]);
2591
                                        row.Background = new SolidColorBrush(Colors.Transparent);
2592
                                        row.BorderBrush = new SolidColorBrush(Colors.Transparent);
2593
                                        row.BorderThickness = new Thickness(0);
2594
                                    }
2595
 
2596
                                    _wpIndex = data[13] - 1;
2597
                                    row = (DataGridRow)dgvWP.ItemContainerGenerator.ContainerFromIndex(wpOffset[_wpIndex]);
2598
                                    row.Background = new SolidColorBrush(Color.FromArgb(80, 0, 255, 100));
2599
                                    row.BorderBrush = new SolidColorBrush(Colors.SpringGreen);
2600
                                    row.BorderThickness = new Thickness(2);
2601
                                    dgvWP.UpdateLayout();
2602
                                });
2603
                            _wpIndex = data[13] - 1;
2604
                        }
2605
                        else
2606
                        {
2607
                            if ((data[13] == 0 || wpList.Count == 0) & MainMap.Markers.Contains(wpActiveMarker))
2608
                            {
2609
                                Dispatcher.Invoke(() => MainMap.Markers.Remove(wpActiveMarker));
2610
                                Dispatcher.Invoke(() =>
2611
                                {
2612
                                    DataGridRow row;
2613
                                    if (_wpIndex > -1 && data[13] == 0 && wpList.Count > _wpIndex)
2614
                                    {
2615
                                        row = (DataGridRow)dgvWP.ItemContainerGenerator.ContainerFromIndex(wpOffset[_wpIndex]);
2616
                                        row.Background = new SolidColorBrush(Colors.Transparent);
2617
                                        row.BorderBrush = new SolidColorBrush(Colors.Transparent);
2618
                                        row.BorderThickness = new Thickness(0);
2619
                                        _wpIndex = -1;
2620
                                    }
2621
                                });
2622
 
2623
                            }
2624
                        }
2625
                        //----------------Waypoints count----------------------
2626
                        Dispatcher.Invoke((Action)(() => tbWPCount.Text = data[14].ToString())); //Waypoints count
2627
                        Dispatcher.Invoke((Action)(() => lblWPCountNC.Content = data[14].ToString())); //Waypoints count
2628
                        Dispatcher.Invoke((Action)(() => lblWPStatusCountNC.Content = data[14].ToString())); //Waypoints count
2629
                        _wpCount = data[14];
2630
                        if(_wpCount > dtWaypoints.Rows.Count)
2631
                        {
2632
                            Log(LogMsgType.Warning, "The copter reports more waypoints than there are in the local list!");
2633
                        }
2634
 
2635
                        //---------------------------------Target hold time------------------------------
2636
                        Dispatcher.Invoke((Action)(() => lblWPHoldTime.Content = data[15].ToString() + " s"));
2637
                        Dispatcher.Invoke((Action)(() => tbWPStatusHoldTime.Text = data[15].ToString() + " s"));
2638
 
2639
                        break;
2640
 
2641
                    case 16:
2642
                        //--------------- Capacity used ------------------------
2643
                        i_16 = data[18];
2644
                        i_16 = (Int16)(i_16 << 8);
2645
                        iVal = data[17] + i_16;
2646
                        Dispatcher.Invoke((Action)(() => tbCapacity.Text = iVal.ToString() + " mAh"));
2647
                        Dispatcher.Invoke((Action)(() => tbTopCapacity.Text = iVal.ToString() + " mAh"));
2648
 
2649
                        //--------------- Heading compass ------------------------
2650
                        i_16 = data[21];
2651
                        iVal = 2 * i_16;
2652
                        Dispatcher.Invoke((Action)(() => tbHeadingCompass.Text = iVal.ToString() + " °"));
2653
                        if (_Simulate)
2654
                        {
2655
                            Dispatcher.Invoke(() => ArtHor.rotate = iVal);
2656
                            Dispatcher.Invoke(() => ((CustomMarkerCopter)(copter.Shape)).rotate = iVal);
2657
                        }
2658
 
2659
                        break;
2660
                    case 17:
2661
 
2662
                        break;
2663
                    case 18:
2664
 
2665
                        break;
2666
                    default:
2667
                        break;
2668
                }
2669
                //--------------------------------------------------------------------------------
2670
                //-----------------------------FC Status Flags-------------------------------
2671
                //--------------------------------------------------------------------------------
2672
                Dispatcher.Invoke((Action)(() => FC1_1.Background = ((OSDSTATUSFLAGS2 & 1) == 1) ? new SolidColorBrush(Colors.LightSeaGreen) : new SolidColorBrush(Colors.Transparent)));// FC_STATUS_MOTOR_RUN                                 0x01
2673
                Dispatcher.Invoke((Action)(() => FC1_2.Background = ((OSDSTATUSFLAGS2 & 2) == 2) ? new SolidColorBrush(Colors.LightSeaGreen) : new SolidColorBrush(Colors.Transparent)));// FC_STATUS_FLY                                       0x02
2674
                Dispatcher.Invoke((Action)(() => FC1_3.Background = ((OSDSTATUSFLAGS1 & 4) == 4) ? new SolidColorBrush(Colors.LightSeaGreen) : new SolidColorBrush(Colors.Transparent)));// FC_STATUS_CALIBRATE                                 0x04
2675
                Dispatcher.Invoke((Action)(() => FC1_4.Background = ((OSDSTATUSFLAGS2 & 8) == 8) ? new SolidColorBrush(Colors.LightSeaGreen) : new SolidColorBrush(Colors.Transparent)));// FC_STATUS_START                                     0x08
2676
                Dispatcher.Invoke((Action)(() => FC1_5.Background = ((OSDSTATUSFLAGS2 & 16) == 16) ? new SolidColorBrush(Colors.LightCoral) : new SolidColorBrush(Colors.Transparent)));// FC_STATUS_EMERGENCY_LANDING          0x10
2677
                Dispatcher.Invoke((Action)(() => FC1_6.Background = ((OSDSTATUSFLAGS1 & 32) == 32) ? new SolidColorBrush(Colors.LightCoral) : new SolidColorBrush(Colors.Transparent)));// FC_STATUS_LOWBAT                                 0x20
2678
 
2679
                Dispatcher.Invoke((Action)(() => FC2_1.Background = ((OSDSTATUSFLAGS1 & 1) == 1) ? new SolidColorBrush(Colors.LightSeaGreen) : new SolidColorBrush(Colors.Transparent)));// FC_STATUS2_CAREFREE                         0x01
2680
                Dispatcher.Invoke((Action)(() => FC2_2.Background = ((OSDSTATUSFLAGS1 & 2) == 2) ? new SolidColorBrush(Colors.LightSeaGreen) : new SolidColorBrush(Colors.Transparent)));// FC_STATUS2_ALTITUDE_CONTROL                 0x02
2681
                Dispatcher.Invoke((Action)(() => FC2_3.Background = ((OSDSTATUSFLAGS2 & 4) == 4) ? new SolidColorBrush(Colors.LightCoral) : new SolidColorBrush(Colors.Transparent)));// FC_STATUS2_RC_FAILSAVE_ACTIVE                  0x04
2682
                Dispatcher.Invoke((Action)(() => FC2_4.Background = ((OSDSTATUSFLAGS1 & 8) == 8) ? new SolidColorBrush(Colors.LightSeaGreen) : new SolidColorBrush(Colors.Transparent)));// FC_STATUS2_OUT1_ACTIVE                              0x08
2683
                Dispatcher.Invoke((Action)(() => FC2_5.Background = ((OSDSTATUSFLAGS1 & 16) == 16) ? new SolidColorBrush(Colors.LightSeaGreen) : new SolidColorBrush(Colors.Transparent)));// FC_STATUS2_OUT2_ACTIVE                            0x10
2684
                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
2685
                Dispatcher.Invoke((Action)(() => FC2_7.Background = ((OSDSTATUSFLAGS2 & 64) == 64) ? new SolidColorBrush(Colors.LightSeaGreen) : new SolidColorBrush(Colors.Transparent)));// FC_STATUS2_AUTO_STARTING                  0x40
2686
                Dispatcher.Invoke((Action)(() => FC2_8.Background = ((OSDSTATUSFLAGS2 & 128) == 128) ? new SolidColorBrush(Colors.LightSeaGreen) : new SolidColorBrush(Colors.Transparent)));// FC_STATUS2_AUTO_LANDING                 0x80
2687
 
2688
                //Sidebar StatusSymbols
2689
                Dispatcher.Invoke((Action)(() => tbSideBarStatusMotors.Background = ((OSDSTATUSFLAGS2 & 1) == 1) ? new SolidColorBrush(Colors.LightSeaGreen) : new SolidColorBrush(Colors.Transparent)));// FC_STATUS_MOTOR_RUN                                         0x01
2690
                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
2691
                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
2692
 
2693
                Dispatcher.Invoke((Action)(() => tbSideBarStatusCF.Background = ((OSDSTATUSFLAGS1 & 1) == 1) ? new SolidColorBrush(Colors.LightSeaGreen) : new SolidColorBrush(Colors.Transparent)));// FC_STATUS2_CAREFREE                                 0x01
2694
                Dispatcher.Invoke((Action)(() => tbSideBarStatusCF.Foreground = ((OSDSTATUSFLAGS1 & 1) == 1) ? new SolidColorBrush(Colors.White) : new SolidColorBrush(Color.FromArgb(255, 211, 210, 210))));// FC_STATUS2_CAREFREE                     0x01
2695
                Dispatcher.Invoke((Action)(() => tbSideBarStatusCF.BorderBrush = ((OSDSTATUSFLAGS1 & 1) == 1) ? new SolidColorBrush(Colors.White) : new SolidColorBrush(Color.FromArgb(255, 211, 210, 210))));// FC_STATUS2_CAREFREE                    0x01
2696
 
2697
                Dispatcher.Invoke((Action)(() => tbSideBarStatusEmergencyLanding.Background = ((OSDSTATUSFLAGS2 & 16) == 16) ? new SolidColorBrush(Colors.LightCoral) : new SolidColorBrush(Colors.Transparent)));// FC_STATUS_EMERGENCY_LANDING        0x10
2698
                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
2699
                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
2700
 
2701
                Dispatcher.Invoke((Action)(() => tbSideBarStatusAC.Background = ((OSDSTATUSFLAGS1 & 2) == 2) ? new SolidColorBrush(Colors.LightSeaGreen) : new SolidColorBrush(Colors.Transparent)));// FC_STATUS2_ALTITUDE_CONTROL                             0x02
2702
                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
2703
                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
2704
 
2705
                _bAirborne = (OSDSTATUSFLAGS2 & 2) == 2 ? true : false;
2706
            }
2707
        }
2708
        public class OSD_Base_Data_t
2709
        {
2710
            byte[] data;
2711
 
2712
            public OSD_Base_Data_t(byte [] _data)
2713
            {
2714
                data = _data;
2715
            }
2716
 
2717
            public PointLatLng Pos()
2718
            {
2719
                PointLatLng p = new PointLatLng();
2720
                int i_32, iVal;
2721
                double d;
2722
 
2723
                i_32 = data[4];
2724
                iVal = i_32 << 24;
2725
                i_32 = data[3];
2726
                iVal += i_32 << 16;
2727
                i_32 = data[2];
2728
                iVal += i_32 << 8;
2729
                iVal += data[1];
2730
                d = (double)iVal / Math.Pow(10, 7);
2731
                p.Lng = d;
2732
 
2733
                i_32 = data[8];
2734
                iVal = i_32 << 24;
2735
                i_32 = data[7];
2736
                iVal += i_32 << 16;
2737
                i_32 = data[6];
2738
                iVal += i_32 << 8;
2739
                iVal += data[5];
2740
                d = (double)iVal / Math.Pow(10, 7);
2741
                p.Lat = d;
2742
 
2743
                return p;
2744
 
2745
            }
2746
 
2747
            public int Height()
2748
            {
2749
                int i_32, iVal;
2750
                i_32 = data[10];
2751
                iVal = i_32 << 8;
2752
                iVal += data[9];
2753
 
2754
                return iVal;
2755
            }
2756
 
2757
            public double Speed()
2758
            {
2759
                if (data.Length > 11)
2760
                    return (double)data[11]/10;
2761
                else return 0;
2762
            }
2763
 
2764
            public byte OSDSTATUSFLAGS1()
2765
            {
2766
                if (data.Length > 12)
2767
                    return data[12];
2768
                else return 0;
2769
            }
2770
            public byte OSDSTATUSFLAGS2()
2771
            {
2772
                if (data.Length > 13)
2773
                    return data[13];
2774
                else return 0;
2775
            }
2776
        }
2777
        void _processNCData(byte[] data)
2778
        {
2779
            int i_32, i_16, iVal;
2780
            double d;
2781
 
2782
            //----------------------------POSITION------------------------------------
2783
            i_32 = data[4];
2784
            iVal = i_32 << 24;
2785
            i_32 = data[3];
2786
            iVal += i_32 << 16;
2787
            i_32 = data[2];
2788
            iVal += i_32 << 8;
2789
            iVal += data[1];
2790
            d = (double)iVal / Math.Pow(10, 7);
2791
            Dispatcher.Invoke(() => { drGPX[2] = d; });
2792
 
2793
            PointLatLng p = new PointLatLng();
2794
 
2795
            p.Lng = d;
2796
          //  lblNCGPSLong.Invoke((Action)(() => lblNCGPSLong.Text = d.ToString("0.######°"))); //GPS-Position: Longitude in decimal degree
2797
            //lblNCGPSLong.Invoke((Action)(() => lblNCGPSLong.Text = _convertDegree(d))); //GPS-Position: Longitude in minutes, seconds
2798
 
2799
            i_32 = data[8];
2800
            iVal = i_32 << 24;
2801
            i_32 = data[7];
2802
            iVal += i_32 << 16;
2803
            i_32 = data[6];
2804
            iVal += i_32 << 8;
2805
            iVal += data[5];
2806
            d = (double)iVal / Math.Pow(10, 7);
2807
            Dispatcher.Invoke(() => { drGPX[1] = d; });
2808
            Dispatcher.Invoke(() => { drGPX[4] = DateTime.UtcNow.ToString("u", System.Globalization.CultureInfo.InvariantCulture); }); //2011-01-14T01:59:01Z });
2809
            p.Lat = d;
2810
 
2811
            //---------------------------SATS-------------------------------------------------
2812
            if (data[50] > 4)//if more than 4 sats in use . otherwise the map would jump and scroll insane at beginning
2813
            {
2814
                _bSatFix = true; _iSatsJitter = 0; _bVoiceSatFixActive = false;
2815
                if(_bAutoHome && !_bFirstSatFix)
2816
                {
2817
                    if (_iFirstSatFix < 3)
2818
                        _iFirstSatFix++;
2819
                    else
2820
                    {
2821
                        _bFirstSatFix = true;
2822
                        Dispatcher.Invoke(() => _setHomePos());
2823
                    }
2824
                }
2825
                if (stbSatFixLostAnim != null && _bAnimSatFixActive)
2826
                {
2827
                    Dispatcher.Invoke(() => stbSatFixLostAnim.Stop());
2828
                    _bAnimSatFixActive = false;
2829
                }
2830
                if (!_bFollowCopter)
2831
                {
2832
                    _setCopterData(p);
2833
                    if (!MainMap.ViewArea.Contains(p))
2834
                        Dispatcher.Invoke(() => MainMap.Position = p);
2835
 
2836
                }
2837
                else
2838
                    Dispatcher.Invoke(() => MainMap.Position = p);
2839
            }
2840
            else
2841
            {
2842
                if(_bSatFix)
2843
                {
2844
                    if (data[50] == _iSatsLast)
2845
                    {
2846
                        if (_iSatsJitter < 20) _iSatsJitter++;
2847
                    }
2848
                    else
2849
                    {
2850
                        _iSatsJitter = 0;
2851
                        _iSatsLast = data[50];
2852
                    }
2853
 
2854
                    if (_iSatsJitter == 20)
2855
                    {
2856
                        if (stbSatFixLostAnim != null && !_bAnimSatFixActive)
2857
                        {
2858
                            Dispatcher.Invoke(() => stbSatFixLostAnim.Begin());
2859
                            _bAnimSatFixActive = true;
2860
                        }
2861
                        if (_bVoiceSatFixPlay && !_bVoiceSatFixActive)
2862
                        {
2863
                            _bVoiceSatFixActive = true;
2864
                            ThreadPool.QueueUserWorkItem(new WaitCallback(_mediaPlayer), "Voice\\" + _voiceLanguage[_iVoiceIndex] + "\\SatFixLost.mp3");
2865
                            //Thread th = new Thread(() => _mediaPlayer("Voice\\SatFixLost.mp3"));
2866
                            //th.Start();
2867
                        }
2868
 
2869
                        _bSatFix = false;
2870
                    }
2871
                }
2872
            }
2873
 
2874
            //--------------------------Distance to next WP--------------------------------
2875
            i_16 = data[28];
2876
            i_16 = (Int16)(i_16 << 8);
2877
            iVal = data[27] + i_16;
2878
            Dispatcher.Invoke((Action)(() => tbWP.Text = ((double)iVal / (double)10).ToString("0.0 m")));
2879
            Dispatcher.Invoke((Action)(() => lblWPRouteDistanceWP.Content = ((double)iVal / (double)10).ToString("0.0 m")));
2880
            Dispatcher.Invoke((Action)(() => tbWPStatusDistanceWP.Text = ((double)iVal / (double)10).ToString("0.0 m")));
2881
 
2882
            //-------------------------Distance to HP set by GPS on----------------------------------
2883
            i_16 = data[45];
2884
            i_16 = (Int16)(i_16 << 8);
2885
            iVal = data[44] + i_16;
2886
            Dispatcher.Invoke((Action)(() => tbHP.Text = ((double)iVal / (double)10).ToString("0.0 m")));
2887
 
2888
            //--------------------------------Waypoint index------------------------------------
2889
            Dispatcher.Invoke((Action)(() => tbWPIndex.Text = data[48].ToString()));
2890
            Dispatcher.Invoke((Action)(() => lblWPIndexNC.Content = data[48].ToString()));
2891
            Dispatcher.Invoke((Action)(() => lblWPStatusIndexNC.Content = data[48].ToString()));
2892
            if(data[48] > 0 && _wpIndex != data[48] -1 && wpList.Count >= data[48] -1)
2893
            {
2894
                _setActiveWP(data[48]- 1);
2895
                if((data[67] & 2) == 2)
2896
                    Dispatcher.Invoke(() => {
2897
                        DataGridRow row;
2898
                        if (_wpIndex > -1)
2899
                        {
2900
                            row = (DataGridRow)dgvWP.ItemContainerGenerator.ContainerFromIndex(wpOffset[_wpIndex]);
2901
                            row.Background = new SolidColorBrush(Colors.Transparent);
2902
                            row.BorderBrush = new SolidColorBrush(Colors.Transparent);
2903
                            row.BorderThickness = new Thickness(0);
2904
                        }
2905
 
2906
                        _wpIndex = data[48] - 1;
2907
                        row = (DataGridRow)dgvWP.ItemContainerGenerator.ContainerFromIndex(wpOffset[_wpIndex]);
2908
                        row.Background = new SolidColorBrush(Color.FromArgb(80, 0, 255, 100));
2909
                        row.BorderBrush = new SolidColorBrush(Colors.SpringGreen);
2910
                        row.BorderThickness = new Thickness(2);
2911
                        dgvWP.UpdateLayout();
2912
                    });
2913
                _wpIndex = data[48]- 1;
2914
            }
2915
            else
2916
            {
2917
                if ((data[48] == 0 || wpList.Count == 0) & MainMap.Markers.Contains(wpActiveMarker))
2918
                {
2919
                    Dispatcher.Invoke(() => MainMap.Markers.Remove(wpActiveMarker));
2920
                    Dispatcher.Invoke(() =>
2921
                    {
2922
                        DataGridRow row;
2923
                        if (_wpIndex > -1 && data[48] == 0 && wpList.Count > _wpIndex)
2924
                        {
2925
                            row = (DataGridRow)dgvWP.ItemContainerGenerator.ContainerFromIndex(wpOffset[_wpIndex]);
2926
                            row.Background = new SolidColorBrush(Colors.Transparent);
2927
                            row.BorderBrush = new SolidColorBrush(Colors.Transparent);
2928
                            row.BorderThickness = new Thickness(0);
2929
                            _wpIndex = -1;
2930
                        }
2931
                    });
2932
 
2933
                }
2934
            }
2935
            //----------------Waypoints count----------------------
2936
            Dispatcher.Invoke((Action)(() => tbWPCount.Text = data[49].ToString())); //Waypoints count
2937
            Dispatcher.Invoke((Action)(() => lblWPCountNC.Content = data[49].ToString())); //Waypoints count
2938
            Dispatcher.Invoke((Action)(() => lblWPStatusCountNC.Content = data[49].ToString())); //Waypoints count
2939
            _wpCount = data[49];
2940
            //-------------------Satellites----------------------------------
2941
            Dispatcher.Invoke((Action)(() => tbTopSats.Text = data[50].ToString()));
2942
 
2943
            //--------------- Capacity used ------------------------
2944
            i_16 = data[81];
2945
            i_16 = (Int16)(i_16 << 8);
2946
            iVal = data[80] + i_16;
2947
            Dispatcher.Invoke((Action)(() => tbCapacity.Text = iVal.ToString() + " mAh"));
2948
            Dispatcher.Invoke((Action)(() => tbTopCapacity.Text = iVal.ToString() + " mAh"));
2949
 
2950
            //--------------- Ground speed ------------------------
2951
            i_16 = data[59];
2952
            i_16 = (Int16)(i_16 << 8);
2953
            iVal = data[58] + i_16;
2954
            Dispatcher.Invoke((Action)(() => tbNCGrSpeed.Text = ((double)(iVal)/100).ToString("0.00 m/s")));
2955
            if(_Simulate)
2956
                Dispatcher.Invoke((Action)(() => tbTopSpeed.Text = ((double)(iVal)/100).ToString("0.00 m/s")));
2957
 
2958
            //--------------- Heading north ------------------------
2959
            //i_16 = data[61];
2960
            //i_16 = (Int16)(i_16 << 8);
2961
            //iVal = data[60] + i_16;
2962
            //Dispatcher.Invoke((Action)(() => tbHeadingNorth.Text = iVal.ToString() + " °"));
2963
 
2964
            //--------------- Heading compass ------------------------
2965
            i_16 = data[63];
2966
            i_16 = (Int16)(i_16 << 8);
2967
            iVal = data[62] + i_16;
2968
            Dispatcher.Invoke((Action)(() => tbHeadingCompass.Text = iVal.ToString() + " °"));
2969
            if (_Simulate)
2970
            {
2971
                Dispatcher.Invoke(() => ArtHor.rotate = iVal);
2972
                Dispatcher.Invoke(() => ((CustomMarkerCopter)(copter.Shape)).rotate = iVal);
2973
            }
2974
            //--------------- Flying time ------------------------
2975
            i_16 = data[56];
2976
            i_16 = (Int16)(i_16 << 8);
2977
            iVal = data[55] + i_16;
2978
            TimeSpan t = TimeSpan.FromSeconds(iVal);
2979
            string Text = t.Hours.ToString("D2") + ":" + t.Minutes.ToString("D2") + ":" + t.Seconds.ToString("D2");
2980
            Dispatcher.Invoke((Action)(() => tbFTime.Text = Text.ToString()));
2981
            Dispatcher.Invoke((Action)(() => tbTopFTime.Text = Text.ToString()));
2982
 
2983
            //--------------- RC quality ------------------------
2984
            Dispatcher.Invoke((Action)(() => tbRCQ.Text = data[66].ToString()));
2985
            Dispatcher.Invoke((Action)(() => tbTopRC.Text = data[66].ToString()));
2986
 
2987
            if(data[66] > _iThresholdRC)
2988
            {
2989
                _iRCLevelJitter = 0; _bVoiceRCLevelActive = false;
2990
                if (stbRCLevelAnim != null && _bAnimRCLevelActive)
2991
                {
2992
                    Dispatcher.Invoke(() => stbRCLevelAnim.Stop());
2993
                    _bAnimRCLevelActive = false;
2994
                }
2995
            }
2996
            else
2997
            {
2998
                if (_iRCLevelJitter < 20) _iRCLevelJitter++;
2999
                if (_iRCLevelJitter == 20)
3000
                {
3001
                    if (stbRCLevelAnim != null && !_bAnimRCLevelActive)
3002
                    {
3003
                        Dispatcher.Invoke(() => stbRCLevelAnim.Begin());
3004
                        _bAnimRCLevelActive = true;
3005
                    }
3006
                    if (_bVoiceRCLevelPlay && !_bVoiceRCLevelActive)
3007
                    {
3008
                        _bVoiceRCLevelActive = true;
3009
                        ThreadPool.QueueUserWorkItem(new WaitCallback(_mediaPlayer), "Voice\\" + _voiceLanguage[_iVoiceIndex] + "\\MagneticField.mp3");
3010
                        //Thread th = new Thread(() => _mediaPlayer("Voice\\RCLevel.mp3"));
3011
                        //th.Start();
3012
                    }
3013
                        _iRCLevelJitter++;
3014
                }
3015
            }
3016
 
3017
            //-------------------------Waypoint max range (by license)------------------------------
3018
            if(dWPMaxRange != (double)data[70])
3019
            {
3020
                dWPMaxRange = (double)data[70];
3021
                if (home != null && checkBoxShowWPMaxRange.IsChecked == true)
3022
                {
3023
                    if (cWPBound != null && cWPBound.Tag != null)
3024
                        MainMap.Markers.Remove(cWPBound.Tag as GMapMarker);
3025
 
3026
                    createCircle(home.Position, dWPMaxRange);
3027
                    Dispatcher.Invoke(() =>
3028
                    {
3029
                        if (comboBoxWPMaxRangeColor.SelectionBoxItem != null)
3030
                        {
3031
                            string s = _colors[comboBoxWPMaxRangeColor.SelectedIndex];
3032
                            cWPBound.setColor(s);
3033
                        }
3034
                    });
3035
                }
3036
                Dispatcher.Invoke((Action)(() => tbWPMaxRange.Text = data[70].ToString() + " m"));
3037
            }
3038
            //---------------------------------Target hold time------------------------------
3039
            Dispatcher.Invoke((Action)(() => lblWPHoldTime.Content = data[73].ToString()+ " s"));
3040
            Dispatcher.Invoke((Action)(() => tbWPStatusHoldTime.Text = data[73].ToString()+ " s"));
3041
 
3042
            //--------------- NC Error ------------------------
3043
            Dispatcher.Invoke((Action)(() => tbNCErr.Text = data[69].ToString()));  //NC Errornumber
3044
            if (data[69] > 0)
3045
                _readNCError();
3046
            if (data[69] > 0 & data[69] < 44)
3047
                ErrorLog(LogMsgType.Error," NC Error [" + data[69].ToString() + "]: ",NC_Error_Link[data[69]], NC_Error[data[69]]);
3048
            //else
3049
            //    if (_bErrorLog) _clearErrorLog("NC Error");
3050
 
3051
            //--------------------------------------------------------------------------------
3052
            //-----------------------------FC / NC Status Flags-------------------------------
3053
            //--------------------------------------------------------------------------------
3054
            Dispatcher.Invoke((Action)(() => FC1_1.Background = ((data[67] & 1) ==1) ? new SolidColorBrush(Colors.LightSeaGreen) : new SolidColorBrush(Colors.Transparent)));// FC_STATUS_MOTOR_RUN                             0x01
3055
            Dispatcher.Invoke((Action)(() => FC1_2.Background = ((data[67] & 2) ==2) ? new SolidColorBrush(Colors.LightSeaGreen) : new SolidColorBrush(Colors.Transparent)));// FC_STATUS_FLY                                   0x02
3056
            Dispatcher.Invoke((Action)(() => FC1_3.Background = ((data[67] & 4) ==4) ? new SolidColorBrush(Colors.LightSeaGreen) : new SolidColorBrush(Colors.Transparent)));// FC_STATUS_CALIBRATE                             0x04
3057
            Dispatcher.Invoke((Action)(() => FC1_4.Background = ((data[67] & 8) ==8) ? new SolidColorBrush(Colors.LightSeaGreen) : new SolidColorBrush(Colors.Transparent)));// FC_STATUS_START                                 0x08
3058
            Dispatcher.Invoke((Action)(() => FC1_5.Background = ((data[67] & 16) ==16) ? new SolidColorBrush(Colors.LightCoral) : new SolidColorBrush(Colors.Transparent)));// FC_STATUS_EMERGENCY_LANDING                      0x10
3059
            Dispatcher.Invoke((Action)(() => FC1_6.Background = ((data[67] & 32) ==32) ? new SolidColorBrush(Colors.LightCoral) : new SolidColorBrush(Colors.Transparent)));// FC_STATUS_LOWBAT                         0x20
3060
 
3061
            Dispatcher.Invoke((Action)(() => FC2_1.Background = ((data[74] & 1) ==1) ? new SolidColorBrush(Colors.LightSeaGreen) : new SolidColorBrush(Colors.Transparent)));// FC_STATUS2_CAREFREE                             0x01
3062
            Dispatcher.Invoke((Action)(() => FC2_2.Background = ((data[74] & 2) ==2) ? new SolidColorBrush(Colors.LightSeaGreen) : new SolidColorBrush(Colors.Transparent)));// FC_STATUS2_ALTITUDE_CONTROL                     0x02
3063
            Dispatcher.Invoke((Action)(() => FC2_3.Background = ((data[74] & 4) ==4) ? new SolidColorBrush(Colors.LightCoral) : new SolidColorBrush(Colors.Transparent)));// FC_STATUS2_RC_FAILSAVE_ACTIVE                      0x04
3064
            Dispatcher.Invoke((Action)(() => FC2_4.Background = ((data[74] & 8) ==8) ? new SolidColorBrush(Colors.LightSeaGreen) : new SolidColorBrush(Colors.Transparent)));// FC_STATUS2_OUT1_ACTIVE                          0x08
3065
            Dispatcher.Invoke((Action)(() => FC2_5.Background = ((data[74] & 16) ==16) ? new SolidColorBrush(Colors.LightSeaGreen) : new SolidColorBrush(Colors.Transparent)));// FC_STATUS2_OUT2_ACTIVE                        0x10
3066
            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
3067
            Dispatcher.Invoke((Action)(() => FC2_7.Background = ((data[74] & 64) ==64) ? new SolidColorBrush(Colors.LightSeaGreen) : new SolidColorBrush(Colors.Transparent)));// FC_STATUS2_AUTO_STARTING                              0x40
3068
            Dispatcher.Invoke((Action)(() => FC2_8.Background = ((data[74] & 128) ==128) ? new SolidColorBrush(Colors.LightSeaGreen) : new SolidColorBrush(Colors.Transparent)));// FC_STATUS2_AUTO_LANDING                             0x80
3069
 
3070
            Dispatcher.Invoke((Action)(() => NC1_2.Background = ((data[68] & 2) == 2) ? new SolidColorBrush(Colors.LightSeaGreen) : new SolidColorBrush(Colors.Transparent)));// NC_FLAG_PH                                     0x02
3071
            Dispatcher.Invoke((Action)(() => NC1_3.Background = ((data[68] & 4) == 4) ? new SolidColorBrush(Colors.LightSeaGreen) : new SolidColorBrush(Colors.Transparent)));// NC_FLAG_CH                                     0x04
3072
            Dispatcher.Invoke((Action)(() => NC1_4.Background = ((data[68] & 8) == 8) ? new SolidColorBrush(Colors.LightCoral) : new SolidColorBrush(Colors.Transparent)));// NC_FLAG_RANGE_LIMIT                               0x08
3073
            Dispatcher.Invoke((Action)(() => NC1_5.Background = ((data[68] & 16) == 16) ? new SolidColorBrush(Colors.LightCoral) : new SolidColorBrush(Colors.Transparent)));// NC_FLAG_NOSERIALLINK                            0x10
3074
            Dispatcher.Invoke((Action)(() => NC1_6.Background = ((data[68] & 32) == 32) ? new SolidColorBrush(Colors.LightSeaGreen) : new SolidColorBrush(Colors.Transparent)));// NC_FLAG_TARGET_REACHED                               0x20
3075
            Dispatcher.Invoke((Action)(() => NC1_7.Background = ((data[68] & 64) == 64) ? new SolidColorBrush(Colors.DodgerBlue) : new SolidColorBrush(Colors.Transparent)));// NC_FLAG_MANUAL_CONTROL                          0x40
3076
            Dispatcher.Invoke((Action)(() => NC1_8.Background = ((data[68] & 128) == 128) ? new SolidColorBrush(Colors.LightSeaGreen) : new SolidColorBrush(Colors.Transparent)));// NC_FLAG_GPS_OK                                     0x80
3077
 
3078
            //Sidebar StatusSymbols
3079
            Dispatcher.Invoke((Action)(() => tbSideBarStatusMotors.Background = ((data[67] & 1) ==1) ? new SolidColorBrush(Colors.LightSeaGreen) : new SolidColorBrush(Colors.Transparent)));// FC_STATUS_MOTOR_RUN                             0x01
3080
            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
3081
            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
3082
 
3083
            Dispatcher.Invoke((Action)(() => tbSideBarStatusCF.Background = ((data[74] & 1) == 1) ? new SolidColorBrush(Colors.LightSeaGreen) : new SolidColorBrush(Colors.Transparent)));// FC_STATUS2_CAREFREE                                0x01
3084
            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
3085
            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
3086
 
3087
            Dispatcher.Invoke((Action)(() => tbSideBarStatusEmergencyLanding.Background = ((data[67] & 16) == 16) ? new SolidColorBrush(Colors.LightCoral) : new SolidColorBrush(Colors.Transparent)));// FC_STATUS_EMERGENCY_LANDING                   0x10
3088
            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
3089
            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
3090
 
3091
            Dispatcher.Invoke((Action)(() => tbSideBarStatusAC.Background = ((data[74] & 2) ==2) ? new SolidColorBrush(Colors.LightSeaGreen) : new SolidColorBrush(Colors.Transparent)));// FC_STATUS2_ALTITUDE_CONTROL                         0x02
3092
            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
3093
            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
3094
 
3095
            Dispatcher.Invoke((Action)(() => tbSideBarStatusPH.Text = ((data[68] & 4) == 4) ? "CH" : "PH"));// NC_FLAG_PH 0x02 / NC_FLAG_CH 0x04
3096
            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
3097
            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
3098
            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
3099
 
3100
            _bAirborne = (data[67] & 2) == 2 ? true : false;
3101
        }
3102
        /// <summary>
3103
        /// Navi-Ctrl WP data struct 'X'
3104
        /// called by index
3105
        /// </summary>
3106
        /// <param name="data">the received byte array to process</param>
3107
        void _processWPData(byte[] data)
3108
        {
3109
            _iWPCount = data[0];
3110
            _bGetWPCount = false;
3111
            if (data.Length >= 28)
3112
            {
3113
                Dispatcher.Invoke(() => lblWPIndex.Content = data[1].ToString());
3114
                Dispatcher.Invoke(() => lblWPCount.Content = data[0].ToString());
3115
                if (_bGetWP)
3116
                {
3117
                    if (data[1] == 1)
3118
                    {
3119
                        Dispatcher.Invoke(() =>
3120
                        {
3121
                            wpList.Clear();
3122
                            _clearMapMarkers(typeof(CustomMarkerWP));
3123
                            if (mRouteWP != null)
3124
                                MainMap.Markers.Remove(mRouteWP);
3125
                            if (wpActiveMarker != null)
3126
                                MainMap.Markers.Remove(wpActiveMarker);
3127
                            lblWPRouteDistance.Content = "0 m";
3128
                            dtWaypoints.Rows.Clear();
3129
                            _wpEdit = -1;_wpIndex = -1;
3130
                            wpOffset.Clear();
3131
                        });
3132
                    }
3133
                    DataRow dr = dtWaypoints.NewRow();
3134
                    dr = Waypoints.toDataRow(data, dr);
3135
                    dtWaypoints.Rows.Add(dr);
3136
                    _createWP(new PointLatLng((double)dr[3], (double)dr[4]), (string)dr[2], (int)dr[1],(int)data[1]-1);
3137
                    Dispatcher.Invoke(() => dgvWP.Items.Refresh());
3138
                    Dispatcher.Invoke(() => _iWPIndex = data[1]);
3139
                    if (data[1] == data[0])
3140
                    {
3141
                        _bGetWP = false;
3142
                        _routeUpdate();
3143
                    }
3144
 
3145
                }
3146
            }
3147
            else
3148
            {
3149
                Dispatcher.Invoke(() => lblWPIndex.Content = 0);
3150
                Dispatcher.Invoke(() => lblWPCount.Content = 0);
3151
            }
3152
        }
3153
        /// <summary>
3154
        /// OSD Menue 'L'
3155
        /// single page called by pagenumber
3156
        /// no autoupdate
3157
        /// </summary>
3158
        /// <param name="data">the received byte array to process</param>
3159
        void _processOSDSingle(byte[] data)
3160
        {
3161
            if (data.Length == 84)
3162
            {
3163
                string sMessage = "";
3164
                iOSDPage = data[0];
3165
                iOSDMax = data[1];
3166
                if (cbOSD.Items.Count != iOSDMax) _initOSDCB();
3167
                sMessage = new string(ASCIIEncoding.ASCII.GetChars(data, 2, data.Length - 4));
3168
                OSD(LogMsgType.Incoming, sMessage.Substring(0, 20)+ "\r", true);
3169
                OSD(LogMsgType.Incoming, sMessage.Substring(20, 20)+ "\r", false);
3170
                OSD(LogMsgType.Incoming, sMessage.Substring(40, 20)+ "\r", false);
3171
                OSD(LogMsgType.Incoming, sMessage.Substring(60, 20), false);
3172
                Dispatcher.Invoke(() => { cbOSD.SelectedValue = iOSDPage; });
3173
              //  lblOSDPageNr.Invoke((Action)(() => lblOSDPageNr.Text = iOSDPage.ToString("[0]")));
3174
 
3175
            }
3176
            //else
3177
            //    OSD(LogMsgType.Incoming, "Wrong length: " + data.Length + " (should be 84)");
3178
 
3179
        }
3180
        /// <summary>
3181
        /// OSD Menue 'H'
3182
        /// called by keys (0x01,0x02,0x03,0x04)
3183
        /// autoupdate
3184
        /// </summary>
3185
        /// <param name="data">the received byte array to process</param>
3186
        void _processOSDAuto(byte[] data)
3187
        {
3188
            if (data.Length == 81)
3189
            {
3190
                string sMessage = "";
3191
                sMessage = new string(ASCIIEncoding.ASCII.GetChars(data, 0, data.Length - 1));
3192
                OSD(LogMsgType.Incoming, sMessage.Substring(0, 20)+ "\r", true);
3193
                OSD(LogMsgType.Incoming, sMessage.Substring(20, 20)+ "\r", false);
3194
                OSD(LogMsgType.Incoming, sMessage.Substring(40, 20)+ "\r", false);
3195
                OSD(LogMsgType.Incoming, sMessage.Substring(60, 20), false);
3196
 
3197
            }
3198
            //else
3199
            //    OSD(LogMsgType.Incoming, "Wrong length: " + data.Length + " (should be 81)");
3200
        }
3201
 
3202
        #endregion processing received data
3203
 
3204
        #region controller messages
3205
        /// <summary> send message to controller to request data
3206
        /// for detailed info see http://wiki.mikrokopter.de/en/SerialProtocol/
3207
        /// </summary>
3208
        /// <param name="CMDID"> the command ID </param>
3209
        /// <param name="address"> the address of the controller: 0-any, 1-FC, 2-NC </param>
3210
        private void _sendControllerMessage(char CMDID, byte address)
3211
        {
3212
            if (serialPortCtrl.Port.IsOpen)
3213
            {
3214
                Stream serialStream = serialPortCtrl.Port.BaseStream;
3215
                byte[] bytes = FlightControllerMessage.CreateMessage(CMDID, address);
3216
                serialStream.Write(bytes, 0, bytes.Length);
3217
 
3218
            }
3219
            else
3220
                Log(LogMsgType.Error, "NOT CONNECTED!");
3221
        }
3222
        /// <summary> send message to controller to request data
3223
        /// for detailed info see http://wiki.mikrokopter.de/en/SerialProtocol/
3224
        /// </summary>
3225
        /// <param name="CMDID"> the command ID </param>
3226
        /// <param name="address"> the address of the controller: 0-any, 1-FC, 2-NC </param>
3227
        /// <param name="data"> additional data for the request</param>
3228
        private void _sendControllerMessage(char CMDID, byte address, byte[] data)
3229
        {
3230
            if (serialPortCtrl.Port.IsOpen)
3231
            {
3232
                Stream serialStream = serialPortCtrl.Port.BaseStream;
3233
                byte[] bytes = FlightControllerMessage.CreateMessage(CMDID, address, data);
3234
                serialStream.Write(bytes, 0, bytes.Length);
3235
 
3236
            }
3237
            else
3238
                Log(LogMsgType.Error, "NOT CONNECTED!");
3239
        }
3240
 
3241
        /// <summary>
3242
        /// start/stop continous polling of controller values
3243
        /// </summary>
3244
        /// <param name="b">start/stop switch</param>
3245
        void _readCont(bool b)
3246
        {
3247
            bReadContinously = b;
3248
            if (bReadContinously)
3249
            {
3250
                if (_debugDataAutorefresh) { _readDebugData(true); Thread.Sleep(10); }
3251
                if (_blctrlDataAutorefresh) { _readBLCtrl(true); Thread.Sleep(10); }
3252
                if (_navCtrlDataAutorefresh && _iCtrlAct == 2) { _readNavData(true); Thread.Sleep(10); }
3253
                if (_OSDAutorefresh) { _OSDMenueAutoRefresh(); Thread.Sleep(10); }
3254
                // Dispatcher.Invoke((Action)(() => rctConnection.Fill = Brushes.LightGreen));
3255
                Dispatcher.Invoke(() => imageConn.Source = new BitmapImage(new Uri("Images/Data_G.png", UriKind.Relative)));
3256
            }
3257
            else
3258
            {
3259
                // Dispatcher.Invoke((Action)(() => rctConnection.Fill = Brushes.LightGray));
3260
                Dispatcher.Invoke(() => imageConn.Source = new BitmapImage(new Uri("Images/Data_W.png", UriKind.Relative)));
3261
                _bConnErr = false;
3262
            }
3263
            _iLifeCounter = 0;
3264
        }
3265
 
3266
        private void _getVersion()
3267
        {
3268
            _sendControllerMessage('v', 0);
3269
        }
3270
        /// <summary>
3271
        /// get FC version struct via NC
3272
        /// by sending '1' as data (not documented in wiki...)
3273
        /// returns HW error 255 (comment in uart1.c : tells the KopterTool that it is the FC-version)
3274
        /// </summary>
3275
        /// <param name="ctrl">controller number 1=FC</param> 
3276
        private void _getVersion(byte ctrl)
3277
        {
3278
            _sendControllerMessage('v', 0, new byte[1] { ctrl });
3279
        }
3280
        /// <summary>
3281
        /// Switch back to NC by sending the 'Magic Packet' 0x1B,0x1B,0x55,0xAA,0x00
3282
        /// </summary>
3283
        private void _switchToNC()
3284
        {
3285
            if (serialPortCtrl.Port.IsOpen)
3286
            {
3287
                Stream serialStream = serialPortCtrl.Port.BaseStream;
3288
                byte[] bytes = new byte[5] { 0x1B, 0x1B, 0x55, 0xAA, 0x00 };
3289
                serialStream.Write(bytes, 0, bytes.Length);
3290
 
3291
                Thread.Sleep(100);
3292
                _getVersion();
3293
                Thread.Sleep(100);
3294
                _getLic();
3295
               // _OSDMenue(0);
3296
            }
3297
            else
3298
                Log(LogMsgType.Error, "NOT CONNECTED!");
3299
        }
3300
        /// <summary>
3301
        /// switch to FC
3302
        /// </summary>
3303
        private void _switchToFC()
3304
        {
3305
            _sendControllerMessage('u', 2, new byte[1] { (byte)0 });
3306
            Thread.Sleep(100);
3307
            _getVersion();
3308
            Thread.Sleep(100);
3309
          //  _OSDMenue(0);
3310
        }
3311
        /// <summary>
3312
        /// send RESET signal to FC
3313
        /// </summary>
3314
        private void _resetCtrl()
3315
        {
3316
            _sendControllerMessage('R', 1);
3317
        }
3318
        /// <summary>
3319
        /// poll the debug data (4sec subscription)
3320
        /// </summary>
3321
        /// <param name="auto"> onetimequery(false) or autoupdate(true) with set timing interval </param>
3322
        private void _readDebugData(bool auto)
3323
        {
3324
            byte interval = auto ? debugInterval : (byte)0;
3325
            _sendControllerMessage('d', 0, new byte[1] { debugInterval });
3326
        }
3327
        /// <summary>
3328
        /// poll the BL-CTRL status via NC (4sec subscription)
3329
        /// </summary>
3330
        /// <param name="auto"> onetimequery(false) or autoupdate(true) with set timing interval </param>
3331
        private void _readBLCtrl(bool auto)
3332
        {
3333
            byte interval = auto ? blctrlInterval : (byte)0;
3334
            _sendControllerMessage('k', 0, new byte[1] { interval });
3335
        }
3336
        /// <summary>
3337
        /// poll the NC data struct (4sec subscription)
3338
        /// </summary>
3339
        /// <param name="auto"> onetimequery(false) or autoupdate(true) with set timing interval </param>
3340
        private void _readNavData(bool auto)
3341
        {
3342
            byte interval = auto ? navctrlInterval : (byte)0;
3343
          // _sendControllerMessage('o', 2, new byte[1] { interval });
3344
             _sendControllerMessage('o', 2, new byte[3] { interval,4,0 });
3345
        }
3346
        /// <summary>
3347
        /// request the license info
3348
        /// </summary>
3349
        void _getLic()
3350
        {
3351
            if (serialPortCtrl.Port.IsOpen)
3352
            {
3353
                Stream serialStream = serialPortCtrl.Port.BaseStream;
3354
                byte[] bytes = FlightControllerMessage.CreateMessage('m', 2, new byte[1] { (byte)1 });
3355
                serialStream.Write(bytes, 0, bytes.Length);
3356
            }
3357
            else
3358
                Log(LogMsgType.Error, "NOT CONNECTED!");
3359
 
3360
        }
3361
        /// <summary>
3362
        /// get the errortext for pending NC error
3363
        /// </summary>
3364
        private void _readNCError()
3365
        {
3366
            _sendControllerMessage('e', 2);
3367
        }
3368
        /// <summary>
3369
        /// request the Waypoint at index
3370
        /// </summary>
3371
        /// <param name="index"></param>
3372
        void _getpWP(int index)
3373
        {
3374
            if (serialPortCtrl.Port.IsOpen)
3375
            {
3376
                Stream serialStream = serialPortCtrl.Port.BaseStream;
3377
                byte[] bytes = FlightControllerMessage.CreateMessage('x', 2, new byte[1] { (byte)index });
3378
                serialStream.Write(bytes, 0, bytes.Length);
3379
            }
3380
            else
3381
                Log(LogMsgType.Error, "NOT CONNECTED!");
3382
 
3383
        }
3384
        void _getWP()
3385
        {
3386
            int iTimeout = 0;
3387
            _bGetWPCount = true;
3388
            _getpWP(1); //get the itemscount of wp
3389
            while (_bGetWPCount & iTimeout < _iWPTimeout * 5)
3390
            {
3391
                Thread.Sleep(10);
3392
                iTimeout++;
3393
            }
3394
            if (_iWPCount > 0 & !_bGetWPCount)
3395
                _getWPList();
3396
        }
3397
        void _getWPList()
3398
        {
3399
            _bGetWP = true;
3400
            int iTimeout=0;
3401
            for (int j = 0; j < _iWPCount; j++)
3402
            {
3403
                _getpWP(j + 1);
3404
                iTimeout = 0;
3405
                while (_iWPIndex != j + 1 & iTimeout < _iWPTimeout * 5)
3406
                {
3407
                    Thread.Sleep(1);
3408
                    iTimeout++;
3409
                }
3410
            }
3411
            Dispatcher.Invoke(() =>
3412
            {
3413
               // MainMap.ZoomAndCenterMarkers(null);
3414
                MainMap.Position = new PointLatLng((double)dtWaypoints.Rows[0][3], (double)dtWaypoints.Rows[0][4]);
3415
                MainMap.Zoom = 19;
3416
            });
3417
        }
3418
        /// <summary>
3419
        /// Wrapper for _clearCopterWPList()
3420
        /// necessary, cause it is called by threadnew which does not like return values...
3421
        /// </summary>
3422
        void clearCopterWPList()
3423
        {
3424
            _clearCopterWPList();
3425
        }
3426
        /// <summary>
3427
        /// clear the WP list of the copter
3428
        /// by sending 'invalid' and index '0'
3429
        /// </summary>
3430
        /// <returns></returns>
3431
        bool _clearCopterWPList()
3432
        {
3433
            int iTimeout = 0;
3434
            if (serialPortCtrl.Port.IsOpen)
3435
            {
3436
                byte[] bData = new byte[30];
3437
                for (int i = 0; i < 30; i++)
3438
                    bData[i] = 0;
3439
                Stream serialStream = serialPortCtrl.Port.BaseStream;
3440
                byte[] bytes = FlightControllerMessage.CreateMessage('w', 2, bData); //delete all WP on Copter by sending 'invalid'(==0) at index 0
3441
                serialStream.Write(bytes, 0, bytes.Length);
3442
 
3443
                _iWPCount = -1;
3444
                while (_iWPCount == -1 & iTimeout < _iWPTimeout)
3445
                {
3446
                    Thread.Sleep(10);
3447
                    iTimeout++;
3448
                }
3449
                Dispatcher.Invoke(() => lblWPCount.Content = _iWPCount.ToString());
3450
                if (_iWPCount > -1)
3451
                    return true;
3452
                else
3453
                    Log(LogMsgType.Error, "Timeout while sending list!");
3454
            }
3455
            else
3456
                Log(LogMsgType.Error, "NOT CONNECTED!");
3457
 
3458
            return false;
3459
}
3460
        void _sendWPList()
3461
        {
3462
            _sendWPList(0);
3463
        }
3464
        void _sendWPList(int iStart)
3465
        {
3466
            int iTimeout = 0;
3467
            if (serialPortCtrl.Port.IsOpen)
3468
            {
3469
                if (_clearCopterWPList())
3470
                {
3471
                    int k = 1;
3472
                    for (int i = iStart; i < dtWaypoints.Rows.Count; i++)
3473
                    {
3474
                        k = iStart > 0 ? k : -1;
3475
                        _sendWayPoint(dtWaypoints.Rows[i], k, 'w',false);
3476
 
3477
                        _iWPCount = -1;
3478
                        iTimeout = 0;
3479
                        while (_iWPCount == -1 & iTimeout < _iWPTimeout * 5)
3480
                        {
3481
                            Thread.Sleep(10);
3482
                            iTimeout++;
3483
                        }
3484
                        if (_iWPCount == -1)
3485
                        {
3486
                            Log(LogMsgType.Error, "Timeout while sending list!");
3487
                            break;
3488
                        }
3489
                        Dispatcher.Invoke(() => lblWPCount.Content = _iWPCount.ToString());
3490
                        k++;
3491
                    }
3492
                }
3493
            }
3494
            else
3495
                Log(LogMsgType.Error, "NOT CONNECTED!");
3496
 
3497
        }
3498
        bool _sendWayPoint(DataRow dr, int index, char command,bool bSim)
3499
        {
3500
 
3501
            if (serialPortCtrl.Port.IsOpen)
3502
            {
3503
                byte[] bData = new byte[30];
3504
                for (int i = 0; i < 30; i++)
3505
                    bData[i] = 0;
3506
                Stream serialStream = serialPortCtrl.Port.BaseStream;
3507
                byte[] bytes;
3508
                int iVal;
3509
                double dVal;
3510
                NumberFormatInfo nfi = new NumberFormatInfo();
3511
                nfi.NumberDecimalSeparator = ",";
3512
 
3513
                //longitude
3514
                dVal = Convert.ToDouble(dr[4], nfi);
3515
                iVal = (int)(dVal * Math.Pow(10, 7));
3516
                bData[0] = (byte)(iVal & 0xff);
3517
                bData[1] = (byte)((iVal >> 8) & 0xff);
3518
                bData[2] = (byte)((iVal >> 16) & 0xff);
3519
                bData[3] = (byte)(iVal >> 24);
3520
                //latitude
3521
                dVal = Convert.ToDouble(dr[3], nfi);
3522
                iVal = (int)(dVal * Math.Pow(10, 7));
3523
                bData[4] = (byte)(iVal & 0xff);
3524
                bData[5] = (byte)((iVal >> 8) & 0xff);
3525
                bData[6] = (byte)((iVal >> 16) & 0xff);
3526
                bData[7] = (byte)(iVal >> 24);
3527
                //altitude
3528
                dVal = Convert.ToDouble(dr[5], nfi);
3529
                iVal = (int)(dVal * 10);
3530
                bData[8] = (byte)(iVal & 0xff);
3531
                bData[9] = (byte)((iVal >> 8) & 0xff);
3532
                bData[10] = (byte)((iVal >> 16) & 0xff);
3533
                bData[11] = (byte)(iVal >> 24);
3534
                if(bSim)
3535
                    bData[12] = 3; //Status 'SIMULATE'
3536
                //Status 'NEWDATA'
3537
                else
3538
                    bData[12] = 1;
3539
                //heading
3540
                iVal = Convert.ToInt16(dr[6]);
3541
                bData[13] = (byte)(iVal & 0xff);
3542
                bData[14] = (byte)((iVal >> 8) & 0xff);
3543
                //ToleranceRadius
3544
                bData[15] = Convert.ToByte(dr[9]);
3545
                //HoldTime
3546
                bData[16] = Convert.ToByte(dr[10]);
3547
                //Event_Flag
3548
                bData[17] = Convert.ToByte(dr[13]);
3549
                //Index
3550
                bData[18] = index > -1 ? (byte)index : Convert.ToByte((int)dr[0]);
3551
                //Type
3552
                bData[19] = Convert.ToByte(dr[1]);
3553
                //WP_EventChannelValue
3554
                bData[20] = Convert.ToByte(dr[14]);
3555
                //AltitudeRate
3556
                bData[21] = Convert.ToByte(dr[8]);
3557
                //Speed
3558
                bData[22] = Convert.ToByte(dr[7]);
3559
                //CamAngle
3560
                bData[23] = (byte)Convert.ToInt16(dr[12]);
3561
                //Name
3562
                string s = index > 0 ? ((string)dr[2]).Substring(0, 1) + index.ToString() : (string)dr[2];
3563
                byte[] name = ASCIIEncoding.ASCII.GetBytes(s);
3564
                bData[24] = name.Length > 0 ? name[0] : (byte)0;
3565
                bData[25] = name.Length > 1 ? name[1] : (byte)0;
3566
                bData[26] = name.Length > 2 ? name[2] : (byte)0;
3567
                bData[27] = name.Length > 3 ? name[3] : (byte)0;
3568
                //Autotrigger
3569
                bData[28] = Convert.ToByte(dr[11]);
3570
 
3571
                bytes = FlightControllerMessage.CreateMessage(command, 2, bData);
3572
                serialStream.Write(bytes, 0, bytes.Length);
3573
 
3574
                return true;
3575
            }
3576
 
3577
            return false;
3578
        }
3579
        #region OSD-Menue
3580
 
3581
        /// <summary>
3582
        /// one time query of the OSD Menue with pagenumber
3583
        /// </summary>
3584
        /// <param name="iMenue">Menue page</param>
3585
        void _OSDMenue(int iMenue)
3586
        {
3587
            if (serialPortCtrl.Port.IsOpen)
3588
            {
3589
                if (iMenue > iOSDMax)
3590
                    iMenue = 0;
3591
                Stream serialStream = serialPortCtrl.Port.BaseStream;
3592
                byte[] bytes = FlightControllerMessage.CreateMessage('l', 0, new byte[1] { (byte)iMenue });
3593
                serialStream.Write(bytes, 0, bytes.Length);
3594
            }
3595
            else
3596
                Log(LogMsgType.Error, "NOT CONNECTED!");
3597
 
3598
        }
3599
        /// <summary>
3600
        /// call the OSDMenue and start autorefresh
3601
        ///  usually by sending a menuekey
3602
        /// 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)
3603
        /// therefore the value has to be negative (inverted) in order to distinguish from old (2 line) menuestyle
3604
        /// and must not have any bits of the menue keys 0x1 0x2 0x4 0x8 (0x10?) --> 0x20 = -33
3605
        /// </summary>
3606
        void _OSDMenueAutoRefresh()
3607
        {
3608
            _sendControllerMessage('h', 0, new byte[2] { unchecked((byte)(-33)), OSDInterval });
3609
        }
3610
        void _OSDMenueAutoRefresh(byte key)
3611
        {
3612
            _sendControllerMessage('h', 0, new byte[2] { unchecked((byte)~key), OSDInterval });
3613
        }
3614
        /// <summary>
3615
        /// initialize the OSD menue combobox
3616
        /// combox is filled by numbers from 0 to max pagenumber
3617
        /// </summary>
3618
        void _initOSDCB()
3619
        {
3620
            _bCBInit = true;
3621
            if (iOSDMax == 0)
3622
            {
3623
                _OSDMenue(0);
3624
                Thread.Sleep(10);
3625
            }
3626
            Dispatcher.Invoke((Action)(() => cbOSD.Items.Clear()));
3627
            for (int i = 0; i <= iOSDMax; i++)
3628
            {
3629
                Dispatcher.Invoke((Action)(() => cbOSD.Items.Add(i)));
3630
            }
3631
            Dispatcher.Invoke((Action)(() => cbOSD.SelectedItem = iOSDPage));
3632
            _bCBInit = false;
3633
        }
3634
        private void btnOSDForward_Click(object sender, RoutedEventArgs e)
3635
        {
3636
            iOSDPage++;
3637
            if (iOSDPage > iOSDMax)
3638
                iOSDPage = 0;
3639
 
3640
            _OSDMenue(iOSDPage);
3641
        }
3642
        private void btnOSDBackward_Click(object sender, RoutedEventArgs e)
3643
        {
3644
            iOSDPage--;
3645
            if (iOSDPage < 0)
3646
                iOSDPage = iOSDMax;
3647
 
3648
            _OSDMenue(iOSDPage);
3649
        }
3650
        private void btnOSDLeave_Click(object sender, RoutedEventArgs e)
3651
        {
3652
            _OSDMenueAutoRefresh(8);
3653
        }
3654
        private void btnOSDEnter_Click(object sender, RoutedEventArgs e)
3655
        {
3656
            _OSDMenueAutoRefresh(4);
3657
        }
3658
        private void cbOSD_DropDownClosing(object sender, EventArgs e)
3659
        {
3660
            if (!_bCBInit && cbOSD.SelectedIndex > -1)
3661
                _OSDMenue(cbOSD.SelectedIndex);
3662
        }
3663
        private void OSD(LogMsgType msgtype, string msg, bool bNew)
3664
        {
3665
            Dispatcher.Invoke(() =>
3666
            {
3667
                TextRange tr;
3668
                if (bNew)
3669
                {
3670
                    rtfOSD.SelectAll();
3671
                    rtfOSD.Selection.Text = string.Empty;
3672
                }
3673
                tr = new TextRange(rtfOSD.Document.ContentEnd, rtfOSD.Document.ContentEnd);
3674
                tr.Text = msg;
3675
                tr.ApplyPropertyValue(TextElement.ForegroundProperty, new SolidColorBrush(LogMsgTypeColor[(int)msgtype]));
3676
                //     rtfOSD.AppendText("\r");
3677
                rtfOSD.ScrollToEnd();
3678
 
3679
            });
3680
        }
3681
 
3682
        #endregion OSD-Menue
3683
 
3684
        #endregion controller messages
3685
 
3686
        void _mediaPlayer(object file)
3687
        {
3688
            Monitor.TryEnter(lockObj);
3689
            try
3690
            {
3691
                if (File.Exists((string)file))
3692
                {
3693
 
3694
                    mediaPlayer.Open((string)file);
3695
                    mediaPlayer.Play();
3696
                }
3697
                else
3698
                    Log(LogMsgType.Warning, "File not found: " + file.ToString());
3699
 
3700
            }
3701
            finally
3702
            {
3703
                Monitor.Exit(lockObj);
3704
            }
3705
        }
3706
 
3707
        #region ui
3708
        /// <summary>
3709
        /// Switch between fullscreen and normal window mode
3710
        /// save & restore scaling settings
3711
        /// </summary>
3712
        /// <param name="sender"></param>
3713
        /// <param name="e"></param>
3714
        private void imageFullscreen_MouseDown(object sender, MouseButtonEventArgs e)
3715
        {
3716
            if (winState.isMaximized)
3717
            {
3718
                winState.Restore(this);
3719
                imageFullscreen.Source = new BitmapImage(new Uri("Images/Fullscreen.png", UriKind.Relative));
3720
                if(_bSaveWinStateFull)
3721
                    _saveScaleSliders(true);
3722
                if(_bSaveWinStateNormal)
3723
                    _setScaleSliders(false);
3724
            }
3725
            else
3726
            {
3727
                winState.Maximize(this);
3728
                imageFullscreen.Source = new BitmapImage(new Uri("Images/RestoreScreen.png", UriKind.Relative));
3729
                if(_bSaveWinStateNormal)
3730
                    _saveScaleSliders(false);
3731
                if(_bSaveWinStateFull)
3732
                    _setScaleSliders(true);
3733
            }
3734
        }
3735
 
3736
        /// <summary>
3737
        /// reset the scaling of all UI elements to default
3738
        /// </summary>
3739
        /// <param name="sender"></param>
3740
        /// <param name="e"></param>
3741
        private void buttonUIScaleReset_Click(object sender, RoutedEventArgs e)
3742
        {
3743
            UIScaleHorizonSlider.Value =
3744
                UIScaleLOGSlider.Value =
3745
                UIScaleMotorsSlider.Value =
3746
                UIScaleOSDSlider.Value =
3747
                UIScaleSlider.Value =
3748
                UIScaleTopSlider.Value = 1;
3749
        }
3750
        /// <summary>
3751
        /// adjust the top postion of UI elements below the top bar to fit the bottom position of the bar when scaling the top bar
3752
        /// </summary>
3753
        /// <param name="sender"></param>
3754
        /// <param name="e"></param>
3755
        private void UIScaleTopSlider_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
3756
        {
3757
            GridSettings.Margin = new Thickness(GridSettings.Margin.Left, 36 * UIScaleTopSlider.Value, GridSettings.Margin.Right, GridSettings.Margin.Bottom);
3758
            if (GridMotors != null)
3759
                GridMotors.Margin = new Thickness(GridMotors.Margin.Left, 36 * UIScaleTopSlider.Value, GridMotors.Margin.Right, GridMotors.Margin.Bottom);
3760
            if (GridSideBar != null)
3761
                GridSideBar.Margin = new Thickness(GridSideBar.Margin.Left, 36 * UIScaleTopSlider.Value, GridSideBar.Margin.Right, GridSideBar.Margin.Bottom);
3762
            if (WPStatus != null)
3763
                WPStatus.Margin = new Thickness(WPStatus.Margin.Left, 36 * UIScaleTopSlider.Value, WPStatus.Margin.Right, WPStatus.Margin.Bottom);
3764
            if (GridOSD != null)
3765
            {
3766
                if(WPStatus.Visibility == Visibility.Visible)
3767
                    GridOSD.Margin = new Thickness(GridOSD.Margin.Left, 36 * UIScaleTopSlider.Value + WPStatus.Margin.Bottom, GridOSD.Margin.Right, GridOSD.Margin.Bottom);
3768
                else
3769
                    GridOSD.Margin = new Thickness(GridOSD.Margin.Left, 36 * UIScaleTopSlider.Value, GridOSD.Margin.Right, GridOSD.Margin.Bottom);
3770
            }
3771
            if (GridData != null)
3772
                GridData.Margin = new Thickness(GridData.Margin.Left, 36 * UIScaleTopSlider.Value, GridData.Margin.Right, GridData.Margin.Bottom);
3773
            if (GridWP != null)
3774
                GridWP.Margin = new Thickness(GridWP.Margin.Left, 36 * UIScaleTopSlider.Value, GridWP.Margin.Right, GridWP.Margin.Bottom);
3775
        }
3776
        private void UIScaleOSDSlider_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
3777
        {
3778
            if (!_init)
3779
            {
3780
                if (WPStatus != null && (WPStatus.Visibility == Visibility.Visible))
3781
                    GridOSD.Margin = new Thickness(GridOSD.Margin.Left, 36 * UIScaleTopSlider.Value + 36, GridOSD.Margin.Right, GridOSD.Margin.Bottom);
3782
                else
3783
                    GridOSD.Margin = new Thickness(GridOSD.Margin.Left, 36 * UIScaleTopSlider.Value, GridOSD.Margin.Right, GridOSD.Margin.Bottom);
3784
            }
3785
        }
3786
 
3787
        /// <summary>
3788
        /// restore the saved scalings for the fullscreen/normal window mode
3789
        /// </summary>
3790
        /// <param name="bFull">the mode the window is set to</param>
3791
        void _setScaleSliders(bool bFull)
3792
        {
3793
            if(bFull)
3794
            {
3795
                UIScaleSlider.Value = scaleFullAll;
3796
                UIScaleTopSlider.Value = scaleFullTopBar;
3797
                UIScaleMotorsSlider.Value = scaleFullMotors;
3798
                UIScaleOSDSlider.Value = scaleFullOSD;
3799
                UIScaleLOGSlider.Value = scaleFullLOG;
3800
                UIScaleHorizonSlider.Value = scaleFullHorizon;
3801
            }
3802
            else
3803
            {
3804
                UIScaleSlider.Value = scaleNormalAll;
3805
                UIScaleTopSlider.Value = scaleNormalTopBar;
3806
                UIScaleMotorsSlider.Value = scaleNormalMotors;
3807
                UIScaleOSDSlider.Value = scaleNormalOSD;
3808
                UIScaleLOGSlider.Value = scaleNormalLOG;
3809
                UIScaleHorizonSlider.Value = scaleNormalHorizon;
3810
            }
3811
        }
3812
 
3813
        /// <summary>
3814
        /// save the scalings for the actual window mode
3815
        /// </summary>
3816
        /// <param name="bFull">the actual window mode</param>
3817
        void _saveScaleSliders(bool bFull)
3818
        {
3819
 
3820
            if (bFull)
3821
            {
3822
                scaleFullAll = UIScaleSlider.Value;
3823
                scaleFullTopBar = UIScaleTopSlider.Value;
3824
                scaleFullMotors = UIScaleMotorsSlider.Value;
3825
                scaleFullOSD = UIScaleOSDSlider.Value;
3826
                scaleFullLOG = UIScaleLOGSlider.Value;
3827
                scaleFullHorizon = UIScaleHorizonSlider.Value;
3828
            }
3829
            else
3830
            {
3831
                scaleNormalAll = UIScaleSlider.Value;
3832
                scaleNormalTopBar = UIScaleTopSlider.Value;
3833
                scaleNormalMotors = UIScaleMotorsSlider.Value;
3834
                scaleNormalOSD = UIScaleOSDSlider.Value;
3835
                scaleNormalLOG = UIScaleLOGSlider.Value;
3836
                scaleNormalHorizon = UIScaleHorizonSlider.Value;
3837
            }
3838
        }
3839
        #endregion ui
3840
 
3841
        #region ini
3842
        /// <summary>
3843
        /// read settings from ini-file
3844
        /// </summary>
3845
        void _readIni()
3846
        {
3847
            if (!File.Exists(filePath + "\\MKLiveViewSettings.ini"))
3848
                _writeIni();
3849
            IniFile ini = new IniFile("MKLiveViewSettings.ini");
3850
            ini.path = filePath + "\\MKLiveViewSettings.ini";
3851
            try
3852
            {
3853
 
3854
                string sVal = ini.IniReadValue("timings", "AutorefreshDebugData");
3855
                if (sVal != "") _debugDataAutorefresh = Convert.ToBoolean(sVal);
3856
                sVal = ini.IniReadValue("timings", "AutorefreshNavCtrlData");
3857
                if (sVal != "") _navCtrlDataAutorefresh = Convert.ToBoolean(sVal);
3858
                sVal = ini.IniReadValue("timings", "AutorefreshBLCtrlData");
3859
                if (sVal != "") _blctrlDataAutorefresh = Convert.ToBoolean(sVal);
3860
                sVal = ini.IniReadValue("timings", "AutorefreshOSDData");
3861
                if (sVal != "") _OSDAutorefresh = Convert.ToBoolean(sVal);
3862
 
3863
                sVal = ini.IniReadValue("timings", "IntervalDebugData");
3864
                if (sVal != "") debugInterval = (byte)Convert.ToInt16(sVal);
3865
                sVal = ini.IniReadValue("timings", "IntervalNavCtrlData");
3866
                if (sVal != "") navctrlInterval = (byte)Convert.ToInt16(sVal);
3867
                sVal = ini.IniReadValue("timings", "IntervalBLCtrlData");
3868
                if (sVal != "") blctrlInterval = (byte)Convert.ToInt16(sVal);
3869
                sVal = ini.IniReadValue("timings", "IntervalOSDData");
3870
                if (sVal != "") OSDInterval = (byte)Convert.ToInt16(sVal);
3871
 
3872
                sVal = ini.IniReadValue("topBar", "voltage");
3873
                if (sVal != "") chkBoxTopBarShowVoltage.IsChecked = Convert.ToBoolean(sVal);
3874
                sVal = ini.IniReadValue("topBar", "capacity");
3875
                if (sVal != "") chkBoxTopBarShowCapacity.IsChecked = Convert.ToBoolean(sVal);
3876
                sVal = ini.IniReadValue("topBar", "current");
3877
                if (sVal != "") chkBoxTopBarShowCurrent.IsChecked = Convert.ToBoolean(sVal);
3878
                sVal = ini.IniReadValue("topBar", "flightTime");
3879
                if (sVal != "") chkBoxTopBarShowFlightTime.IsChecked = Convert.ToBoolean(sVal);
3880
                sVal = ini.IniReadValue("topBar", "distanceHP");
3881
                if (sVal != "") chkBoxTopBarShowDistanceHP.IsChecked = Convert.ToBoolean(sVal);
3882
                sVal = ini.IniReadValue("topBar", "height");
3883
                if (sVal != "") chkBoxTopBarShowHeight.IsChecked = Convert.ToBoolean(sVal);
3884
                sVal = ini.IniReadValue("topBar", "speed");
3885
                if (sVal != "") chkBoxTopBarShowSpeed.IsChecked = Convert.ToBoolean(sVal);
3886
                sVal = ini.IniReadValue("topBar", "magneticField");
3887
                if (sVal != "") chkBoxTopBarShowMF.IsChecked = Convert.ToBoolean(sVal);
3888
                sVal = ini.IniReadValue("topBar", "satellites");
3889
                if (sVal != "") chkBoxTopBarShowSatellites.IsChecked = Convert.ToBoolean(sVal);
3890
                sVal = ini.IniReadValue("topBar", "rc");
3891
                if (sVal != "") chkBoxTopBarShowRC.IsChecked = Convert.ToBoolean(sVal);
3892
 
3893
                sVal = ini.IniReadValue("style", "saveFullScreen");
3894
                if (sVal != "") chkBoxSaveFullScreenState.IsChecked = Convert.ToBoolean(sVal);
3895
                sVal = ini.IniReadValue("style", "saveNormalState");
3896
                if (sVal != "") chkBoxSaveNormalState.IsChecked = Convert.ToBoolean(sVal);
3897
 
3898
                sVal = ini.IniReadValue("style", "scaleNormalAll");
3899
                if (sVal != "") scaleNormalAll = Convert.ToDouble(sVal);
3900
                sVal = ini.IniReadValue("style", "scaleNormalTopBar");
3901
                if (sVal != "") scaleNormalTopBar = Convert.ToDouble(sVal);
3902
                sVal = ini.IniReadValue("style", "scaleNormalMotors");
3903
                if (sVal != "") scaleNormalMotors = Convert.ToDouble(sVal);
3904
                sVal = ini.IniReadValue("style", "scaleNormalOSD");
3905
                if (sVal != "") scaleNormalOSD = Convert.ToDouble(sVal);
3906
                sVal = ini.IniReadValue("style", "scaleNormalLOG");
3907
                if (sVal != "") scaleNormalLOG = Convert.ToDouble(sVal);
3908
                sVal = ini.IniReadValue("style", "scaleNormalHorizon");
3909
                if (sVal != "") scaleNormalHorizon = Convert.ToDouble(sVal);
3910
 
3911
                sVal = ini.IniReadValue("style", "scaleFullAll");
3912
                if (sVal != "") scaleFullAll = Convert.ToDouble(sVal);
3913
                sVal = ini.IniReadValue("style", "scaleFullTopBar");
3914
                if (sVal != "") scaleFullTopBar = Convert.ToDouble(sVal);
3915
                sVal = ini.IniReadValue("style", "scaleFullMotors");
3916
                if (sVal != "") scaleFullMotors = Convert.ToDouble(sVal);
3917
                sVal = ini.IniReadValue("style", "scaleFullOSD");
3918
                if (sVal != "") scaleFullOSD = Convert.ToDouble(sVal);
3919
                sVal = ini.IniReadValue("style", "scaleFullLOG");
3920
                if (sVal != "") scaleFullLOG = Convert.ToDouble(sVal);
3921
                sVal = ini.IniReadValue("style", "scaleFullHorizon");
3922
                if (sVal != "") scaleFullHorizon = Convert.ToDouble(sVal);
3923
 
3924
                sVal = ini.IniReadValue("general", "LiPoCells");
3925
                _LipoCells = Convert.ToInt16(sVal);
3926
                sVal = ini.IniReadValue("general", "LiPoAutoDetect");
3927
                _bLiPoAutoDetect = Convert.ToBoolean(sVal);
3928
                sVal = ini.IniReadValue("general", "Motors");
3929
                if (sVal != "") _iMotors = Convert.ToInt16(sVal);
3930
                sVal = ini.IniReadValue("general", "UILanguage");
3931
                if (sVal != "") _iUILanguage = Convert.ToInt16(sVal);
3932
 
3933
                sVal = ini.IniReadValue("map", "followMe");
3934
                if (sVal != "") _bFollowCopter = Convert.ToBoolean(sVal);
3935
                sVal = ini.IniReadValue("map", "location");
3936
                if (sVal != "") _mapPosition = sVal;
3937
                sVal = ini.IniReadValue("map", "AutoSetHome");
3938
                if (sVal != "") _bAutoHome = Convert.ToBoolean(sVal);
3939
                sVal = ini.IniReadValue("map", "GPXLog");
3940
                if (sVal != "") _bGPXLog = Convert.ToBoolean(sVal);
3941
 
3942
                sVal = ini.IniReadValue("threshold", "VoltageWarning");
3943
                if(sVal != "") _dThresholdVoltageWarn = Convert.ToDouble(sVal);
3944
                sVal = ini.IniReadValue("threshold", "VoltageCritical");
3945
                if(sVal != "") _dThresholdVoltageCrit = Convert.ToDouble(sVal);
3946
                sVal = ini.IniReadValue("threshold", "VoiceVoltageEnable");
3947
                if(sVal != "") _bVoiceVoltPlay = Convert.ToBoolean(sVal);
3948
                sVal = ini.IniReadValue("threshold", "VoiceSatFixEnable");
3949
                if(sVal != "") _bVoiceSatFixPlay = Convert.ToBoolean(sVal);
3950
                sVal = ini.IniReadValue("threshold", "VoiceMagFieldEnable");
3951
                if(sVal != "") _bVoiceMagneticFieldPlay = Convert.ToBoolean(sVal);
3952
                sVal = ini.IniReadValue("threshold", "DistanceWarning");
3953
                if(sVal != "") _dThresholdDistanceWarn = Convert.ToDouble(sVal);
3954
                sVal = ini.IniReadValue("threshold", "VoiceDistanceWarnEnable");
3955
                if(sVal != "") _bVoiceDistancePlay = Convert.ToBoolean(sVal);
3956
                sVal = ini.IniReadValue("threshold", "VoiceRCLevelWarnEnable");
3957
                if(sVal != "") _bVoiceRCLevelPlay = Convert.ToBoolean(sVal);
3958
                sVal = ini.IniReadValue("threshold", "MaxDistance");
3959
                if(sVal != "") _dThresholdDistanceMax = Convert.ToDouble(sVal);
3960
                sVal = ini.IniReadValue("threshold", "RCThreshold");
3961
                if(sVal != "") _iThresholdRC = Convert.ToInt32(sVal);
3962
                sVal = ini.IniReadValue("threshold", "MagFieldThreshold");
3963
                if(sVal != "") _iThresholdMagField = Convert.ToInt32(sVal);
3964
                sVal = ini.IniReadValue("threshold", "BLCtrlTemp");
3965
                if(sVal != "") _iThresholdBLCTRLTempWarn = Convert.ToInt32(sVal);
3966
                sVal = ini.IniReadValue("threshold", "VoiceBLCtrlTempEnable");
3967
                if(sVal != "") _bVoiceBLCTRLTempPlay = Convert.ToBoolean(sVal);
3968
                sVal = ini.IniReadValue("threshold", "VoiceLanguageIndex");
3969
                if(sVal != "") _iVoiceIndex = Convert.ToInt32(sVal);
3970
 
3971
                sVal = ini.IniReadValue("waypoints", "wpcolor");
3972
                if(sVal != "") comboBoxWPColor.SelectedIndex = Convert.ToInt32(sVal);
3973
                sVal = ini.IniReadValue("waypoints", "poicolor");
3974
                if(sVal != "") comboBoxPOIColor.SelectedIndex = Convert.ToInt32(sVal);
3975
                sVal = ini.IniReadValue("waypoints", "fscolor");
3976
                if(sVal != "") comboBoxFSColor.SelectedIndex = Convert.ToInt32(sVal);
3977
                sVal = ini.IniReadValue("waypoints", "coptercolor");
3978
                if(sVal != "") comboBoxCopterColor.SelectedIndex = Convert.ToInt32(sVal);
3979
                sVal = ini.IniReadValue("waypoints", "copterheadingcolor");
3980
                if(sVal != "") comboBoxCopterHeadingColor.SelectedIndex = Convert.ToInt32(sVal);
3981
                sVal = ini.IniReadValue("waypoints", "landingcolor");
3982
                if(sVal != "") comboBoxLandingColor.SelectedIndex = Convert.ToInt32(sVal);
3983
                sVal = ini.IniReadValue("waypoints", "routecolor");
3984
                if(sVal != "") comboBoxRouteColor.SelectedIndex = Convert.ToInt32(sVal);
3985
                sVal = ini.IniReadValue("waypoints", "showWPRoute");
3986
                if(sVal != "") _bShowWPRoute = Convert.ToBoolean(sVal);
3987
                sVal = ini.IniReadValue("waypoints", "autoShowWPEdit");
3988
                if(sVal != "") _bAutoWPEdit = Convert.ToBoolean(sVal);
3989
                sVal = ini.IniReadValue("waypoints", "showWPMaxRange");
3990
                if(sVal != "") checkBoxShowWPMaxRange.IsChecked = Convert.ToBoolean(sVal);
3991
                sVal = ini.IniReadValue("waypoints", "WPMaxRangecolor");
3992
                if(sVal != "") comboBoxWPMaxRangeColor.SelectedIndex = Convert.ToInt32(sVal);
3993
                sVal = ini.IniReadValue("waypoints", "WPDefPrefix");
3994
                if(sVal != "") _wpDefPrefix = sVal;
3995
                sVal = ini.IniReadValue("waypoints", "WPDefAltitude");
3996
                if(sVal != "") _wpDefAltitude = Convert.ToInt32(sVal);
3997
                sVal = ini.IniReadValue("waypoints", "WPDefHeading");
3998
                if(sVal != "") _wpDefHeading = Convert.ToInt32(sVal);
3999
                sVal = ini.IniReadValue("waypoints", "WPDefCBoxHeading");
4000
                if(sVal != "") _wpDefCBoxHeading = Convert.ToInt32(sVal);
4001
                sVal = ini.IniReadValue("waypoints", "WPDefSpeed");
4002
                if(sVal != "") _wpDefSpeed = Convert.ToInt32(sVal);
4003
                sVal = ini.IniReadValue("waypoints", "WPDefCBoxSpeed");
4004
                if(sVal != "") _wpDefCBoxSpeed = Convert.ToInt32(sVal);
4005
                sVal = ini.IniReadValue("waypoints", "WPDefClimb");
4006
                if(sVal != "") _wpDefClimb = Convert.ToInt32(sVal);
4007
                sVal = ini.IniReadValue("waypoints", "WPDefCBoxClimb");
4008
                if(sVal != "") _wpDefCBoxClimb = Convert.ToInt32(sVal);
4009
                sVal = ini.IniReadValue("waypoints", "WPDefRadius");
4010
                if(sVal != "") _wpDefRadius = Convert.ToInt32(sVal);
4011
                sVal = ini.IniReadValue("waypoints", "WPDefHoldtime");
4012
                if(sVal != "") _wpDefHoldtime = Convert.ToInt32(sVal);
4013
                sVal = ini.IniReadValue("waypoints", "WPDefAutotrig");
4014
                if(sVal != "") _wpDefAutotrig = Convert.ToInt32(sVal);
4015
                sVal = ini.IniReadValue("waypoints", "WPDefCamangle");
4016
                if(sVal != "") _wpDefCamangle = Convert.ToInt32(sVal);
4017
                sVal = ini.IniReadValue("waypoints", "WPDefCBoxCamangle");
4018
                if(sVal != "") _wpDefCBoxCamangle = Convert.ToInt32(sVal);
4019
                sVal = ini.IniReadValue("waypoints", "WPDefOut1");
4020
                if(sVal != "") _wpDefOut1 = Convert.ToInt32(sVal);
4021
                sVal = ini.IniReadValue("waypoints", "WPAddCopterHeight");
4022
                if (sVal != "") _wpAddCopterHeight = Convert.ToBoolean(sVal);
4023
                sVal = ini.IniReadValue("waypoints", "WPAddCopterHeading");
4024
                if (sVal != "") _wpAddCopterHeading = Convert.ToBoolean(sVal);
4025
                sVal = ini.IniReadValue("waypoints", "CopterSize");
4026
                if (sVal != "") SliderCopterZoom.Value = Convert.ToDouble(sVal);
4027
                sVal = ini.IniReadValue("waypoints", "WPSize");
4028
                if (sVal != "") SliderWPZoom.Value = Convert.ToDouble(sVal);
4029
 
4030
                sVal = ini.IniReadValue("cam", "CamImagePosLeft");
4031
                if (sVal != "") _camImageMargin.Left = Convert.ToDouble(sVal);
4032
                sVal = ini.IniReadValue("cam", "CamImagePosTop");
4033
                if (sVal != "") _camImageMargin.Top = Convert.ToDouble(sVal);
4034
                sVal = ini.IniReadValue("cam", "CamImageZoom");
4035
                if (sVal != "") SliderCamZoom.Value = Convert.ToDouble(sVal);
4036
 
4037
                for (int i = 0; i < 12; i++)
4038
                {
4039
                    sVal = ini.IniReadValue("serial", "ch" + i.ToString() + "Val");
4040
                    if (sVal != "")
4041
                        serChan[i] = Convert.ToInt16(sVal);
4042
                    sVal = ini.IniReadValue("serial", "ch" + i.ToString() + "Title");
4043
                    if (sVal != "")
4044
                        serChanTitle[i] = sVal;
4045
                    for (int y = 0; i < 4 && y < 3; y++)
4046
                    {
4047
                        sVal = ini.IniReadValue("serial", "ch" + i.ToString() + "ValSub" + y.ToString());
4048
                        if (sVal != "")
4049
                            serChan_sub[(i * 3) + y] = Convert.ToInt16(sVal);
4050
                    }
4051
                }
4052
 
4053
            }
4054
            catch (Exception e)
4055
            {
4056
 
4057
                MessageBox.Show("Error parsing ini-file!" + Environment.NewLine + e.Message,"Read ini-file" ,MessageBoxButton.OK,MessageBoxImage.Error);
4058
            }
4059
 
4060
        }
4061
 
4062
        /// <summary>
4063
        /// save settings to ini-file
4064
        /// </summary>
4065
        void _writeIni()
4066
        {
4067
 
4068
            IniFile ini = new IniFile("MKLiveViewSettings.ini");
4069
            ini.path = filePath + "\\MKLiveViewSettings.ini";
4070
 
4071
            try
4072
            {
4073
 
4074
                ini.IniWriteValue("timings", "AutorefreshDebugData", _debugDataAutorefresh ? "true" : "false");
4075
                ini.IniWriteValue("timings", "AutorefreshNavCtrlData", _navCtrlDataAutorefresh ? "true" : "false");
4076
                ini.IniWriteValue("timings", "AutorefreshBLCtrlData", _blctrlDataAutorefresh ? "true" : "false");
4077
                ini.IniWriteValue("timings", "AutorefreshOSDData", _OSDAutorefresh ? "true" : "false");
4078
 
4079
                ini.IniWriteValue("timings", "IntervalDebugData", debugInterval.ToString());
4080
                ini.IniWriteValue("timings", "IntervalNavCtrlData", navctrlInterval.ToString());
4081
                ini.IniWriteValue("timings", "IntervalBLCtrlData", blctrlInterval.ToString());
4082
                ini.IniWriteValue("timings", "IntervalOSDData", OSDInterval.ToString());
4083
 
4084
                ini.IniWriteValue("general", "LiPoCells", _LipoCells.ToString());
4085
                ini.IniWriteValue("general", "LiPoAutoDetect", _bLiPoAutoDetect.ToString());
4086
                ini.IniWriteValue("general", "Motors", _iMotors.ToString());
4087
                ini.IniWriteValue("general", "UILanguage", _iUILanguage.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 = _colors[comboBoxRouteColor.SelectedIndex];
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 = _colors[comboBoxWPColor.SelectedIndex];
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 = _colors[comboBoxPOIColor.SelectedIndex];
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 = _colors[comboBoxFSColor.SelectedIndex];
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 = _colors[comboBoxLandingColor.SelectedIndex];
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 = _colors[((ComboBox)sender).SelectedIndex];
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 = _colors[comboBoxCopterColor.SelectedIndex];
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 = _colors[comboBoxCopterHeadingColor.SelectedIndex];
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 = _colors[comboBoxRouteColor.SelectedIndex];
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 = _colors[comboBoxWPMaxRangeColor.SelectedIndex];
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 = _colors[comboBoxWPMaxRangeColor.SelectedIndex];
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
 
5944
        private void btnClearRoute_Click(object sender, RoutedEventArgs e)
5945
        {
5946
            _clearMapMarkers(typeof(GMapRoute));
5947
        }
5948
        void _loadGPXLog()
5949
        {
5950
 
5951
            Microsoft.Win32.OpenFileDialog fd = new Microsoft.Win32.OpenFileDialog();
5952
            fd.Filter = "GPX-Logfile | *.gpx";
5953
            fd.Multiselect = false;
5954
            if (fd.ShowDialog().Value)
5955
            {
5956
                string file = fd.FileName;
5957
                try
5958
                {
5959
                    XDocument gpxDoc = XDocument.Load(file);
5960
                    XNamespace gpx = XNamespace.Get("http://www.topografix.com/GPX/1/1");
5961
 
5962
                    NumberFormatInfo nfi = new NumberFormatInfo();
5963
                    nfi.NumberDecimalSeparator = ".";
5964
 
5965
                    var tracks = from track in gpxDoc.Descendants(gpx + "trk")
5966
                                 select new
5967
                                 {
5968
                                     Name = track.Element(gpx + "name") != null ? track.Element(gpx + "name").Value : null,
5969
                                     Segs = (
5970
                                         from trackpoint in track.Descendants(gpx + "trkpt")
5971
                                         select new
5972
                                         {
5973
                                             Latitude = trackpoint.Attribute("lat").Value,
5974
                                             Longitude = trackpoint.Attribute("lon").Value,
5975
                                             Elevation = trackpoint.Element(gpx + "ele") != null ?
5976
                                             trackpoint.Element(gpx + "ele").Value : null,
5977
                                             Time = trackpoint.Element(gpx + "time") != null ?
5978
                                             trackpoint.Element(gpx + "time").Value : null
5979
                                         }
5980
                                     )
5981
                                 };
5982
 
5983
                    List<PointLatLng> wpl = new List<PointLatLng>();
5984
                    foreach(var trk in tracks)
5985
                    {
5986
                        foreach(var trkseg in trk.Segs)
5987
                        {
5988
                            if(trkseg.Latitude != "" && trkseg.Longitude !="")
5989
                            wpl.Add(new PointLatLng(Convert.ToDouble(trkseg.Latitude, nfi), Convert.ToDouble(trkseg.Longitude, nfi)));
5990
                        }
5991
 
5992
                    }
5993
                    if(wpl.Count() > 0)
5994
                    {
5995
                        _clearMapMarkers(typeof(GMapRoute));
5996
                        MapRoute mr = new MapRoute(wpl, "flying");
5997
                        Dispatcher.Invoke(() =>
5998
                        {
5999
                            GMapRoute mRoute;
6000
                            if (comboBoxRouteColor.SelectionBoxItem != null)
6001
                            {
6002
                                string s = _colors[comboBoxRouteColor.SelectedIndex];
6003
                                mRoute = new GMapRoute(wpl, _getBrush(s));
6004
                            }
6005
                            else
6006
                                mRoute = new GMapRoute(wpl, null);
6007
 
6008
                            MainMap.Markers.Add(mRoute);
6009
                        });
6010
                    }
6011
 
6012
                }
6013
                catch (Exception e)
6014
                {
6015
                    Console.WriteLine("Exception: {0}", e.ToString());
6016
                }
6017
            }
6018
        }
6019
        #endregion GPX
6020
 
6021
        /// <summary>
6022
        /// switch language
6023
        /// </summary>
6024
        /// <param name="culture">specific culture</param>
6025
        public void ChangeLanguage(string culture)
6026
        {
6027
            // Alle Woerterbuecher finden   
6028
            List<ResourceDictionary> dictionaryList = new List<ResourceDictionary>();
6029
            foreach (ResourceDictionary dictionary in Application.Current.Resources.MergedDictionaries)
6030
            {
6031
                dictionaryList.Add(dictionary);
6032
            }
6033
 
6034
            // Woerterbuch waehlen
6035
            string requestedCulture = string.Format("Localize/localization.{0}.xaml", culture);
6036
            ResourceDictionary resourceDictionary = dictionaryList.FirstOrDefault(d => d.Source.OriginalString == requestedCulture);
6037
            if (resourceDictionary == null)
6038
            {
6039
                // Wenn das gewuenschte Woerterbuch nicht gefunden wird,
6040
                // lade Standard-Woerterbuch
6041
                requestedCulture = "Localize/localization.xaml";
6042
                resourceDictionary = dictionaryList.FirstOrDefault(d => d.Source.OriginalString == requestedCulture);
6043
            }
6044
 
6045
            // Altes Woerterbuch loeschen und Neues hinzufuegen       
6046
            if (resourceDictionary != null)
6047
            {
6048
                Application.Current.Resources.MergedDictionaries.Remove(resourceDictionary);
6049
                Application.Current.Resources.MergedDictionaries.Add(resourceDictionary);
6050
            }
6051
 
6052
            // Hauptthread ueber neues Culture informieren
6053
            Thread.CurrentThread.CurrentCulture = CultureInfo.CreateSpecificCulture(culture);
6054
            Thread.CurrentThread.CurrentUICulture = new CultureInfo(culture);
6055
        }
6056
        private void cbLang_DropDownClosed(object sender, EventArgs e)
6057
        {
6058
            if (cbLang.SelectedIndex > -1)
6059
            {
6060
                _iUILanguage = cbLang.SelectedIndex;
6061
                ChangeLanguage(_UILanguage[_iUILanguage]);
6062
            }
6063
        }
6064
 
6065
        #endregion functions
6066
    }
6067
 
6068
    /// <summary>
6069
    /// formats the wp datatable values for display in datagrid - this is bound in the datagrid as a converter
6070
    /// </summary>
6071
    public class waypointsConverter : IValueConverter
6072
    {
6073
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
6074
        {
6075
            if (value != null)
6076
            {
6077
                switch ((string)parameter)
6078
                {
6079
                    case "Latitude":
6080
                        return value.ToString() + " °";
6081
                    case "Longitude":
6082
                        return value.ToString() + " °";
6083
                    case "Radius":
6084
                        return value.ToString() + " m";
6085
                    case "Altitude":
6086
                        return value.ToString() + " m";
6087
                    case "ClimbRate":
6088
                        return value.ToString() == "255" ? "Auto" : (System.Convert.ToDouble(value) / 10).ToString("0.0 m/s");
6089
                    case "DelayTime":
6090
                        return value.ToString() + " s";
6091
                    case "Heading":
6092
                        return Waypoints.Heading(System.Convert.ToInt32(value));
6093
                    case "Speed":
6094
                        return Waypoints.WPSpeed(System.Convert.ToInt16(value));
6095
                    case "CamAngle":
6096
                        return Waypoints.CAMAngle(System.Convert.ToInt16(value));
6097
                    case "Type":
6098
                        return ((Waypoints.pointType)(System.Convert.ToInt16(value))).ToString();
6099
                    case "AutoTrigger":
6100
                        return value.ToString() == "0" ? "- - -" : value.ToString() + " m";
6101
                    case "Status":
6102
                        return (Waypoints.status)(System.Convert.ToInt16(value));
6103
                }
6104
 
6105
                return value.ToString();
6106
            }
6107
            else return value;
6108
        }
6109
 
6110
        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
6111
        {
6112
            throw new NotImplementedException();
6113
        }
6114
    }
6115
    public class IniFile
6116
    {
6117
        public string path;
6118
 
6119
        [DllImport("kernel32")]
6120
        private static extern long WritePrivateProfileString(string section,
6121
          string key, string val, string filePath);
6122
 
6123
        [DllImport("kernel32.dll", CharSet = CharSet.Auto)]
6124
        static extern uint GetPrivateProfileSectionNames(IntPtr lpszReturnBuffer,
6125
               uint nSize, string lpFileName);
6126
 
6127
        [DllImport("kernel32")]
6128
        private static extern int GetPrivateProfileString(string section,
6129
          string key, string def, StringBuilder retVal,
6130
          int size, string filePath);
6131
 
6132
        public IniFile(string INIPath)
6133
        {
6134
            path = INIPath;
6135
        }
6136
 
6137
        public void IniWriteValue(string Section, string Key, string Value)
6138
        {
6139
            WritePrivateProfileString(Section, Key, Value, this.path);
6140
        }
6141
 
6142
        public string IniReadValue(string Section, string Key)
6143
        {
6144
            StringBuilder temp = new StringBuilder(255);
6145
            int i = GetPrivateProfileString(Section, Key, "", temp, 255, this.path);
6146
            return temp.ToString();
6147
        }
6148
        //Ini_sections auslesen in String-Array
6149
        public string[] IniSectionNames()
6150
        {
6151
 
6152
            //  uint MAX_BUFFER = 32767;
6153
            uint MAX_BUFFER = 8388608;
6154
            IntPtr pReturnedString = Marshal.AllocCoTaskMem((int)MAX_BUFFER);
6155
            uint bytesReturned = GetPrivateProfileSectionNames(pReturnedString, MAX_BUFFER, this.path);
6156
            if (bytesReturned == 0)
6157
            {
6158
                Marshal.FreeCoTaskMem(pReturnedString);
6159
                return null;
6160
            }
6161
            string local = Marshal.PtrToStringAuto(pReturnedString, (int)bytesReturned).ToString();
6162
            Marshal.FreeCoTaskMem(pReturnedString);
6163
            //use of Substring below removes terminating null for split
6164
            return local.Substring(0, local.Length - 1).Split('\0');
6165
 
6166
 
6167
        }
6168
    }
6169
    /// <summary>
6170
    /// Selected Win AI Function Calls
6171
    /// </summary>
6172
    public class WinApi
6173
    {
6174
        [DllImport("user32.dll", EntryPoint = "GetSystemMetrics")]
6175
        public static extern int GetSystemMetrics(int which);
6176
        [DllImport("user32.dll")]
6177
        public static extern void
6178
                SetWindowPos(IntPtr hwnd, IntPtr hwndInsertAfter,
6179
                             int X, int Y, int width, int height, uint flags);
6180
 
6181
        private const int SM_CXSCREEN = 0;
6182
        private const int SM_CYSCREEN = 1;
6183
        private static IntPtr HWND_TOP = IntPtr.Zero;
6184
        private const int SWP_SHOWWINDOW = 64; // 0x0040
6185
 
6186
        public static int ScreenX
6187
        {
6188
            get { return GetSystemMetrics(SM_CXSCREEN); }
6189
        }
6190
 
6191
        public static int ScreenY
6192
        {
6193
            get { return GetSystemMetrics(SM_CYSCREEN); }
6194
        }
6195
 
6196
        public static void SetWinFullScreen(IntPtr hwnd)
6197
        {
6198
            SetWindowPos(hwnd, HWND_TOP, -8, -7, ScreenX+15, ScreenY+14, SWP_SHOWWINDOW);
6199
        }
6200
    }
6201
    /// <summary>
6202
    /// Class used to preserve / restore state of the window
6203
    /// </summary>
6204
    public class WinState
6205
    {
6206
        private WindowState winState;
6207
        private WindowStyle brdStyle;
6208
        private bool topMost;
6209
        private Rect restore;
6210
        private bool IsMaximized = false;
6211
 
6212
        public bool isMaximized
6213
        {
6214
            get { return IsMaximized; }
6215
        }
6216
        public void Maximize(Window targetForm)
6217
        {
6218
            if (!IsMaximized)
6219
            {
6220
                IsMaximized = true;
6221
                Save(targetForm);
6222
                targetForm.WindowState = WindowState.Maximized;
6223
                targetForm.WindowStyle = WindowStyle.None;
6224
                targetForm.Topmost = true;
6225
                WinApi.SetWinFullScreen(new WindowInteropHelper(targetForm).Handle);
6226
            }
6227
        }
6228
 
6229
        public void Save(Window targetForm)
6230
        {
6231
            winState = targetForm.WindowState;
6232
            brdStyle = targetForm.WindowStyle;
6233
            topMost = targetForm.Topmost;
6234
            restore = targetForm.RestoreBounds;
6235
        }
6236
        public void Restore(Window targetForm)
6237
        {
6238
            targetForm.WindowState = winState;
6239
            targetForm.WindowStyle = brdStyle;
6240
            targetForm.Topmost = topMost;
6241
 
6242
            targetForm.Left = restore.Left;
6243
            targetForm.Top = restore.Top;
6244
            targetForm.Height = restore.Height;
6245
            targetForm.Width = restore.Width;
6246
            IsMaximized = false;
6247
        }
6248
    }
6249
 
6250
    public static class BitmapConversion
6251
    {
6252
        public static System.Drawing.Bitmap ToWinFormsBitmap(this BitmapSource bitmapsource)
6253
        {
6254
            using (MemoryStream stream = new MemoryStream())
6255
            {
6256
                BitmapEncoder enc = new BmpBitmapEncoder();
6257
                enc.Frames.Add(BitmapFrame.Create(bitmapsource));
6258
                enc.Save(stream);
6259
                using (var tempBitmap = new System.Drawing.Bitmap(stream))
6260
                {
6261
                    // According to MSDN, one "must keep the stream open for the lifetime of the Bitmap."
6262
                    // So we return a copy of the new bitmap, allowing us to dispose both the bitmap and the stream.
6263
                    return new System.Drawing.Bitmap(tempBitmap);
6264
                }
6265
            }
6266
        }
6267
        public static BitmapSource ToWpfBitmap(this System.Drawing.Bitmap bitmap)
6268
        {
6269
            using (MemoryStream stream = new MemoryStream())
6270
            {
6271
                bitmap.Save(stream, System.Drawing.Imaging.ImageFormat.Bmp); stream.Position = 0;
6272
                BitmapImage result = new BitmapImage();
6273
                result.BeginInit();
6274
                // According to MSDN, "The default OnDemand cache option retains access to the stream until the image is needed."
6275
                // Force the bitmap to load right now so we can dispose the stream.
6276
                result.CacheOption = BitmapCacheOption.OnLoad;
6277
                result.StreamSource = stream;
6278
                result.EndInit();
6279
                result.Freeze();
6280
                return result;
6281
            }
6282
        }
6283
    }
6284
 
6285
}