Subversion Repositories Projects

Rev

Rev 2545 | Go to most recent revision | Details | Compare with Previous | 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
                {
2554 - 3471
                    bool bError = false;
2545 - 3472
                    int k = 1;
3473
                    for (int i = iStart; i < dtWaypoints.Rows.Count; i++)
3474
                    {
3475
                        k = iStart > 0 ? k : -1;
3476
                        _sendWayPoint(dtWaypoints.Rows[i], k, 'w',false);
3477
 
3478
                        _iWPCount = -1;
3479
                        iTimeout = 0;
3480
                        while (_iWPCount == -1 & iTimeout < _iWPTimeout * 5)
3481
                        {
3482
                            Thread.Sleep(10);
3483
                            iTimeout++;
3484
                        }
3485
                        if (_iWPCount == -1)
3486
                        {
3487
                            Log(LogMsgType.Error, "Timeout while sending list!");
2554 - 3488
                            bError = true;
2545 - 3489
                            break;
3490
                        }
3491
                        Dispatcher.Invoke(() => lblWPCount.Content = _iWPCount.ToString());
3492
                        k++;
3493
                    }
2554 - 3494
                    if(!bError)
3495
                        Log(LogMsgType.Normal, dtWaypoints.Rows.Count.ToString() + " WP sent to Copter");
2545 - 3496
                }
3497
            }
3498
            else
3499
                Log(LogMsgType.Error, "NOT CONNECTED!");
3500
 
3501
        }
3502
        bool _sendWayPoint(DataRow dr, int index, char command,bool bSim)
3503
        {
3504
 
3505
            if (serialPortCtrl.Port.IsOpen)
3506
            {
3507
                byte[] bData = new byte[30];
3508
                for (int i = 0; i < 30; i++)
3509
                    bData[i] = 0;
3510
                Stream serialStream = serialPortCtrl.Port.BaseStream;
3511
                byte[] bytes;
3512
                int iVal;
3513
                double dVal;
3514
                NumberFormatInfo nfi = new NumberFormatInfo();
3515
                nfi.NumberDecimalSeparator = ",";
3516
 
3517
                //longitude
3518
                dVal = Convert.ToDouble(dr[4], nfi);
3519
                iVal = (int)(dVal * Math.Pow(10, 7));
3520
                bData[0] = (byte)(iVal & 0xff);
3521
                bData[1] = (byte)((iVal >> 8) & 0xff);
3522
                bData[2] = (byte)((iVal >> 16) & 0xff);
3523
                bData[3] = (byte)(iVal >> 24);
3524
                //latitude
3525
                dVal = Convert.ToDouble(dr[3], nfi);
3526
                iVal = (int)(dVal * Math.Pow(10, 7));
3527
                bData[4] = (byte)(iVal & 0xff);
3528
                bData[5] = (byte)((iVal >> 8) & 0xff);
3529
                bData[6] = (byte)((iVal >> 16) & 0xff);
3530
                bData[7] = (byte)(iVal >> 24);
3531
                //altitude
3532
                dVal = Convert.ToDouble(dr[5], nfi);
3533
                iVal = (int)(dVal * 10);
3534
                bData[8] = (byte)(iVal & 0xff);
3535
                bData[9] = (byte)((iVal >> 8) & 0xff);
3536
                bData[10] = (byte)((iVal >> 16) & 0xff);
3537
                bData[11] = (byte)(iVal >> 24);
3538
                if(bSim)
3539
                    bData[12] = 3; //Status 'SIMULATE'
3540
                //Status 'NEWDATA'
3541
                else
3542
                    bData[12] = 1;
3543
                //heading
3544
                iVal = Convert.ToInt16(dr[6]);
3545
                bData[13] = (byte)(iVal & 0xff);
3546
                bData[14] = (byte)((iVal >> 8) & 0xff);
3547
                //ToleranceRadius
3548
                bData[15] = Convert.ToByte(dr[9]);
3549
                //HoldTime
3550
                bData[16] = Convert.ToByte(dr[10]);
3551
                //Event_Flag
3552
                bData[17] = Convert.ToByte(dr[13]);
3553
                //Index
3554
                bData[18] = index > -1 ? (byte)index : Convert.ToByte((int)dr[0]);
3555
                //Type
3556
                bData[19] = Convert.ToByte(dr[1]);
3557
                //WP_EventChannelValue
3558
                bData[20] = Convert.ToByte(dr[14]);
3559
                //AltitudeRate
3560
                bData[21] = Convert.ToByte(dr[8]);
3561
                //Speed
3562
                bData[22] = Convert.ToByte(dr[7]);
3563
                //CamAngle
3564
                bData[23] = (byte)Convert.ToInt16(dr[12]);
3565
                //Name
3566
                string s = index > 0 ? ((string)dr[2]).Substring(0, 1) + index.ToString() : (string)dr[2];
3567
                byte[] name = ASCIIEncoding.ASCII.GetBytes(s);
3568
                bData[24] = name.Length > 0 ? name[0] : (byte)0;
3569
                bData[25] = name.Length > 1 ? name[1] : (byte)0;
3570
                bData[26] = name.Length > 2 ? name[2] : (byte)0;
3571
                bData[27] = name.Length > 3 ? name[3] : (byte)0;
3572
                //Autotrigger
3573
                bData[28] = Convert.ToByte(dr[11]);
3574
 
3575
                bytes = FlightControllerMessage.CreateMessage(command, 2, bData);
3576
                serialStream.Write(bytes, 0, bytes.Length);
3577
 
3578
                return true;
3579
            }
3580
 
3581
            return false;
3582
        }
3583
        #region OSD-Menue
3584
 
3585
        /// <summary>
3586
        /// one time query of the OSD Menue with pagenumber
3587
        /// </summary>
3588
        /// <param name="iMenue">Menue page</param>
3589
        void _OSDMenue(int iMenue)
3590
        {
3591
            if (serialPortCtrl.Port.IsOpen)
3592
            {
3593
                if (iMenue > iOSDMax)
3594
                    iMenue = 0;
3595
                Stream serialStream = serialPortCtrl.Port.BaseStream;
3596
                byte[] bytes = FlightControllerMessage.CreateMessage('l', 0, new byte[1] { (byte)iMenue });
3597
                serialStream.Write(bytes, 0, bytes.Length);
3598
            }
3599
            else
3600
                Log(LogMsgType.Error, "NOT CONNECTED!");
3601
 
3602
        }
3603
        /// <summary>
3604
        /// call the OSDMenue and start autorefresh
3605
        ///  usually by sending a menuekey
3606
        /// 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)
3607
        /// therefore the value has to be negative (inverted) in order to distinguish from old (2 line) menuestyle
3608
        /// and must not have any bits of the menue keys 0x1 0x2 0x4 0x8 (0x10?) --> 0x20 = -33
3609
        /// </summary>
3610
        void _OSDMenueAutoRefresh()
3611
        {
3612
            _sendControllerMessage('h', 0, new byte[2] { unchecked((byte)(-33)), OSDInterval });
3613
        }
3614
        void _OSDMenueAutoRefresh(byte key)
3615
        {
3616
            _sendControllerMessage('h', 0, new byte[2] { unchecked((byte)~key), OSDInterval });
3617
        }
3618
        /// <summary>
3619
        /// initialize the OSD menue combobox
3620
        /// combox is filled by numbers from 0 to max pagenumber
3621
        /// </summary>
3622
        void _initOSDCB()
3623
        {
3624
            _bCBInit = true;
3625
            if (iOSDMax == 0)
3626
            {
3627
                _OSDMenue(0);
3628
                Thread.Sleep(10);
3629
            }
3630
            Dispatcher.Invoke((Action)(() => cbOSD.Items.Clear()));
3631
            for (int i = 0; i <= iOSDMax; i++)
3632
            {
3633
                Dispatcher.Invoke((Action)(() => cbOSD.Items.Add(i)));
3634
            }
3635
            Dispatcher.Invoke((Action)(() => cbOSD.SelectedItem = iOSDPage));
3636
            _bCBInit = false;
3637
        }
3638
        private void btnOSDForward_Click(object sender, RoutedEventArgs e)
3639
        {
3640
            iOSDPage++;
3641
            if (iOSDPage > iOSDMax)
3642
                iOSDPage = 0;
3643
 
3644
            _OSDMenue(iOSDPage);
3645
        }
3646
        private void btnOSDBackward_Click(object sender, RoutedEventArgs e)
3647
        {
3648
            iOSDPage--;
3649
            if (iOSDPage < 0)
3650
                iOSDPage = iOSDMax;
3651
 
3652
            _OSDMenue(iOSDPage);
3653
        }
3654
        private void btnOSDLeave_Click(object sender, RoutedEventArgs e)
3655
        {
3656
            _OSDMenueAutoRefresh(8);
3657
        }
3658
        private void btnOSDEnter_Click(object sender, RoutedEventArgs e)
3659
        {
3660
            _OSDMenueAutoRefresh(4);
3661
        }
3662
        private void cbOSD_DropDownClosing(object sender, EventArgs e)
3663
        {
3664
            if (!_bCBInit && cbOSD.SelectedIndex > -1)
3665
                _OSDMenue(cbOSD.SelectedIndex);
3666
        }
3667
        private void OSD(LogMsgType msgtype, string msg, bool bNew)
3668
        {
3669
            Dispatcher.Invoke(() =>
3670
            {
3671
                TextRange tr;
3672
                if (bNew)
3673
                {
3674
                    rtfOSD.SelectAll();
3675
                    rtfOSD.Selection.Text = string.Empty;
3676
                }
3677
                tr = new TextRange(rtfOSD.Document.ContentEnd, rtfOSD.Document.ContentEnd);
3678
                tr.Text = msg;
3679
                tr.ApplyPropertyValue(TextElement.ForegroundProperty, new SolidColorBrush(LogMsgTypeColor[(int)msgtype]));
3680
                //     rtfOSD.AppendText("\r");
3681
                rtfOSD.ScrollToEnd();
3682
 
3683
            });
3684
        }
3685
 
3686
        #endregion OSD-Menue
3687
 
3688
        #endregion controller messages
3689
 
3690
        void _mediaPlayer(object file)
3691
        {
3692
            Monitor.TryEnter(lockObj);
3693
            try
3694
            {
3695
                if (File.Exists((string)file))
3696
                {
3697
 
3698
                    mediaPlayer.Open((string)file);
3699
                    mediaPlayer.Play();
3700
                }
3701
                else
3702
                    Log(LogMsgType.Warning, "File not found: " + file.ToString());
3703
 
3704
            }
3705
            finally
3706
            {
3707
                Monitor.Exit(lockObj);
3708
            }
3709
        }
3710
 
3711
        #region ui
3712
        /// <summary>
3713
        /// Switch between fullscreen and normal window mode
3714
        /// save & restore scaling settings
3715
        /// </summary>
3716
        /// <param name="sender"></param>
3717
        /// <param name="e"></param>
3718
        private void imageFullscreen_MouseDown(object sender, MouseButtonEventArgs e)
3719
        {
3720
            if (winState.isMaximized)
3721
            {
3722
                winState.Restore(this);
3723
                imageFullscreen.Source = new BitmapImage(new Uri("Images/Fullscreen.png", UriKind.Relative));
3724
                if(_bSaveWinStateFull)
3725
                    _saveScaleSliders(true);
3726
                if(_bSaveWinStateNormal)
3727
                    _setScaleSliders(false);
3728
            }
3729
            else
3730
            {
3731
                winState.Maximize(this);
3732
                imageFullscreen.Source = new BitmapImage(new Uri("Images/RestoreScreen.png", UriKind.Relative));
3733
                if(_bSaveWinStateNormal)
3734
                    _saveScaleSliders(false);
3735
                if(_bSaveWinStateFull)
3736
                    _setScaleSliders(true);
3737
            }
3738
        }
3739
 
3740
        /// <summary>
3741
        /// reset the scaling of all UI elements to default
3742
        /// </summary>
3743
        /// <param name="sender"></param>
3744
        /// <param name="e"></param>
3745
        private void buttonUIScaleReset_Click(object sender, RoutedEventArgs e)
3746
        {
3747
            UIScaleHorizonSlider.Value =
3748
                UIScaleLOGSlider.Value =
3749
                UIScaleMotorsSlider.Value =
3750
                UIScaleOSDSlider.Value =
3751
                UIScaleSlider.Value =
3752
                UIScaleTopSlider.Value = 1;
3753
        }
3754
        /// <summary>
3755
        /// adjust the top postion of UI elements below the top bar to fit the bottom position of the bar when scaling the top bar
3756
        /// </summary>
3757
        /// <param name="sender"></param>
3758
        /// <param name="e"></param>
3759
        private void UIScaleTopSlider_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
3760
        {
3761
            GridSettings.Margin = new Thickness(GridSettings.Margin.Left, 36 * UIScaleTopSlider.Value, GridSettings.Margin.Right, GridSettings.Margin.Bottom);
3762
            if (GridMotors != null)
3763
                GridMotors.Margin = new Thickness(GridMotors.Margin.Left, 36 * UIScaleTopSlider.Value, GridMotors.Margin.Right, GridMotors.Margin.Bottom);
3764
            if (GridSideBar != null)
3765
                GridSideBar.Margin = new Thickness(GridSideBar.Margin.Left, 36 * UIScaleTopSlider.Value, GridSideBar.Margin.Right, GridSideBar.Margin.Bottom);
3766
            if (WPStatus != null)
3767
                WPStatus.Margin = new Thickness(WPStatus.Margin.Left, 36 * UIScaleTopSlider.Value, WPStatus.Margin.Right, WPStatus.Margin.Bottom);
3768
            if (GridOSD != null)
3769
            {
3770
                if(WPStatus.Visibility == Visibility.Visible)
3771
                    GridOSD.Margin = new Thickness(GridOSD.Margin.Left, 36 * UIScaleTopSlider.Value + WPStatus.Margin.Bottom, GridOSD.Margin.Right, GridOSD.Margin.Bottom);
3772
                else
3773
                    GridOSD.Margin = new Thickness(GridOSD.Margin.Left, 36 * UIScaleTopSlider.Value, GridOSD.Margin.Right, GridOSD.Margin.Bottom);
3774
            }
3775
            if (GridData != null)
3776
                GridData.Margin = new Thickness(GridData.Margin.Left, 36 * UIScaleTopSlider.Value, GridData.Margin.Right, GridData.Margin.Bottom);
3777
            if (GridWP != null)
3778
                GridWP.Margin = new Thickness(GridWP.Margin.Left, 36 * UIScaleTopSlider.Value, GridWP.Margin.Right, GridWP.Margin.Bottom);
3779
        }
3780
        private void UIScaleOSDSlider_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
3781
        {
3782
            if (!_init)
3783
            {
3784
                if (WPStatus != null && (WPStatus.Visibility == Visibility.Visible))
3785
                    GridOSD.Margin = new Thickness(GridOSD.Margin.Left, 36 * UIScaleTopSlider.Value + 36, GridOSD.Margin.Right, GridOSD.Margin.Bottom);
3786
                else
3787
                    GridOSD.Margin = new Thickness(GridOSD.Margin.Left, 36 * UIScaleTopSlider.Value, GridOSD.Margin.Right, GridOSD.Margin.Bottom);
3788
            }
3789
        }
3790
 
3791
        /// <summary>
3792
        /// restore the saved scalings for the fullscreen/normal window mode
3793
        /// </summary>
3794
        /// <param name="bFull">the mode the window is set to</param>
3795
        void _setScaleSliders(bool bFull)
3796
        {
3797
            if(bFull)
3798
            {
3799
                UIScaleSlider.Value = scaleFullAll;
3800
                UIScaleTopSlider.Value = scaleFullTopBar;
3801
                UIScaleMotorsSlider.Value = scaleFullMotors;
3802
                UIScaleOSDSlider.Value = scaleFullOSD;
3803
                UIScaleLOGSlider.Value = scaleFullLOG;
3804
                UIScaleHorizonSlider.Value = scaleFullHorizon;
3805
            }
3806
            else
3807
            {
3808
                UIScaleSlider.Value = scaleNormalAll;
3809
                UIScaleTopSlider.Value = scaleNormalTopBar;
3810
                UIScaleMotorsSlider.Value = scaleNormalMotors;
3811
                UIScaleOSDSlider.Value = scaleNormalOSD;
3812
                UIScaleLOGSlider.Value = scaleNormalLOG;
3813
                UIScaleHorizonSlider.Value = scaleNormalHorizon;
3814
            }
3815
        }
3816
 
3817
        /// <summary>
3818
        /// save the scalings for the actual window mode
3819
        /// </summary>
3820
        /// <param name="bFull">the actual window mode</param>
3821
        void _saveScaleSliders(bool bFull)
3822
        {
3823
 
3824
            if (bFull)
3825
            {
3826
                scaleFullAll = UIScaleSlider.Value;
3827
                scaleFullTopBar = UIScaleTopSlider.Value;
3828
                scaleFullMotors = UIScaleMotorsSlider.Value;
3829
                scaleFullOSD = UIScaleOSDSlider.Value;
3830
                scaleFullLOG = UIScaleLOGSlider.Value;
3831
                scaleFullHorizon = UIScaleHorizonSlider.Value;
3832
            }
3833
            else
3834
            {
3835
                scaleNormalAll = UIScaleSlider.Value;
3836
                scaleNormalTopBar = UIScaleTopSlider.Value;
3837
                scaleNormalMotors = UIScaleMotorsSlider.Value;
3838
                scaleNormalOSD = UIScaleOSDSlider.Value;
3839
                scaleNormalLOG = UIScaleLOGSlider.Value;
3840
                scaleNormalHorizon = UIScaleHorizonSlider.Value;
3841
            }
3842
        }
3843
        #endregion ui
3844
 
3845
        #region ini
3846
        /// <summary>
3847
        /// read settings from ini-file
3848
        /// </summary>
3849
        void _readIni()
3850
        {
3851
            if (!File.Exists(filePath + "\\MKLiveViewSettings.ini"))
3852
                _writeIni();
3853
            IniFile ini = new IniFile("MKLiveViewSettings.ini");
3854
            ini.path = filePath + "\\MKLiveViewSettings.ini";
3855
            try
3856
            {
3857
 
3858
                string sVal = ini.IniReadValue("timings", "AutorefreshDebugData");
3859
                if (sVal != "") _debugDataAutorefresh = Convert.ToBoolean(sVal);
3860
                sVal = ini.IniReadValue("timings", "AutorefreshNavCtrlData");
3861
                if (sVal != "") _navCtrlDataAutorefresh = Convert.ToBoolean(sVal);
3862
                sVal = ini.IniReadValue("timings", "AutorefreshBLCtrlData");
3863
                if (sVal != "") _blctrlDataAutorefresh = Convert.ToBoolean(sVal);
3864
                sVal = ini.IniReadValue("timings", "AutorefreshOSDData");
3865
                if (sVal != "") _OSDAutorefresh = Convert.ToBoolean(sVal);
3866
 
3867
                sVal = ini.IniReadValue("timings", "IntervalDebugData");
3868
                if (sVal != "") debugInterval = (byte)Convert.ToInt16(sVal);
3869
                sVal = ini.IniReadValue("timings", "IntervalNavCtrlData");
3870
                if (sVal != "") navctrlInterval = (byte)Convert.ToInt16(sVal);
3871
                sVal = ini.IniReadValue("timings", "IntervalBLCtrlData");
3872
                if (sVal != "") blctrlInterval = (byte)Convert.ToInt16(sVal);
3873
                sVal = ini.IniReadValue("timings", "IntervalOSDData");
3874
                if (sVal != "") OSDInterval = (byte)Convert.ToInt16(sVal);
3875
 
3876
                sVal = ini.IniReadValue("topBar", "voltage");
3877
                if (sVal != "") chkBoxTopBarShowVoltage.IsChecked = Convert.ToBoolean(sVal);
3878
                sVal = ini.IniReadValue("topBar", "capacity");
3879
                if (sVal != "") chkBoxTopBarShowCapacity.IsChecked = Convert.ToBoolean(sVal);
3880
                sVal = ini.IniReadValue("topBar", "current");
3881
                if (sVal != "") chkBoxTopBarShowCurrent.IsChecked = Convert.ToBoolean(sVal);
3882
                sVal = ini.IniReadValue("topBar", "flightTime");
3883
                if (sVal != "") chkBoxTopBarShowFlightTime.IsChecked = Convert.ToBoolean(sVal);
3884
                sVal = ini.IniReadValue("topBar", "distanceHP");
3885
                if (sVal != "") chkBoxTopBarShowDistanceHP.IsChecked = Convert.ToBoolean(sVal);
3886
                sVal = ini.IniReadValue("topBar", "height");
3887
                if (sVal != "") chkBoxTopBarShowHeight.IsChecked = Convert.ToBoolean(sVal);
3888
                sVal = ini.IniReadValue("topBar", "speed");
3889
                if (sVal != "") chkBoxTopBarShowSpeed.IsChecked = Convert.ToBoolean(sVal);
3890
                sVal = ini.IniReadValue("topBar", "magneticField");
3891
                if (sVal != "") chkBoxTopBarShowMF.IsChecked = Convert.ToBoolean(sVal);
3892
                sVal = ini.IniReadValue("topBar", "satellites");
3893
                if (sVal != "") chkBoxTopBarShowSatellites.IsChecked = Convert.ToBoolean(sVal);
3894
                sVal = ini.IniReadValue("topBar", "rc");
3895
                if (sVal != "") chkBoxTopBarShowRC.IsChecked = Convert.ToBoolean(sVal);
3896
 
3897
                sVal = ini.IniReadValue("style", "saveFullScreen");
3898
                if (sVal != "") chkBoxSaveFullScreenState.IsChecked = Convert.ToBoolean(sVal);
3899
                sVal = ini.IniReadValue("style", "saveNormalState");
3900
                if (sVal != "") chkBoxSaveNormalState.IsChecked = Convert.ToBoolean(sVal);
3901
 
3902
                sVal = ini.IniReadValue("style", "scaleNormalAll");
3903
                if (sVal != "") scaleNormalAll = Convert.ToDouble(sVal);
3904
                sVal = ini.IniReadValue("style", "scaleNormalTopBar");
3905
                if (sVal != "") scaleNormalTopBar = Convert.ToDouble(sVal);
3906
                sVal = ini.IniReadValue("style", "scaleNormalMotors");
3907
                if (sVal != "") scaleNormalMotors = Convert.ToDouble(sVal);
3908
                sVal = ini.IniReadValue("style", "scaleNormalOSD");
3909
                if (sVal != "") scaleNormalOSD = Convert.ToDouble(sVal);
3910
                sVal = ini.IniReadValue("style", "scaleNormalLOG");
3911
                if (sVal != "") scaleNormalLOG = Convert.ToDouble(sVal);
3912
                sVal = ini.IniReadValue("style", "scaleNormalHorizon");
3913
                if (sVal != "") scaleNormalHorizon = Convert.ToDouble(sVal);
3914
 
3915
                sVal = ini.IniReadValue("style", "scaleFullAll");
3916
                if (sVal != "") scaleFullAll = Convert.ToDouble(sVal);
3917
                sVal = ini.IniReadValue("style", "scaleFullTopBar");
3918
                if (sVal != "") scaleFullTopBar = Convert.ToDouble(sVal);
3919
                sVal = ini.IniReadValue("style", "scaleFullMotors");
3920
                if (sVal != "") scaleFullMotors = Convert.ToDouble(sVal);
3921
                sVal = ini.IniReadValue("style", "scaleFullOSD");
3922
                if (sVal != "") scaleFullOSD = Convert.ToDouble(sVal);
3923
                sVal = ini.IniReadValue("style", "scaleFullLOG");
3924
                if (sVal != "") scaleFullLOG = Convert.ToDouble(sVal);
3925
                sVal = ini.IniReadValue("style", "scaleFullHorizon");
3926
                if (sVal != "") scaleFullHorizon = Convert.ToDouble(sVal);
3927
 
3928
                sVal = ini.IniReadValue("general", "LiPoCells");
3929
                _LipoCells = Convert.ToInt16(sVal);
3930
                sVal = ini.IniReadValue("general", "LiPoAutoDetect");
3931
                _bLiPoAutoDetect = Convert.ToBoolean(sVal);
3932
                sVal = ini.IniReadValue("general", "Motors");
3933
                if (sVal != "") _iMotors = Convert.ToInt16(sVal);
3934
                sVal = ini.IniReadValue("general", "UILanguage");
3935
                if (sVal != "") _iUILanguage = Convert.ToInt16(sVal);
3936
 
3937
                sVal = ini.IniReadValue("map", "followMe");
3938
                if (sVal != "") _bFollowCopter = Convert.ToBoolean(sVal);
3939
                sVal = ini.IniReadValue("map", "location");
3940
                if (sVal != "") _mapPosition = sVal;
3941
                sVal = ini.IniReadValue("map", "AutoSetHome");
3942
                if (sVal != "") _bAutoHome = Convert.ToBoolean(sVal);
3943
                sVal = ini.IniReadValue("map", "GPXLog");
3944
                if (sVal != "") _bGPXLog = Convert.ToBoolean(sVal);
3945
 
3946
                sVal = ini.IniReadValue("threshold", "VoltageWarning");
3947
                if(sVal != "") _dThresholdVoltageWarn = Convert.ToDouble(sVal);
3948
                sVal = ini.IniReadValue("threshold", "VoltageCritical");
3949
                if(sVal != "") _dThresholdVoltageCrit = Convert.ToDouble(sVal);
3950
                sVal = ini.IniReadValue("threshold", "VoiceVoltageEnable");
3951
                if(sVal != "") _bVoiceVoltPlay = Convert.ToBoolean(sVal);
3952
                sVal = ini.IniReadValue("threshold", "VoiceSatFixEnable");
3953
                if(sVal != "") _bVoiceSatFixPlay = Convert.ToBoolean(sVal);
3954
                sVal = ini.IniReadValue("threshold", "VoiceMagFieldEnable");
3955
                if(sVal != "") _bVoiceMagneticFieldPlay = Convert.ToBoolean(sVal);
3956
                sVal = ini.IniReadValue("threshold", "DistanceWarning");
3957
                if(sVal != "") _dThresholdDistanceWarn = Convert.ToDouble(sVal);
3958
                sVal = ini.IniReadValue("threshold", "VoiceDistanceWarnEnable");
3959
                if(sVal != "") _bVoiceDistancePlay = Convert.ToBoolean(sVal);
3960
                sVal = ini.IniReadValue("threshold", "VoiceRCLevelWarnEnable");
3961
                if(sVal != "") _bVoiceRCLevelPlay = Convert.ToBoolean(sVal);
3962
                sVal = ini.IniReadValue("threshold", "MaxDistance");
3963
                if(sVal != "") _dThresholdDistanceMax = Convert.ToDouble(sVal);
3964
                sVal = ini.IniReadValue("threshold", "RCThreshold");
3965
                if(sVal != "") _iThresholdRC = Convert.ToInt32(sVal);
3966
                sVal = ini.IniReadValue("threshold", "MagFieldThreshold");
3967
                if(sVal != "") _iThresholdMagField = Convert.ToInt32(sVal);
3968
                sVal = ini.IniReadValue("threshold", "BLCtrlTemp");
3969
                if(sVal != "") _iThresholdBLCTRLTempWarn = Convert.ToInt32(sVal);
3970
                sVal = ini.IniReadValue("threshold", "VoiceBLCtrlTempEnable");
3971
                if(sVal != "") _bVoiceBLCTRLTempPlay = Convert.ToBoolean(sVal);
3972
                sVal = ini.IniReadValue("threshold", "VoiceLanguageIndex");
3973
                if(sVal != "") _iVoiceIndex = Convert.ToInt32(sVal);
3974
 
3975
                sVal = ini.IniReadValue("waypoints", "wpcolor");
3976
                if(sVal != "") comboBoxWPColor.SelectedIndex = Convert.ToInt32(sVal);
3977
                sVal = ini.IniReadValue("waypoints", "poicolor");
3978
                if(sVal != "") comboBoxPOIColor.SelectedIndex = Convert.ToInt32(sVal);
3979
                sVal = ini.IniReadValue("waypoints", "fscolor");
3980
                if(sVal != "") comboBoxFSColor.SelectedIndex = Convert.ToInt32(sVal);
3981
                sVal = ini.IniReadValue("waypoints", "coptercolor");
3982
                if(sVal != "") comboBoxCopterColor.SelectedIndex = Convert.ToInt32(sVal);
3983
                sVal = ini.IniReadValue("waypoints", "copterheadingcolor");
3984
                if(sVal != "") comboBoxCopterHeadingColor.SelectedIndex = Convert.ToInt32(sVal);
3985
                sVal = ini.IniReadValue("waypoints", "landingcolor");
3986
                if(sVal != "") comboBoxLandingColor.SelectedIndex = Convert.ToInt32(sVal);
3987
                sVal = ini.IniReadValue("waypoints", "routecolor");
3988
                if(sVal != "") comboBoxRouteColor.SelectedIndex = Convert.ToInt32(sVal);
3989
                sVal = ini.IniReadValue("waypoints", "showWPRoute");
3990
                if(sVal != "") _bShowWPRoute = Convert.ToBoolean(sVal);
3991
                sVal = ini.IniReadValue("waypoints", "autoShowWPEdit");
3992
                if(sVal != "") _bAutoWPEdit = Convert.ToBoolean(sVal);
3993
                sVal = ini.IniReadValue("waypoints", "showWPMaxRange");
3994
                if(sVal != "") checkBoxShowWPMaxRange.IsChecked = Convert.ToBoolean(sVal);
3995
                sVal = ini.IniReadValue("waypoints", "WPMaxRangecolor");
3996
                if(sVal != "") comboBoxWPMaxRangeColor.SelectedIndex = Convert.ToInt32(sVal);
3997
                sVal = ini.IniReadValue("waypoints", "WPDefPrefix");
3998
                if(sVal != "") _wpDefPrefix = sVal;
3999
                sVal = ini.IniReadValue("waypoints", "WPDefAltitude");
4000
                if(sVal != "") _wpDefAltitude = Convert.ToInt32(sVal);
4001
                sVal = ini.IniReadValue("waypoints", "WPDefHeading");
4002
                if(sVal != "") _wpDefHeading = Convert.ToInt32(sVal);
4003
                sVal = ini.IniReadValue("waypoints", "WPDefCBoxHeading");
4004
                if(sVal != "") _wpDefCBoxHeading = Convert.ToInt32(sVal);
4005
                sVal = ini.IniReadValue("waypoints", "WPDefSpeed");
4006
                if(sVal != "") _wpDefSpeed = Convert.ToInt32(sVal);
4007
                sVal = ini.IniReadValue("waypoints", "WPDefCBoxSpeed");
4008
                if(sVal != "") _wpDefCBoxSpeed = Convert.ToInt32(sVal);
4009
                sVal = ini.IniReadValue("waypoints", "WPDefClimb");
4010
                if(sVal != "") _wpDefClimb = Convert.ToInt32(sVal);
4011
                sVal = ini.IniReadValue("waypoints", "WPDefCBoxClimb");
4012
                if(sVal != "") _wpDefCBoxClimb = Convert.ToInt32(sVal);
4013
                sVal = ini.IniReadValue("waypoints", "WPDefRadius");
4014
                if(sVal != "") _wpDefRadius = Convert.ToInt32(sVal);
4015
                sVal = ini.IniReadValue("waypoints", "WPDefHoldtime");
4016
                if(sVal != "") _wpDefHoldtime = Convert.ToInt32(sVal);
4017
                sVal = ini.IniReadValue("waypoints", "WPDefAutotrig");
4018
                if(sVal != "") _wpDefAutotrig = Convert.ToInt32(sVal);
4019
                sVal = ini.IniReadValue("waypoints", "WPDefCamangle");
4020
                if(sVal != "") _wpDefCamangle = Convert.ToInt32(sVal);
4021
                sVal = ini.IniReadValue("waypoints", "WPDefCBoxCamangle");
4022
                if(sVal != "") _wpDefCBoxCamangle = Convert.ToInt32(sVal);
4023
                sVal = ini.IniReadValue("waypoints", "WPDefOut1");
4024
                if(sVal != "") _wpDefOut1 = Convert.ToInt32(sVal);
4025
                sVal = ini.IniReadValue("waypoints", "WPAddCopterHeight");
4026
                if (sVal != "") _wpAddCopterHeight = Convert.ToBoolean(sVal);
4027
                sVal = ini.IniReadValue("waypoints", "WPAddCopterHeading");
4028
                if (sVal != "") _wpAddCopterHeading = Convert.ToBoolean(sVal);
4029
                sVal = ini.IniReadValue("waypoints", "CopterSize");
4030
                if (sVal != "") SliderCopterZoom.Value = Convert.ToDouble(sVal);
4031
                sVal = ini.IniReadValue("waypoints", "WPSize");
4032
                if (sVal != "") SliderWPZoom.Value = Convert.ToDouble(sVal);
4033
 
4034
                sVal = ini.IniReadValue("cam", "CamImagePosLeft");
4035
                if (sVal != "") _camImageMargin.Left = Convert.ToDouble(sVal);
4036
                sVal = ini.IniReadValue("cam", "CamImagePosTop");
4037
                if (sVal != "") _camImageMargin.Top = Convert.ToDouble(sVal);
4038
                sVal = ini.IniReadValue("cam", "CamImageZoom");
4039
                if (sVal != "") SliderCamZoom.Value = Convert.ToDouble(sVal);
4040
 
4041
                for (int i = 0; i < 12; i++)
4042
                {
4043
                    sVal = ini.IniReadValue("serial", "ch" + i.ToString() + "Val");
4044
                    if (sVal != "")
4045
                        serChan[i] = Convert.ToInt16(sVal);
4046
                    sVal = ini.IniReadValue("serial", "ch" + i.ToString() + "Title");
4047
                    if (sVal != "")
4048
                        serChanTitle[i] = sVal;
4049
                    for (int y = 0; i < 4 && y < 3; y++)
4050
                    {
4051
                        sVal = ini.IniReadValue("serial", "ch" + i.ToString() + "ValSub" + y.ToString());
4052
                        if (sVal != "")
4053
                            serChan_sub[(i * 3) + y] = Convert.ToInt16(sVal);
4054
                    }
4055
                }
4056
 
4057
            }
4058
            catch (Exception e)
4059
            {
4060
 
4061
                MessageBox.Show("Error parsing ini-file!" + Environment.NewLine + e.Message,"Read ini-file" ,MessageBoxButton.OK,MessageBoxImage.Error);
4062
            }
4063
 
4064
        }
4065
 
4066
        /// <summary>
4067
        /// save settings to ini-file
4068
        /// </summary>
4069
        void _writeIni()
4070
        {
4071
 
4072
            IniFile ini = new IniFile("MKLiveViewSettings.ini");
4073
            ini.path = filePath + "\\MKLiveViewSettings.ini";
4074
 
4075
            try
4076
            {
4077
 
4078
                ini.IniWriteValue("timings", "AutorefreshDebugData", _debugDataAutorefresh ? "true" : "false");
4079
                ini.IniWriteValue("timings", "AutorefreshNavCtrlData", _navCtrlDataAutorefresh ? "true" : "false");
4080
                ini.IniWriteValue("timings", "AutorefreshBLCtrlData", _blctrlDataAutorefresh ? "true" : "false");
4081
                ini.IniWriteValue("timings", "AutorefreshOSDData", _OSDAutorefresh ? "true" : "false");
4082
 
4083
                ini.IniWriteValue("timings", "IntervalDebugData", debugInterval.ToString());
4084
                ini.IniWriteValue("timings", "IntervalNavCtrlData", navctrlInterval.ToString());
4085
                ini.IniWriteValue("timings", "IntervalBLCtrlData", blctrlInterval.ToString());
4086
                ini.IniWriteValue("timings", "IntervalOSDData", OSDInterval.ToString());
4087
 
4088
                ini.IniWriteValue("general", "LiPoCells", _LipoCells.ToString());
4089
                ini.IniWriteValue("general", "LiPoAutoDetect", _bLiPoAutoDetect.ToString());
4090
                ini.IniWriteValue("general", "Motors", _iMotors.ToString());
4091
                ini.IniWriteValue("general", "UILanguage", _iUILanguage.ToString());
4092
 
4093
                ini.IniWriteValue("map", "location", _mapPosition);
4094
                ini.IniWriteValue("map", "followMe", _bFollowCopter.ToString());
4095
                ini.IniWriteValue("map", "AutoSetHome", _bAutoHome.ToString());
4096
                ini.IniWriteValue("map", "GPXLog", _bGPXLog.ToString());
4097
 
4098
                ini.IniWriteValue("topBar", "voltage", chkBoxTopBarShowVoltage.IsChecked.ToString());
4099
                ini.IniWriteValue("topBar", "capacity", chkBoxTopBarShowCapacity.IsChecked.ToString());
4100
                ini.IniWriteValue("topBar", "current", chkBoxTopBarShowCurrent.IsChecked.ToString());
4101
                ini.IniWriteValue("topBar", "flightTime", chkBoxTopBarShowFlightTime.IsChecked.ToString());
4102
                ini.IniWriteValue("topBar", "distanceHP", chkBoxTopBarShowDistanceHP.IsChecked.ToString());
4103
                ini.IniWriteValue("topBar", "height", chkBoxTopBarShowHeight.IsChecked.ToString());
4104
                ini.IniWriteValue("topBar", "speed", chkBoxTopBarShowSpeed.IsChecked.ToString());
4105
                ini.IniWriteValue("topBar", "magneticField", chkBoxTopBarShowMF.IsChecked.ToString());
4106
                ini.IniWriteValue("topBar", "satellites", chkBoxTopBarShowSatellites.IsChecked.ToString());
4107
                ini.IniWriteValue("topBar", "rc", chkBoxTopBarShowRC.IsChecked.ToString());
4108
 
4109
                ini.IniWriteValue("style", "saveFullScreen", chkBoxSaveFullScreenState.IsChecked.ToString());
4110
                ini.IniWriteValue("style", "saveNormalState", chkBoxSaveNormalState.IsChecked.ToString());
4111
 
4112
                ini.IniWriteValue("style", "scaleNormalAll", scaleNormalAll.ToString());
4113
                ini.IniWriteValue("style", "scaleNormalTopBar", scaleNormalTopBar.ToString());
4114
                ini.IniWriteValue("style", "scaleNormalMotors", scaleNormalMotors.ToString());
4115
                ini.IniWriteValue("style", "scaleNormalOSD", scaleNormalOSD.ToString());
4116
                ini.IniWriteValue("style", "scaleNormalLOG", scaleNormalLOG.ToString());
4117
                ini.IniWriteValue("style", "scaleNormalHorizon", scaleNormalHorizon.ToString());
4118
 
4119
                ini.IniWriteValue("style", "scaleFullAll", scaleFullAll.ToString());
4120
                ini.IniWriteValue("style", "scaleFullTopBar", scaleFullTopBar.ToString());
4121
                ini.IniWriteValue("style", "scaleFullMotors", scaleFullMotors.ToString());
4122
                ini.IniWriteValue("style", "scaleFullOSD", scaleFullOSD.ToString());
4123
                ini.IniWriteValue("style", "scaleFullLOG", scaleFullLOG.ToString());
4124
                ini.IniWriteValue("style", "scaleFullHorizon", scaleFullHorizon.ToString());
4125
 
4126
                ini.IniWriteValue("style", "horizon", chkBoxShowHorizon.IsChecked.ToString());
4127
 
4128
                ini.IniWriteValue("threshold", "VoltageWarning", _dThresholdVoltageWarn.ToString());
4129
                ini.IniWriteValue("threshold", "VoltageCritical", _dThresholdVoltageCrit.ToString());
4130
                ini.IniWriteValue("threshold", "VoiceVoltageEnable", _bVoiceVoltPlay.ToString());
4131
                ini.IniWriteValue("threshold", "VoiceSatFixEnable", _bVoiceSatFixPlay.ToString());
4132
                ini.IniWriteValue("threshold", "VoiceMagFieldEnable", _bVoiceMagneticFieldPlay.ToString());
4133
                ini.IniWriteValue("threshold", "VoiceDistanceWarnEnable", _bVoiceDistancePlay.ToString());
4134
                ini.IniWriteValue("threshold", "VoiceRCLevelWarnEnable", _bVoiceRCLevelPlay.ToString());
4135
                ini.IniWriteValue("threshold", "DistanceWarning", _dThresholdDistanceWarn.ToString());
4136
                ini.IniWriteValue("threshold", "MaxDistance", _dThresholdDistanceMax.ToString());
4137
                ini.IniWriteValue("threshold", "RCThreshold", _iThresholdRC.ToString());
4138
                ini.IniWriteValue("threshold", "MagFieldThreshold", _iThresholdMagField.ToString());
4139
                ini.IniWriteValue("threshold", "BLCtrlTemp", _iThresholdBLCTRLTempWarn.ToString());
4140
                ini.IniWriteValue("threshold", "VoiceBLCtrlTempEnable", _bVoiceBLCTRLTempPlay.ToString());
4141
                ini.IniWriteValue("threshold", "VoiceLanguageIndex", _iVoiceIndex.ToString());
4142
 
4143
                ini.IniWriteValue("waypoints", "wpcolor", comboBoxWPColor.SelectedIndex.ToString());
4144
                ini.IniWriteValue("waypoints", "poicolor", comboBoxPOIColor.SelectedIndex.ToString());
4145
                ini.IniWriteValue("waypoints", "fscolor", comboBoxFSColor.SelectedIndex.ToString());
4146
                ini.IniWriteValue("waypoints", "coptercolor", comboBoxCopterColor.SelectedIndex.ToString());
4147
                ini.IniWriteValue("waypoints", "copterheadingcolor", comboBoxCopterHeadingColor.SelectedIndex.ToString());
4148
                ini.IniWriteValue("waypoints", "landingcolor", comboBoxLandingColor.SelectedIndex.ToString());
4149
                ini.IniWriteValue("waypoints", "routecolor", comboBoxRouteColor.SelectedIndex.ToString());
4150
                ini.IniWriteValue("waypoints", "showWPRoute", _bShowWPRoute.ToString());
4151
                ini.IniWriteValue("waypoints", "showWPMaxRange", ((bool)checkBoxShowWPMaxRange.IsChecked).ToString());
4152
                ini.IniWriteValue("waypoints", "autoShowWPEdit", ((bool)checkBoxAutoShowWPEdit.IsChecked).ToString());
4153
                ini.IniWriteValue("waypoints", "WPMaxRangecolor", comboBoxWPMaxRangeColor.SelectedIndex.ToString());
4154
                ini.IniWriteValue("waypoints", "WPDefPrefix", _wpDefPrefix);
4155
                ini.IniWriteValue("waypoints", "WPDefAltitude", _wpDefAltitude.ToString());
4156
                ini.IniWriteValue("waypoints", "WPDefHeading", _wpDefHeading.ToString());
4157
                ini.IniWriteValue("waypoints", "WPDefCBoxHeading", _wpDefCBoxHeading.ToString());
4158
                ini.IniWriteValue("waypoints", "WPDefSpeed", _wpDefSpeed.ToString());
4159
                ini.IniWriteValue("waypoints", "WPDefCBoxSpeed", _wpDefCBoxSpeed.ToString());
4160
                ini.IniWriteValue("waypoints", "WPDefClimb", _wpDefClimb.ToString());
4161
                ini.IniWriteValue("waypoints", "WPDefCBoxClimb", _wpDefCBoxClimb.ToString());
4162
                ini.IniWriteValue("waypoints", "WPDefRadius", _wpDefRadius.ToString());
4163
                ini.IniWriteValue("waypoints", "WPDefHoldtime", _wpDefHoldtime.ToString());
4164
                ini.IniWriteValue("waypoints", "WPDefAutotrig", _wpDefAutotrig.ToString());
4165
                ini.IniWriteValue("waypoints", "WPDefCamangle", _wpDefCamangle.ToString());
4166
                ini.IniWriteValue("waypoints", "WPDefCBoxCamangle", _wpDefCBoxCamangle.ToString());
4167
                ini.IniWriteValue("waypoints", "WPDefOut1", _wpDefOut1.ToString());
4168
                ini.IniWriteValue("waypoints", "WPAddCopterHeight", _wpAddCopterHeight.ToString());
4169
                ini.IniWriteValue("waypoints", "WPAddCopterHeading", _wpAddCopterHeading.ToString());
4170
                ini.IniWriteValue("waypoints", "CopterSize", SliderCopterZoom.Value.ToString());
4171
                ini.IniWriteValue("waypoints", "WPSize", SliderWPZoom.Value.ToString());
4172
 
4173
                ini.IniWriteValue("cam", "CamImagePosLeft", _camImageMargin.Left.ToString());
4174
                ini.IniWriteValue("cam", "CamImagePosTop", _camImageMargin.Top.ToString());
4175
                ini.IniWriteValue("cam", "CamImageZoom", SliderCamZoom.Value.ToString());
4176
 
4177
                for (int i = 0; i < 12; i++)
4178
                {
4179
                    ini.IniWriteValue("serial", "ch" + i.ToString() + "Val", serChan[i].ToString());
4180
                    ini.IniWriteValue("serial", "ch" + i.ToString() + "Title", serChanTitle[i]);
4181
                    for (int y = 0; i < 4 && y < 3; y++)
4182
                    {
4183
                        ini.IniWriteValue("serial", "ch" + i.ToString() + "ValSub" + y.ToString(), serChan_sub[(i * 3) + y].ToString());
4184
                    }
4185
                }
4186
 
4187
            }
4188
            catch (Exception e)
4189
            {
4190
 
4191
                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);
4192
            }
4193
        }
4194
        #endregion ini
4195
 
4196
        #region serial channels
4197
        /// <summary>
4198
        /// Sending the serial channel values
4199
        /// </summary>
4200
        void _sendSerialData()
4201
        {
4202
            byte[] serData = new byte[12];
4203
            for (int i = 0; i < 12; i++)
4204
            {
4205
                serData[i] = unchecked((byte)(serChan[i] - 127));
4206
            }
4207
            _sendControllerMessage('y', 1, serData);
4208
        }
4209
        /// <summary>
4210
        /// init the controls for displaying
4211
        /// and setting serial control channels
4212
        /// </summary>
4213
        void _initSerialCtrl()
4214
        {
4215
            SerChan1ScaleSlider.Value = serChan[0];
4216
            textBoxSerial1.Text = serChanTitle[0];
4217
            SerChan2ScaleSlider.Value = serChan[1];
4218
            textBoxSerial2.Text = serChanTitle[1];
4219
            SerChan3ScaleSlider.Value = serChan[2];
4220
            textBoxSerial3.Text = serChanTitle[2];
4221
            //SerChan4ScaleSlider.Value = serChan[3];
4222
            //textBoxSerial4.Text = serChanTitle[3];
4223
            //trckbarSerial5.Value = serChan[4];
4224
            //textBoxSerial5.Text = serChanTitle[4];
4225
            //trckbarSerial6.Value = serChan[5];
4226
            //textBoxSerial6.Text = serChanTitle[5];
4227
            //trckbarSerial7.Value = serChan[6];
4228
            //textBoxSerial7.Text = serChanTitle[6];
4229
            //trckbarSerial8.Value = serChan[7];
4230
            //textBoxSerial8.Text = serChanTitle[7];
4231
 
4232
            textBoxSerial1_val1.Text = serChan_sub[0].ToString();
4233
            textBoxSerial1_val2.Text = serChan_sub[1].ToString();
4234
            textBoxSerial1_val3.Text = serChan_sub[2].ToString();
4235
            textBoxSerial2_val1.Text = serChan_sub[3].ToString();
4236
            textBoxSerial2_val2.Text = serChan_sub[4].ToString();
4237
            textBoxSerial2_val3.Text = serChan_sub[5].ToString();
4238
            textBoxSerial3_val1.Text = serChan_sub[6].ToString();
4239
            textBoxSerial3_val2.Text = serChan_sub[7].ToString();
4240
            textBoxSerial3_val3.Text = serChan_sub[8].ToString();
4241
            //textBoxSerial4_val1.Text = serChan_sub[9].ToString();
4242
            //textBoxSerial4_val2.Text = serChan_sub[10].ToString();
4243
            //textBoxSerial4_val3.Text = serChan_sub[11].ToString();
4244
        }
4245
        private void SerChan1ScaleSlider_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
4246
        {
4247
            if (!_init)
4248
            {
4249
                serChan[0] = (int)SerChan1ScaleSlider.Value;
4250
                _sendSerialData();
4251
            }
4252
        }
4253
        private void textBoxSerial1_TextChanged(object sender, TextChangedEventArgs e)
4254
        {
4255
            if (!_init)
4256
            {
4257
                serChanTitle[0] = textBoxSerial1.Text;
4258
            }
4259
        }
4260
        private void textBoxSerial1_val1_TextChanged(object sender, TextChangedEventArgs e)
4261
        {
4262
            if (textBoxSerial1_val1.Text.Length > 0 & !_init)
4263
            {
4264
                serChan_sub[0] = Convert.ToInt16(textBoxSerial1_val1.Text);
4265
            }
4266
        }
4267
        private void textBoxSerial1_val2_TextChanged(object sender, TextChangedEventArgs e)
4268
        {
4269
            if (textBoxSerial1_val2.Text.Length > 0 & !_init)
4270
            {
4271
                serChan_sub[1] = Convert.ToInt16(textBoxSerial1_val2.Text);
4272
            }
4273
        }
4274
        private void textBoxSerial1_val3_TextChanged(object sender, TextChangedEventArgs e)
4275
        {
4276
            if (textBoxSerial1_val3.Text.Length > 0 & !_init)
4277
            {
4278
                serChan_sub[2] = Convert.ToInt16(textBoxSerial1_val3.Text);
4279
            }
4280
        }
4281
        private void btnSer1_val1_Click(object sender, RoutedEventArgs e)
4282
        {
4283
            if (textBoxSerial1_val1.Text.Length > 0)
4284
            {
4285
                SerChan1ScaleSlider.Value = Convert.ToInt16(textBoxSerial1_val1.Text);
4286
            }
4287
        }
4288
        private void btnSer1_0_Click(object sender, RoutedEventArgs e)
4289
        {
4290
            SerChan1ScaleSlider.Value = 0;
4291
        }
4292
        private void btnSer1_127_Click(object sender, RoutedEventArgs e)
4293
        {
4294
            SerChan1ScaleSlider.Value = 127;
4295
        }
4296
        private void btnSer1_254_Click(object sender, RoutedEventArgs e)
4297
        {
4298
            SerChan1ScaleSlider.Value = 254;
4299
        }
4300
        private void btnSer1_val2_Click(object sender, RoutedEventArgs e)
4301
        {
4302
            if (textBoxSerial1_val2.Text.Length > 0)
4303
            {
4304
                SerChan1ScaleSlider.Value = Convert.ToInt16(textBoxSerial1_val2.Text);
4305
            }
4306
        }
4307
        private void btnSer1_val3_Click(object sender, RoutedEventArgs e)
4308
        {
4309
            if (textBoxSerial1_val3.Text.Length > 0)
4310
            {
4311
                SerChan1ScaleSlider.Value = Convert.ToInt16(textBoxSerial1_val3.Text);
4312
            }
4313
        }
4314
 
4315
        private void SerChan2ScaleSlider_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
4316
        {
4317
            if (!_init)
4318
            {
4319
                serChan[1] = (int)SerChan2ScaleSlider.Value;
4320
                _sendSerialData();
4321
            }
4322
        }
4323
        private void textBoxSerial2_TextChanged(object sender, TextChangedEventArgs e)
4324
        {
4325
            if (!_init)
4326
            {
4327
                serChanTitle[1] = textBoxSerial2.Text;
4328
            }
4329
        }
4330
        private void textBoxSerial2_val1_TextChanged(object sender, TextChangedEventArgs e)
4331
        {
4332
            if (textBoxSerial2_val1.Text.Length > 0 & !_init)
4333
            {
4334
                serChan_sub[3] = Convert.ToInt16(textBoxSerial2_val1.Text);
4335
            }
4336
        }
4337
        private void textBoxSerial2_val2_TextChanged(object sender, TextChangedEventArgs e)
4338
        {
4339
            if (textBoxSerial2_val2.Text.Length > 0 & !_init)
4340
            {
4341
                serChan_sub[4] = Convert.ToInt16(textBoxSerial2_val2.Text);
4342
            }
4343
        }
4344
        private void textBoxSerial2_val3_TextChanged(object sender, TextChangedEventArgs e)
4345
        {
4346
            if (textBoxSerial2_val3.Text.Length > 0 & !_init)
4347
            {
4348
                serChan_sub[5] = Convert.ToInt16(textBoxSerial2_val3.Text);
4349
            }
4350
        }
4351
        private void btnSer2_0_Click(object sender, RoutedEventArgs e)
4352
        {
4353
            SerChan2ScaleSlider.Value = 0;
4354
        }
4355
        private void btnSer2_127_Click(object sender, RoutedEventArgs e)
4356
        {
4357
            SerChan2ScaleSlider.Value = 127;
4358
        }
4359
        private void btnSer2_254_Click(object sender, RoutedEventArgs e)
4360
        {
4361
            SerChan2ScaleSlider.Value = 254;
4362
        }
4363
        private void btnSer2_val1_Click(object sender, RoutedEventArgs e)
4364
        {
4365
            if (textBoxSerial2_val1.Text.Length > 0)
4366
            {
4367
                SerChan2ScaleSlider.Value = Convert.ToInt16(textBoxSerial2_val1.Text);
4368
            }
4369
        }
4370
        private void btnSer2_val2_Click(object sender, RoutedEventArgs e)
4371
        {
4372
            if (textBoxSerial2_val2.Text.Length > 0)
4373
            {
4374
                SerChan2ScaleSlider.Value = Convert.ToInt16(textBoxSerial2_val2.Text);
4375
            }
4376
        }
4377
        private void btnSer2_val3_Click(object sender, RoutedEventArgs e)
4378
        {
4379
            if (textBoxSerial2_val3.Text.Length > 0)
4380
            {
4381
                SerChan2ScaleSlider.Value = Convert.ToInt16(textBoxSerial2_val3.Text);
4382
            }
4383
        }
4384
 
4385
        private void SerChan3ScaleSlider_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
4386
        {
4387
            if (!_init)
4388
            {
4389
                serChan[2] = (int)SerChan3ScaleSlider.Value;
4390
                _sendSerialData();
4391
            }
4392
        }
4393
        private void textBoxSerial3_TextChanged(object sender, TextChangedEventArgs e)
4394
        {
4395
            if (!_init)
4396
            {
4397
                serChanTitle[2] = textBoxSerial3.Text;
4398
            }
4399
        }
4400
        private void textBoxSerial3_val1_TextChanged(object sender, TextChangedEventArgs e)
4401
        {
4402
            if (textBoxSerial3_val1.Text.Length > 0 & !_init)
4403
            {
4404
                serChan_sub[6] = Convert.ToInt16(textBoxSerial3_val1.Text);
4405
            }
4406
        }
4407
        private void textBoxSerial3_val2_TextChanged(object sender, TextChangedEventArgs e)
4408
        {
4409
            if (textBoxSerial3_val2.Text.Length > 0 & !_init)
4410
            {
4411
                serChan_sub[7] = Convert.ToInt16(textBoxSerial3_val2.Text);
4412
            }
4413
        }
4414
        private void textBoxSerial3_val3_TextChanged(object sender, TextChangedEventArgs e)
4415
        {
4416
            if (textBoxSerial3_val3.Text.Length > 0 & !_init)
4417
            {
4418
                serChan_sub[8] = Convert.ToInt16(textBoxSerial3_val3.Text);
4419
            }
4420
        }
4421
        private void btnSer3_0_Click(object sender, RoutedEventArgs e)
4422
        {
4423
            SerChan3ScaleSlider.Value = 0;
4424
        }
4425
        private void btnSer3_127_Click(object sender, RoutedEventArgs e)
4426
        {
4427
            SerChan3ScaleSlider.Value = 127;
4428
        }
4429
        private void btnSer3_254_Click(object sender, RoutedEventArgs e)
4430
        {
4431
            SerChan3ScaleSlider.Value = 254;
4432
        }
4433
        private void btnSer3_val1_Click(object sender, RoutedEventArgs e)
4434
        {
4435
            if (textBoxSerial3_val1.Text.Length > 0)
4436
            {
4437
                SerChan3ScaleSlider.Value = Convert.ToInt16(textBoxSerial3_val1.Text);
4438
            }
4439
        }
4440
        private void btnSer3_val2_Click(object sender, RoutedEventArgs e)
4441
        {
4442
            if (textBoxSerial3_val2.Text.Length > 0)
4443
            {
4444
                SerChan3ScaleSlider.Value = Convert.ToInt16(textBoxSerial3_val2.Text);
4445
            }
4446
        }
4447
        private void btnSer3_val3_Click(object sender, RoutedEventArgs e)
4448
        {
4449
            if (textBoxSerial3_val3.Text.Length > 0)
4450
            {
4451
                SerChan3ScaleSlider.Value = Convert.ToInt16(textBoxSerial3_val3.Text);
4452
            }
4453
        }
4454
        /// <summary>
4455
        /// checks the input of a textbox
4456
        /// for valid data
4457
        /// in this case values 0-254
4458
        /// </summary>
4459
        /// <param name="sender"></param>
4460
        /// <param name="e"></param>
4461
        private void textBox_serial_KeyPress(object sender, KeyEventArgs e)
4462
        {
4463
            if ("1234567890,\b".IndexOf(e.Key.ToString()) < 0) //general check for valid chars(0-9) and backspace (\b)
4464
                e.Handled = true;
4465
            else
4466
            if ("\b".IndexOf(e.Key.ToString()) < 0)
4467
                if (Convert.ToInt16(((TextBox)sender).Text + e.Key) > 254) //if valid and not backspace, check for upper limit of the resulting number
4468
                    e.Handled = true;
4469
                else
4470
                {
4471
                    int i = -1;
4472
                    switch (((TextBox)sender).Name)
4473
                    {
4474
                        case "textBoxSerial1_val1":
4475
                            i = 0;
4476
                            break;
4477
                        case "textBoxSerial1_val2":
4478
                            i = 1;
4479
                            break;
4480
                        case "textBoxSerial1_val3":
4481
                            i = 2;
4482
                            break;
4483
                        case "textBoxSerial2_val1":
4484
                            i = 3;
4485
                            break;
4486
                        case "textBoxSerial2_val2":
4487
                            i = 4;
4488
                            break;
4489
                        case "textBoxSerial2_val3":
4490
                            i = 5;
4491
                            break;
4492
                        case "textBoxSerial3_val1":
4493
                            i = 6;
4494
                            break;
4495
                        case "textBoxSerial3_val2":
4496
                            i = 7;
4497
                            break;
4498
                        case "textBoxSerial3_val3":
4499
                            i = 8;
4500
                            break;
4501
                        case "textBoxSerial4_val1":
4502
                            i = 9;
4503
                            break;
4504
                        case "textBoxSerial4_val2":
4505
                            i = 10;
4506
                            break;
4507
                        case "textBoxSerial4_val3":
4508
                            i = 11;
4509
                            break;
4510
                    }
4511
                    if (i > -1)
4512
                        serChan_sub[i] = Convert.ToInt16(((TextBox)sender).Text + e.Key.ToString());
4513
                }
4514
        }
4515
 
4516
        #endregion serial channels
4517
        #region WP
4518
        void _readWPLFile()
4519
        {
4520
            Microsoft.Win32.OpenFileDialog fd = new Microsoft.Win32.OpenFileDialog();
4521
            fd.Filter = "Waypointlists | *.wpl";
4522
            fd.Multiselect = false;
4523
            if (fd.ShowDialog().Value)
4524
            {
4525
                string file = fd.SafeFileName;
4526
                IniFile ini = new IniFile(fd.SafeFileName);
4527
                ini.path = fd.FileName;
4528
 
4529
                try
4530
                {
4531
                    string sVal = ini.IniReadValue("General", "FileVersion");
4532
                    if (sVal == "")
4533
                        MessageBox.Show("The file has no version declared - can't go on...", "", MessageBoxButton.OK, MessageBoxImage.Information);
4534
                    else
4535
                    {
4536
                        if (Convert.ToInt16(sVal) < 3)
4537
                            MessageBox.Show("The file version is not supported - can't go on...", "", MessageBoxButton.OK, MessageBoxImage.Information);
4538
                        else
4539
                        {
4540
                            sVal = ini.IniReadValue("General", "NumberOfWaypoints");
4541
                            if (sVal == "")
4542
                                MessageBox.Show("The file has no number of waypoints declared - can't go on...", "", MessageBoxButton.OK, MessageBoxImage.Information);
4543
                            else
4544
                            {
4545
                                int wpnum = Convert.ToInt16(sVal);
4546
                                string wp;
4547
                                int i;
4548
                                NumberFormatInfo nfi = new NumberFormatInfo();
4549
                                nfi.NumberDecimalSeparator = ".";
4550
                                dtWaypoints.Rows.Clear();
4551
                                _wpEdit = -1;_wpIndex = -1;
4552
                                wpOffset.Clear();
4553
                                _clearMapMarkers(typeof(CustomMarkerWP));
4554
                                _clearMapMarkers(typeof(CustomMarkerWPActive));
4555
                                wpList.Clear();
4556
                                if (mRouteWP != null)
4557
                                    MainMap.Markers.Remove(mRouteWP);
4558
                                //if (wpActiveMarker != null)
4559
                                //    MainMap.Markers.Remove(wpActiveMarker);
4560
                                Dispatcher.Invoke(() => lblWPRouteDistance.Content = "0 m");
4561
 
4562
                                for (int k = 1; k <= wpnum; k++)
4563
                                {
4564
                                    DataRow dr = dtWaypoints.NewRow();
4565
                                    dr.ItemArray = new object[16];
4566
                                    object[] o = new object[16];
4567
                                    i = 0;
4568
                                    wp = "Point" + k.ToString();
4569
                                    o[i] = k;
4570
                                    i++;
4571
                                    sVal = ini.IniReadValue(wp, "Type");
4572
                                    if (sVal != "")
4573
                                        o[i] = Convert.ToInt16(sVal) - 1;
4574
                                    i++;
4575
                                    sVal = ini.IniReadValue(wp, "Prefix");
4576
                                    if (sVal != "")
4577
                                        o[i] = sVal + k.ToString();
4578
                                   //     o[i] = sVal == "0" ? "!" + k.ToString() : sVal + k.ToString();
4579
                                    i++;
4580
                                    sVal = ini.IniReadValue(wp, "Latitude");
4581
                                    if (sVal != "")
4582
                                        o[i] = Convert.ToDouble(sVal, nfi);
4583
                                    i++;
4584
                                    sVal = ini.IniReadValue(wp, "Longitude");
4585
                                    if (sVal != "")
4586
                                        o[i] = Convert.ToDouble(sVal, nfi);
4587
                                    i++;
4588
                                    sVal = ini.IniReadValue(wp, "Altitude");
4589
                                    if (sVal != "")
4590
                                        o[i] = Convert.ToDouble(sVal, nfi);
4591
                                    i++;
4592
                                    sVal = ini.IniReadValue(wp, "Heading");
4593
                                    if (sVal != "")
4594
                                        o[i] = Convert.ToInt16(sVal);
4595
                                    i++;
4596
                                    sVal = ini.IniReadValue(wp, "Speed");
4597
                                    if (sVal != "")
4598
                                        o[i] = Convert.ToInt16(sVal);
4599
                                    i++;
4600
                                    sVal = ini.IniReadValue(wp, "ClimbRate");
4601
                                    if (sVal != "")
4602
                                        o[i] = Convert.ToInt16(sVal);
4603
                                    i++;
4604
                                    sVal = ini.IniReadValue(wp, "Radius");
4605
                                    if (sVal != "")
4606
                                        o[i] = Convert.ToInt16(sVal);
4607
                                    i++;
4608
                                    sVal = ini.IniReadValue(wp, "DelayTime");
4609
                                    if (sVal != "")
4610
                                        o[i] = Convert.ToInt16(sVal);
4611
                                    i++;
4612
                                    sVal = ini.IniReadValue(wp, "AutoTrigger");
4613
                                    if (sVal != "")
4614
                                        o[i] = Convert.ToInt16(sVal); ;
4615
                                    i++;
4616
                                    sVal = ini.IniReadValue(wp, "CAM-Nick");
4617
                                    if (sVal != "")
4618
                                        o[i] = Convert.ToInt16(sVal);
4619
                                    i++;
4620
                                    o[i] = 0;
4621
                                    i++;
4622
                                    sVal = ini.IniReadValue(wp, "WP_Event_Channel_Value");
4623
                                    if (sVal != "")
4624
                                        o[i] = Convert.ToInt16(sVal);
4625
                                    i++;
4626
                                    o[i] = "New";
4627
 
4628
                                    dr.ItemArray = o;
4629
                                    dtWaypoints.Rows.Add(dr);
4630
                                    _createWP(new PointLatLng((double)o[3], (double)o[4]), (string)dr[2], (int)o[1], (int)o[0]-1);
4631
 
4632
                                    Dispatcher.Invoke(() => lblWPIndex.Content = k.ToString());
4633
                                    Dispatcher.Invoke(() => lblWPCount.Content = k.ToString());
4634
                                    Dispatcher.Invoke(() => dgvWP.Items.Refresh());
4635
                                    Thread.Sleep(1);
4636
                                }
4637
                                Dispatcher.Invoke(() => MainMap.Position = new PointLatLng((double)dtWaypoints.Rows[0][3], (double)dtWaypoints.Rows[0][4]));
4638
                                Dispatcher.Invoke(() => MainMap.Zoom = 19);
4639
                             //   Dispatcher.Invoke(() => MainMap.ZoomAndCenterMarkers(null));
4640
                                Dispatcher.Invoke(() => _routeUpdate());
4641
                            }
4642
                        }
4643
                    }
4644
 
4645
                }
4646
                catch (Exception e)
4647
                {
4648
 
4649
                    MessageBox.Show("Error parsing wpl-file!" + Environment.NewLine + e.Message, "Read wpl-file", MessageBoxButton.OK, MessageBoxImage.Error);
4650
                }
4651
 
4652
            }
4653
        }
4654
        void _saveWPLFile()
4655
        {
4656
            if (dtWaypoints.Rows.Count > 0)
4657
            {
4658
                Microsoft.Win32.SaveFileDialog fd = new Microsoft.Win32.SaveFileDialog();
4659
                fd.Filter = "Waypointlists | *.wpl";
4660
                fd.AddExtension = true;
4661
                if (fd.ShowDialog().Value)
4662
                {
4663
                    string file = fd.SafeFileName;
4664
                    IniFile ini = new IniFile(fd.SafeFileName);
4665
                    ini.path = fd.FileName;
4666
                    NumberFormatInfo nfi = new NumberFormatInfo();
4667
                    nfi.NumberDecimalSeparator = ".";
4668
 
4669
                    try
4670
                    {
4671
                        ini.IniWriteValue("General", "FileVersion", "3");
4672
                        ini.IniWriteValue("General", "NumberOfWaypoints", dtWaypoints.Rows.Count.ToString());
4673
                        ini.IniWriteValue("General", "Mapfile", "");
4674
                        for(int i = 1; i<=dtWaypoints.Rows.Count; i++)
4675
                        {
4676
                            ini.IniWriteValue("Point" + i.ToString(), "Latitude", ((double)(dtWaypoints.Rows[i-1][3])).ToString(nfi));
4677
                            ini.IniWriteValue("Point" + i.ToString(), "Longitude", ((double)(dtWaypoints.Rows[i - 1][4])).ToString(nfi));
4678
                            ini.IniWriteValue("Point" + i.ToString(), "Radius", dtWaypoints.Rows[i - 1][9].ToString());
4679
                            ini.IniWriteValue("Point" + i.ToString(), "Altitude", dtWaypoints.Rows[i - 1][5].ToString());
4680
                            ini.IniWriteValue("Point" + i.ToString(), "ClimbRate", dtWaypoints.Rows[i - 1][8].ToString());
4681
                            ini.IniWriteValue("Point" + i.ToString(), "DelayTime", dtWaypoints.Rows[i - 1][10].ToString());
4682
                            ini.IniWriteValue("Point" + i.ToString(), "WP_Event_Channel_Value", dtWaypoints.Rows[i - 1][14].ToString());
4683
                            ini.IniWriteValue("Point" + i.ToString(), "Heading", dtWaypoints.Rows[i - 1][6].ToString());
4684
                            ini.IniWriteValue("Point" + i.ToString(), "Speed", dtWaypoints.Rows[i - 1][7].ToString());
4685
                            ini.IniWriteValue("Point" + i.ToString(), "CAM-Nick", dtWaypoints.Rows[i - 1][12].ToString());
4686
                            ini.IniWriteValue("Point" + i.ToString(), "Type", ((int)dtWaypoints.Rows[i - 1][1]+1).ToString());
4687
                            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));
4688
                            ini.IniWriteValue("Point" + i.ToString(), "AutoTrigger", dtWaypoints.Rows[i - 1][11].ToString());
4689
                        }
4690
                        MessageBox.Show(dtWaypoints.Rows.Count.ToString() + " points saved to " + file, "Waypointlist saved", MessageBoxButton.OK, MessageBoxImage.Information);
4691
                    }
4692
                    catch { }
4693
                }
4694
            }
4695
            else
4696
                MessageBox.Show("Nothing to save...");
4697
        }
4698
        private void btnSaveWPLFile_Click(object sender, RoutedEventArgs e)
4699
        {
4700
            _saveWPLFile();
4701
        }
4702
        /// <summary>
4703
        /// set the selected color for the route
4704
        /// </summary>
4705
        /// <param name="color"></param>
4706
        /// <returns></returns>
4707
        Brush _getBrush(string color)
4708
        {
4709
            switch (color)
4710
            {
4711
                case "red":
4712
                    return Brushes.Red;
4713
                case "green":
4714
                    return Brushes.Lime;
4715
                case "blue":
4716
                    return Brushes.Aqua;
4717
                case "pink":
4718
                    return Brushes.Magenta;
4719
                case "yellow":
4720
                    return Brushes.Yellow;
4721
                default:
4722
                    return Brushes.Magenta;
4723
            }
4724
        }
4725
        void _routeUpdate()
4726
        {
4727
            Dispatcher.Invoke(() =>
4728
            {
4729
                if (comboBoxRouteColor.SelectionBoxItem != null)
4730
                {
4731
                    string s = _colors[comboBoxRouteColor.SelectedIndex];
4732
                    mRouteWP = new GMapRoute(wpList, _getBrush(s));
4733
                }
4734
                else
4735
                    mRouteWP = new GMapRoute(wpList, null);
4736
 
4737
                if (_bShowWPRoute)
4738
                    MainMap.Markers.Add(mRouteWP);
4739
            });
4740
 
4741
            MapRoute mr = new MapRoute(wpList, "WPList");
4742
            Dispatcher.Invoke(() => lblWPRouteDistance.Content = (mr.Distance * 1000).ToString("0 m"));
4743
        }
4744
        GMapMarker _createWP(PointLatLng p, string name, int type, int index)
4745
        {
4746
            GMapMarker wpMarker = new GMapMarker(p);
4747
            Dispatcher.Invoke(()=>
4748
            {
4749
                wpMarker.Shape = new CustomMarkerWP(this, wpMarker, name, type);
4750
                wpMarker.Tag = name;
4751
                wpMarker.Offset = new System.Windows.Point(-11.5, -11.5);
4752
                wpMarker.ZIndex = 100;
4753
                _setMarkerColor(wpMarker, type);
4754
                MainMap.Markers.Add(wpMarker);
4755
                if (type == 0 || type == 3)
4756
                {
4757
                    wpList.Add(p);
4758
                    wpOffset.Add(index);
4759
                }
4760
                ((CustomMarkerWP)wpMarker.Shape).positionChanged += _updateDTWPPos;
4761
                ((CustomMarkerWP)wpMarker.Shape).newPosition += _updateDTWPPosFin;
4762
                ((CustomMarkerWP)wpMarker.Shape).mouseCaptured += _WPMouseCaptured;
4763
                _setMapItemsSize("WP", SliderWPZoom.Value);
4764
            });
4765
            return wpMarker;
4766
        }
4767
        bool _WPisMouseCaptured = false;
4768
        void _WPMouseCaptured(bool isCaptured)
4769
        {
4770
            _WPisMouseCaptured = isCaptured;
4771
            MainMap.CanDragMap = !isCaptured;
4772
        }
4773
        void _updateDTWPPos(CustomMarkerWP wp)
4774
        {
4775
            string sIndex = wp.WPText.Substring(1, wp.WPText.Length - 1);
4776
            int index = Convert.ToInt16(sIndex) -1;
4777
            GMapMarker p = ((GMapMarker)wp.DataContext);
4778
            if (p != null && index < dtWaypoints.Rows.Count)
4779
            {
4780
                //Dispatcher.Invoke(() => dgvWP.Items.Refresh());
4781
                if(wp.WPType == 0 | wp.WPType == 3)
4782
                {
4783
                    PointLatLng x = new PointLatLng((double)dtWaypoints.Rows[index][3], (double)dtWaypoints.Rows[index][4]);
4784
                    int wpListIndex = wpList.IndexOf(x);
4785
                    if (wpListIndex > -1)
4786
                    {
4787
                        wpList[wpListIndex] = p.Position;
4788
                        MainMap.Markers.Remove(mRouteWP);
4789
                        _routeUpdate();
4790
                    }
4791
                }
4792
                dtWaypoints.Rows[index][3] = p.Position.Lat;
4793
                dtWaypoints.Rows[index][4] = p.Position.Lng;
4794
            }
4795
        }
4796
        void _updateDTWPPosFin(CustomMarkerWP wp)
4797
        {
4798
            string sIndex = wp.WPText.Substring(1, wp.WPText.Length - 1);
4799
            int index = Convert.ToInt16(sIndex) -1;
4800
            GMapMarker p = ((GMapMarker)wp.DataContext);
4801
            if (p != null && index < dtWaypoints.Rows.Count)
4802
            {
4803
                dtWaypoints.Rows[index][3] = p.Position.Lat;
4804
                dtWaypoints.Rows[index][4] = p.Position.Lng;
4805
                Dispatcher.Invoke(() =>
4806
                {
4807
                    dgvWP.Items.Refresh();
4808
                    dgvWP.SelectedIndex = index;
4809
                    _dgvWPselectEditRow();
4810
                });
4811
 
4812
            }
4813
 
4814
        }
4815
        void _addWP(PointLatLng p,int type)
4816
        {
4817
            object[] o = new object[16];
4818
 
4819
            o[0] = dgvWP.ItemContainerGenerator.Items.Count + 1;
4820
            o[1] = type;
4821
            //     cbWPEditType.SelectedIndex = 0;
4822
            //  tbWPEditPrefix.Text = "P";
4823
            o[2] = _wpDefPrefix + o[0].ToString();
4824
            //   tbWPEditLat.Text = copter.Position.Lat.ToString();
4825
            o[3] = p.Lat;
4826
            //  tbWPEditLon.Text = copter.Position.Lng.ToString();
4827
            o[4] = p.Lng;
4828
            //   lblWPEditAlt.Content = ((double)iAnalogData[4] / (double)10).ToString();
4829
            o[5] = _wpAddCopterHeight ? iAnalogData[4].ToString(): _wpDefAltitude.ToString();
4830
 
4831
            cbWPEditHeading.SelectedIndex = _wpDefCBoxHeading;
4832
            o[6] = _wpAddCopterHeading ? iAnalogData[10].ToString(): _wpDefHeading.ToString();
4833
            //lblWPEditHeading.Content = iAnalogData[10].ToString();
4834
            //    tbWPEditHeading.IsReadOnly = false;
4835
 
4836
            cbWPEditSpeed.SelectedIndex = _wpDefCBoxSpeed;
4837
            //     tbWPEditSpeed.Text = "5.0";
4838
            //     tbWPEditSpeed.IsReadOnly = false;
4839
            o[7] = _wpDefSpeed.ToString();
4840
 
4841
            cbWPEditClimbrate.SelectedIndex = _wpDefCBoxClimb;
4842
            //       lblWPEditClimbrate.Content = "5.0";
4843
            //       tbWPEditClimbrate.IsReadOnly = false;
4844
            o[8] = _wpDefClimb.ToString();
4845
 
4846
            //       lblWPEditRadius.Content = "10";
4847
            o[9] = _wpDefRadius.ToString();
4848
            //       lblWPEditHoldtime.Content = "5";
4849
            o[10] = _wpDefHoldtime.ToString();
4850
            //      lblWPEditAutoTrigger.Content = "0";
4851
            o[11] = _wpDefAutotrig.ToString();
4852
            cbWPEditCamAngle.SelectedIndex = _wpDefCBoxCamangle;
4853
            //       lblWPEditCamAngle.Content = "AUTO";
4854
            //       tbWPEditCamAngle.IsReadOnly = true;
4855
            o[12] = _wpDefCamangle.ToString();
4856
 
4857
            o[13] = "0";
4858
            //     lblWPEditOut1.Content = "0";
4859
            o[14] = _wpDefOut1.ToString();
4860
            o[15] = "0";
4861
 
4862
            dtWaypoints.Rows.Add(o);
4863
            _createWP(new PointLatLng((double)o[3], (double)o[4]), (string)o[2], (int)o[1], (int)o[0] - 1);
4864
            // Dispatcher.Invoke(() => lblWPCount.Content = o[0].ToString());
4865
            if (mRouteWP != null)
4866
                MainMap.Markers.Remove(mRouteWP);
4867
            _routeUpdate();
4868
            Dispatcher.Invoke(() =>
4869
            {
4870
                dgvWP.Items.Refresh();
4871
                dgvWP.UpdateLayout();
4872
                dgvWP.SelectedIndex = (int)o[0] - 1;
4873
                _dgvWPselectEditRow();
4874
            });
4875
        }
4876
        /// <summary>
4877
        /// find the index of of a wp from datatable in the waypointlist wpList
4878
        /// </summary>
4879
        /// <param name="dtIndex">the index of wp in datatable (0-based)</param>
4880
        /// <returns></returns>
4881
        int _getWPIndexfromList(int dtIndex)
4882
        {
4883
            if ((int)dtWaypoints.Rows[dtIndex][1] == 0 || (int)dtWaypoints.Rows[dtIndex][1] == 3)
4884
            {
4885
                GMapMarker wp = _findWPMarker((string)dtWaypoints.Rows[dtIndex][2]);
4886
                if (wp != null)
4887
                    return wpList.IndexOf(wp.Position);
4888
            }
4889
            return -1;
4890
        }
4891
        /// <summary>
4892
        /// find the index of of a wp from datatable in the waypointlist wpList
4893
        /// </summary>
4894
        /// <param name="name">the name of the wp</param>
4895
        /// <returns></returns>
4896
        int _getWPIndexfromList(string name)
4897
        {
4898
            GMapMarker wp = _findWPMarker(name);
4899
            if ((wp != null && wp.Shape != null) && ((CustomMarkerWP)wp.Shape).WPType == 0 | ((CustomMarkerWP)wp.Shape).WPType == 3)
4900
                return wpList.IndexOf(wp.Position);
4901
            else
4902
                return -1;
4903
        }
4904
        int _getWPListOffset(int index)
4905
        {
4906
            int k = 0;
4907
            for(int i = 0; i < wpOffset.Count;i++)
4908
            {
4909
                if (wpOffset[i] <= index)
4910
                    k++;
4911
            }
4912
 
4913
            return k;
4914
        }
4915
        void _setMarkerColor(GMapMarker wpMarker,int iType)
4916
        {
4917
            if(wpMarker != null)
4918
            Dispatcher.Invoke(() =>
4919
            {
4920
                switch (iType)
4921
                {
4922
                    case 0:
4923
                        if (comboBoxWPColor.SelectionBoxItem != null)
4924
                        {
4925
                            string s = _colors[comboBoxWPColor.SelectedIndex];
4926
                            ((CustomMarkerWP)(wpMarker.Shape)).setColor(s);
4927
                        }
4928
                        else
4929
                            ((CustomMarkerWP)(wpMarker.Shape)).setColor("green");
4930
                        break;
4931
                    case 1:
4932
                        if (comboBoxPOIColor.SelectionBoxItem != null)
4933
                        {
4934
                            string s = _colors[comboBoxPOIColor.SelectedIndex];
4935
                            ((CustomMarkerWP)(wpMarker.Shape)).setColor(s);
4936
                        }
4937
                        else
4938
                            ((CustomMarkerWP)(wpMarker.Shape)).setColor("pink");
4939
                        break;
4940
                    case 2:
4941
                        if (comboBoxFSColor.SelectionBoxItem != null)
4942
                        {
4943
                            string s = _colors[comboBoxFSColor.SelectedIndex];
4944
                            ((CustomMarkerWP)(wpMarker.Shape)).setColor(s);
4945
                        }
4946
                        else
4947
                            ((CustomMarkerWP)(wpMarker.Shape)).setColor("red");
4948
                        break;
4949
                    case 3:
4950
                        if (comboBoxLandingColor.SelectionBoxItem != null)
4951
                        {
4952
                            string s = _colors[comboBoxLandingColor.SelectedIndex];
4953
                            ((CustomMarkerWP)(wpMarker.Shape)).setColor(s);
4954
                        }
4955
                        else
4956
                            ((CustomMarkerWP)(wpMarker.Shape)).setColor("blue");
4957
                        break;
4958
                    default:
4959
                        ((CustomMarkerWP)(wpMarker.Shape)).setColor("red");
4960
                        break;
4961
                }
4962
            });
4963
 
4964
        }
4965
        void _MarkerColorSelection(object sender,int type)
4966
        {
4967
            Dispatcher.Invoke(() =>
4968
            {
4969
                if (((ComboBox)sender).SelectionBoxItem != null)
4970
                {
4971
                    for (int k = 0; k < MainMap.Markers.Count; k++)
4972
                    {
4973
                        GMapMarker p = MainMap.Markers[k];
4974
                        if (p.Shape != null && p.Shape.GetType() == typeof(CustomMarkerWP))
4975
                        {
4976
                            if (((CustomMarkerWP)p.Shape).WPType == type)
4977
                            {
4978
                                string s = _colors[((ComboBox)sender).SelectedIndex];
4979
                                ((CustomMarkerWP)(p.Shape)).setColor(s);
4980
                            }
4981
                        }
4982
                    }
4983
                }
4984
            });
4985
        }
4986
        private void comboBoxWPColor_DropDownClosed(object sender, EventArgs e)
4987
        {
4988
            _MarkerColorSelection(sender, 0);
4989
        }
4990
        private void comboBoxPOIColor_DropDownClosed(object sender, EventArgs e)
4991
        {
4992
            _MarkerColorSelection(sender, 1);
4993
        }
4994
        private void comboBoxFSColor_DropDownClosed(object sender, EventArgs e)
4995
        {
4996
            _MarkerColorSelection(sender, 2);
4997
        }
4998
        private void comboBoxLandingColor_DropDownClosed(object sender, EventArgs e)
4999
        {
5000
            _MarkerColorSelection(sender,3);
5001
        }
5002
        private void comboBoxCopterColor_DropDownClosed(object sender, EventArgs e)
5003
        {
5004
            Dispatcher.Invoke(() => {
5005
                if (comboBoxCopterColor.SelectionBoxItem != null)
5006
                {
5007
                    string s = _colors[comboBoxCopterColor.SelectedIndex];
5008
                    ((CustomMarkerCopter)(copter.Shape)).setCopterColor(s);
5009
                }
5010
                else
5011
                    ((CustomMarkerCopter)(copter.Shape)).setCopterColor("red");
5012
            });
5013
        }
5014
        private void comboBoxCopterHeadingColor_DropDownClosed(object sender, EventArgs e)
5015
        {
5016
            Dispatcher.Invoke(() => {
5017
                if (comboBoxCopterHeadingColor.SelectionBoxItem != null)
5018
                {
5019
                    string s = _colors[comboBoxCopterHeadingColor.SelectedIndex];
5020
                    ((CustomMarkerCopter)(copter.Shape)).setHeadingColor(s);
5021
                }
5022
                else
5023
                    ((CustomMarkerCopter)(copter.Shape)).setHeadingColor("red");
5024
            });
5025
        }
5026
        private void comboBoxRouteColor_DropDownClosed(object sender, EventArgs e)
5027
        {
5028
            Dispatcher.Invoke(() =>
5029
            {
5030
                if (comboBoxRouteColor.SelectionBoxItem != null)
5031
                {
5032
                    string s = _colors[comboBoxRouteColor.SelectedIndex];
5033
                    MainMap.Markers.Remove(mRouteWP);
5034
                    mRouteWP = new GMapRoute(wpList, _getBrush(s));
5035
                    if (_bShowWPRoute)
5036
                        MainMap.Markers.Add(mRouteWP);
5037
                }
5038
            });
5039
        }
5040
        private void comboBoxWPMaxRangeColor_DropDownClosed(object sender, EventArgs e)
5041
        {
5042
            Dispatcher.Invoke(() =>
5043
            {
5044
                if (comboBoxWPMaxRangeColor.SelectionBoxItem != null)
5045
                {
5046
                    if (home != null && checkBoxShowWPMaxRange.IsChecked == true && dWPMaxRange > 0)
5047
                    {
5048
                        if (cWPBound != null && cWPBound.Tag != null)
5049
                            MainMap.Markers.Remove(cWPBound.Tag as GMapMarker);
5050
 
5051
                       createCircle(home.Position, dWPMaxRange);
5052
                       string s = _colors[comboBoxWPMaxRangeColor.SelectedIndex];
5053
                       cWPBound.setColor(s);
5054
 
5055
                    }
5056
                }
5057
            });
5058
 
5059
        }
5060
        private void checkBoxShowWPRoute_Click(object sender, RoutedEventArgs e)
5061
        {
5062
            _bShowWPRoute = (bool)checkBoxShowWPRoute.IsChecked;
5063
            if (_bShowWPRoute)
5064
            {
5065
                if (mRouteWP != null)
5066
                    MainMap.Markers.Add(mRouteWP);
5067
            }
5068
            else
5069
            {
5070
                if (mRouteWP != null)
5071
                    MainMap.Markers.Remove(mRouteWP);
5072
            }
5073
        }
5074
 
5075
        private void btnLoadWPLFile_Click(object sender, RoutedEventArgs e)
5076
        {
5077
            _readWPLFile();
5078
        }
5079
        private void btnClearWPList_Click(object sender, RoutedEventArgs e)
5080
        {
5081
            _clearMapMarkers(typeof(CustomMarkerWP));
5082
            _clearMapMarkers(typeof(CustomMarkerWPActive));
5083
            wpList.Clear();
5084
            if (mRouteWP != null)
5085
                MainMap.Markers.Remove(mRouteWP);
5086
            //if (wpActiveMarker != null)
5087
            //    MainMap.Markers.Remove(wpActiveMarker);
5088
            dtWaypoints.Rows.Clear();
5089
            _wpEdit = -1;
5090
            _wpIndex = -1;
5091
            wpOffset.Clear();
5092
            Dispatcher.Invoke(() => dgvWP.Items.Refresh());
5093
            Dispatcher.Invoke(() => lblWPIndex.Content = 0);
5094
            Dispatcher.Invoke(() => lblWPCount.Content = 0);
5095
            Dispatcher.Invoke(() => lblWPRouteDistance.Content = "0 m");
5096
        }
5097
        private void btnClearCopterList_Click(object sender, RoutedEventArgs e)
5098
        {
5099
            Thread t = new Thread(new ThreadStart(clearCopterWPList));
5100
            t.Start();
5101
        }
5102
        private void btnSendActiveWP_Click(object sender, RoutedEventArgs e)
5103
        {
5104
            if (dgvWP.SelectedIndex > -1 && dgvWP.SelectedIndex < dtWaypoints.Rows.Count)
5105
            {
5106
                if (_wpCount > 0)
5107
                    _sendWayPoint(dtWaypoints.Rows[dgvWP.SelectedIndex], -1, 's',false);
5108
                else
5109
                    _sendWayPoint(dtWaypoints.Rows[dgvWP.SelectedIndex], 1, 's',false);
5110
 
5111
                //int index = dgvWP.SelectedIndex;
5112
                //Thread t = new Thread(() => _sendWPList(index));
5113
                //t.Start();
5114
 
5115
                Dispatcher.Invoke(() => {
5116
                    DataGridRow row;
5117
                    if (_wpEdit > -1 && _wpEdit < dgvWP.ItemContainerGenerator.Items.Count)
5118
                    {
5119
                        row = (DataGridRow)dgvWP.ItemContainerGenerator.ContainerFromIndex(_wpEdit);
5120
                        row.Background = new SolidColorBrush(Colors.Transparent);
5121
                        row.BorderBrush = new SolidColorBrush(Colors.Transparent);
5122
                        row.BorderThickness = new Thickness(0);
5123
                        dgvWP.UpdateLayout();
5124
                    }
5125
                    //_wpEdit = dgvWP.SelectedIndex;
5126
                    //row = (DataGridRow)dgvWP.ItemContainerGenerator.ContainerFromIndex(_wpEdit);
5127
                    //row.Background = new SolidColorBrush(Color.FromArgb(80, 0, 255, 100));
5128
                    //row.BorderBrush = new SolidColorBrush(Colors.SpringGreen);
5129
                    //row.BorderThickness = new Thickness(2);
5130
                });
5131
            }
5132
        }
5133
        private void btnEditWPSendToCopter_Click(object sender, RoutedEventArgs e)
5134
        {
5135
            if (dgvWP.SelectedIndex > -1 && dgvWP.SelectedIndex < dtWaypoints.Rows.Count)
5136
            {
5137
 
5138
                object[] o = new object[16];
5139
                o[0] = dgvWP.SelectedIndex + 1;
5140
                o[1] = cbWPEditType.SelectedIndex;
5141
                o[2] = tbWPEditPrefix.Text + (dgvWP.SelectedIndex + 1).ToString();
5142
                o[3] = Convert.ToDouble(tbWPEditLat.Text.Replace('.', ','));
5143
                o[4] = Convert.ToDouble(tbWPEditLon.Text.Replace('.', ','));
5144
                o[5] = lblWPEditAlt.Content;
5145
                switch (cbWPEditHeading.SelectedIndex)
5146
                {
5147
                    case 0:
5148
                        o[6] = "0";
5149
                        break;
5150
                    case 1:
5151
                        o[6] = "-" + lblWPEditHeading.Content;
5152
                        break;
5153
                    case 2:
5154
                        o[6] = lblWPEditHeading.Content;
5155
                        break;
5156
                }
5157
                switch (cbWPEditSpeed.SelectedIndex)
5158
                {
5159
                    case 0:
5160
                        o[7] = "0";
5161
                        break;
5162
                    case 1:
5163
                        o[7] = (System.Convert.ToDouble(lblWPEditSpeed.Content.ToString().Replace('.', ',')) * 10).ToString("0");
5164
                        break;
5165
                    case 2:
5166
                        o[7] = (256 - Convert.ToInt16(lblWPEditSpeed.Content)).ToString();
5167
                        break;
5168
                }
5169
                switch (cbWPEditClimbrate.SelectedIndex)
5170
                {
5171
                    case 0:
5172
                        o[8] = "255";
5173
                        break;
5174
                    case 1:
5175
                        o[8] = (System.Convert.ToDouble(lblWPEditClimbrate.Content.ToString().Replace('.', ',')) * 10).ToString("0");
5176
                        break;
5177
                }
5178
                o[9] = lblWPEditRadius.Content;
5179
                o[10] = lblWPEditHoldtime.Content;
5180
                o[11] = lblWPEditAutoTrigger.Content;
5181
                switch (cbWPEditCamAngle.SelectedIndex)
5182
                {
5183
                    case 0:
5184
                        o[12] = "0";
5185
                        break;
5186
                    case 1:
5187
                        o[12] = "255";
5188
                        break;
5189
                    case 2:
5190
                        o[12] = lblWPEditCamAngle.Content;
5191
                        break;
5192
                }
5193
                o[13] = 0;
5194
                o[14] = lblWPEditOut1.Content;
5195
                DataRow dr = dtWaypoints.NewRow();
5196
                dr.ItemArray = o;
5197
 
5198
                if (_wpCount > 0)
5199
                    _sendWayPoint(dr, -1, 'w', false);
5200
                else
5201
                    _sendWayPoint(dr, 1, 'w', false);
5202
 
5203
                if (_wpIndex > -1 && _wpIndex < dtWaypoints.Rows.Count)
5204
                    _sendWayPoint(dtWaypoints.Rows[wpOffset[_wpIndex]], _wpIndex+1, 's', false);
5205
            }
5206
        }
5207
        private void btnWPSimulateStart_Click(object sender, RoutedEventArgs e)
5208
        {
5209
            _Simulate = !_Simulate;
5210
            if (dtWaypoints.Rows.Count > 0)
5211
            {
5212
                DataRow dr = dtWaypoints.Rows[0];
5213
                dr[13] = _Simulate ? 3 : 0;
5214
                _sendWayPoint(dr, 0, 's', true);
5215
                rectSimulate.Visibility = lblSimu.Visibility = _Simulate ? Visibility.Visible : Visibility.Hidden;
5216
            }
5217
        }
5218
 
5219
        private void dgvWP_MouseUp(object sender, MouseButtonEventArgs e)
5220
        {
5221
            _dgvWPselectEditRow();
5222
        }
5223
        private void dgvWP_MouseDoubleClick(object sender, MouseButtonEventArgs e)
5224
        {
5225
        }
5226
        void _dgvWPselectEditRow()
5227
        {
5228
            if (dgvWP.SelectedIndex > -1 && dgvWP.SelectedIndex < dtWaypoints.Rows.Count)
5229
            {
5230
               Dispatcher.Invoke(() => {
5231
                    DataGridRow row;
5232
                    dgvWP.Items.Refresh();
5233
                    dgvWP.UpdateLayout();
5234
                    if (_wpEdit > -1 && _wpEdit < dgvWP.ItemContainerGenerator.Items.Count)
5235
                    {
5236
                        row = (DataGridRow)dgvWP.ItemContainerGenerator.ContainerFromIndex(_wpEdit);
5237
                       if (row != null)
5238
                       {
5239
                           row.Background = new SolidColorBrush(Colors.Transparent);
5240
                           row.BorderBrush = new SolidColorBrush(Colors.Transparent);
5241
                           row.BorderThickness = new Thickness(0);
5242
                       }
5243
                    }
5244
                    _wpEdit = dgvWP.SelectedIndex;
5245
                    row = (DataGridRow)dgvWP.ItemContainerGenerator.ContainerFromIndex(_wpEdit);
5246
                   if (row != null)
5247
                   {
5248
                       row.Background = new SolidColorBrush(Color.FromArgb(80, 0, 100, 255));
5249
                       row.BorderBrush = new SolidColorBrush(Colors.Aqua);
5250
                       row.BorderThickness = new Thickness(2);
5251
                       dgvWP.UpdateLayout();
5252
                   }
5253
                    if (GridWPEdit.Visibility == Visibility.Collapsed && _bAutoWPEdit)
5254
                        GridWPEdit.Visibility = Visibility.Visible;
5255
 
5256
                    _setWPEditFields(_wpEdit);
5257
                });
5258
            }
5259
        }
5260
        void _setWPEditFields(int index)
5261
        {
5262
            if (GridWPEdit.Visibility == Visibility.Collapsed && _bAutoWPEdit)
5263
                GridWPEdit.Visibility = Visibility.Visible;
5264
 
5265
            int iVal;
5266
            lblWPEditIndex.Content = dtWaypoints.Rows[index][0].ToString();
5267
            cbWPEditType.SelectedIndex = (int)dtWaypoints.Rows[index][1];
5268
            tbWPEditPrefix.Text = dtWaypoints.Rows[index][2].ToString().Substring(0,1);
5269
            tbWPEditLat.Text = dtWaypoints.Rows[index][3].ToString();
5270
            tbWPEditLon.Text = dtWaypoints.Rows[index][4].ToString();
5271
 
5272
            SliderAlt.Value = Convert.ToInt16(dtWaypoints.Rows[index][5]);
5273
 
5274
            iVal = Convert.ToInt16(dtWaypoints.Rows[index][6]);
5275
            SliderHeading.Value = Math.Abs(iVal);
5276
            if (iVal == 0)
5277
            {
5278
                cbWPEditHeading.SelectedIndex = 0;
5279
              //  lblWPEditHeading.Content = " - - -";
5280
            }
5281
            if (iVal > 0 && iVal < 360)
5282
            {
5283
                cbWPEditHeading.SelectedIndex = 2;
5284
              //  lblWPEditHeading.Content = iVal.ToString();
5285
            }
5286
            if (iVal < 0)
5287
            {
5288
                cbWPEditHeading.SelectedIndex = 1;
5289
             //   lblWPEditHeading.Content = (Math.Abs(iVal).ToString());
5290
            }
5291
            iVal = Convert.ToInt16(dtWaypoints.Rows[index][7]);
5292
            SliderSpeed.Value = (double)iVal * 0.1;                                                  //------------!!!!!!!!
5293
            if (iVal == 0)
5294
            {
5295
                cbWPEditSpeed.SelectedIndex = 0;
5296
              //  lblWPEditSpeed.Content = "MAX";
5297
            }
5298
            if (iVal > 0 && iVal < 248)
5299
            {
5300
                cbWPEditSpeed.SelectedIndex = 1;
5301
              //  lblWPEditSpeed.Content = ((double)iVal * 0.1).ToString();
5302
            }
5303
            if (iVal > 247)
5304
            {
5305
                cbWPEditSpeed.SelectedIndex = 256 - iVal + 1;
5306
              //  lblWPEditSpeed.Content = "";
5307
            }
5308
            iVal = Convert.ToInt16(dtWaypoints.Rows[index][8]);
5309
            SliderClimbrate.Value = (System.Convert.ToDouble(iVal) / 10);                              //------------!!!!!!!!
5310
            if (iVal == 255)
5311
            {
5312
                cbWPEditClimbrate.SelectedIndex = 0;
5313
             //   lblWPEditClimbrate.Content = "AUTO";
5314
            }
5315
            else
5316
            {
5317
                cbWPEditClimbrate.SelectedIndex = 1;
5318
               // lblWPEditClimbrate.Content = (System.Convert.ToDouble(iVal) / 10).ToString("0.0");
5319
            }
5320
            iVal = Convert.ToInt16(dtWaypoints.Rows[index][9]);
5321
            SliderRadius.Value = iVal;
5322
            iVal = Convert.ToInt16(dtWaypoints.Rows[index][10]);
5323
            SliderHoldTime.Value = iVal;
5324
            iVal = Convert.ToInt16(dtWaypoints.Rows[index][11]);
5325
            SliderAutoTrigger.Value = iVal;
5326
            iVal = Convert.ToInt16(dtWaypoints.Rows[index][12]);
5327
            SliderCamAngle.Value = iVal;
5328
            if (iVal == 0)
5329
            {
5330
                cbWPEditCamAngle.SelectedIndex = 0;
5331
              //  lblWPEditCamAngle.Content = " - - - ";
5332
            }
5333
            if (iVal < 0 | iVal == 255)
5334
            {
5335
                cbWPEditCamAngle.SelectedIndex = 1;
5336
              //  lblWPEditCamAngle.Content = "AUTO";
5337
            }
5338
            if (iVal > 0 & iVal < 255)
5339
            {
5340
                cbWPEditCamAngle.SelectedIndex = 2;
5341
             //   lblWPEditCamAngle.Content = iVal.ToString();
5342
            }
5343
            iVal = Convert.ToInt16(dtWaypoints.Rows[index][14]);
5344
            SliderOut1.Value = iVal;
5345
        }
5346
        private void btnEditWPSave_Click(object sender, RoutedEventArgs e)
5347
        {
5348
            if(dgvWP.SelectedIndex > -1 && dgvWP.SelectedIndex < dtWaypoints.Rows.Count)
5349
            {
5350
                string oldName = (string)dtWaypoints.Rows[dgvWP.SelectedIndex][2];
5351
                int oldType = (int)dtWaypoints.Rows[dgvWP.SelectedIndex][1];
5352
                PointLatLng pOld = new PointLatLng((double)dtWaypoints.Rows[dgvWP.SelectedIndex][3], (double)dtWaypoints.Rows[dgvWP.SelectedIndex][4]);
5353
                int i = wpList.IndexOf(pOld);
5354
                dtWaypoints.Rows[dgvWP.SelectedIndex][1] = cbWPEditType.SelectedIndex;
5355
                dtWaypoints.Rows[dgvWP.SelectedIndex][2] = tbWPEditPrefix.Text + (dgvWP.SelectedIndex + 1).ToString();
5356
                dtWaypoints.Rows[dgvWP.SelectedIndex][3] = Convert.ToDouble(tbWPEditLat.Text.Replace('.', ','));
5357
                dtWaypoints.Rows[dgvWP.SelectedIndex][4] = Convert.ToDouble(tbWPEditLon.Text.Replace('.', ','));
5358
                if (i > -1)
5359
                {
5360
                    if ((int)dtWaypoints.Rows[dgvWP.SelectedIndex][1] == 0 || (int)dtWaypoints.Rows[dgvWP.SelectedIndex][1] == 3)
5361
                        wpList[i] = (new PointLatLng((double)dtWaypoints.Rows[dgvWP.SelectedIndex][3], (double)dtWaypoints.Rows[dgvWP.SelectedIndex][4]));
5362
                    else
5363
                    {
5364
                        wpList.Remove(pOld);
5365
                        wpOffset.Remove(wpOffset[i]);
5366
                    }
5367
                }
5368
                else
5369
                {
5370
                    if ((int)dtWaypoints.Rows[dgvWP.SelectedIndex][1] == 0 || (int)dtWaypoints.Rows[dgvWP.SelectedIndex][1] == 3)
5371
                    {
5372
                        int found = 0;
5373
                        for (int k = 0; k < dgvWP.SelectedIndex; k++)
5374
                        {
5375
                            if ((int)dtWaypoints.Rows[k][1] == 0 || (int)dtWaypoints.Rows[k][1] == 3)
5376
                            {
5377
                                found++;
5378
                            }
5379
                        }
5380
                        wpList.Insert(found, new PointLatLng((double)dtWaypoints.Rows[dgvWP.SelectedIndex][3], (double)dtWaypoints.Rows[dgvWP.SelectedIndex][4]));
5381
                        wpOffset.Insert(found, dgvWP.SelectedIndex);
5382
                    }
5383
                }
5384
                dtWaypoints.Rows[dgvWP.SelectedIndex][5] = lblWPEditAlt.Content;
5385
                switch (cbWPEditHeading.SelectedIndex)
5386
                {
5387
                    case 0:
5388
                        dtWaypoints.Rows[dgvWP.SelectedIndex][6] = "0";
5389
                        break;
5390
                    case 1:
5391
                        dtWaypoints.Rows[dgvWP.SelectedIndex][6] = "-" + lblWPEditHeading.Content;
5392
                        break;
5393
                    case 2:
5394
                        dtWaypoints.Rows[dgvWP.SelectedIndex][6] = lblWPEditHeading.Content;
5395
                        break;
5396
                }
5397
                switch (cbWPEditSpeed.SelectedIndex)
5398
                {
5399
                    case 0:
5400
                        dtWaypoints.Rows[dgvWP.SelectedIndex][7] = "0";
5401
                        break;
5402
                    case 1:
5403
                        dtWaypoints.Rows[dgvWP.SelectedIndex][7] = (System.Convert.ToDouble(lblWPEditSpeed.Content.ToString().Replace('.', ',')) * 10).ToString("0");
5404
                        break;
5405
                    case 2:
5406
                        dtWaypoints.Rows[dgvWP.SelectedIndex][7] = (256 - Convert.ToInt16(lblWPEditSpeed.Content)).ToString();
5407
                        break;
5408
                }
5409
                switch (cbWPEditClimbrate.SelectedIndex)
5410
                {
5411
                    case 0:
5412
                        dtWaypoints.Rows[dgvWP.SelectedIndex][8] = "255";
5413
                        break;
5414
                    case 1:
5415
                        dtWaypoints.Rows[dgvWP.SelectedIndex][8] = (System.Convert.ToDouble(lblWPEditClimbrate.Content.ToString().Replace('.',',')) * 10).ToString("0");
5416
                        break;
5417
                }
5418
                dtWaypoints.Rows[dgvWP.SelectedIndex][9] = lblWPEditRadius.Content;
5419
                dtWaypoints.Rows[dgvWP.SelectedIndex][10] = lblWPEditHoldtime.Content;
5420
                dtWaypoints.Rows[dgvWP.SelectedIndex][11] = lblWPEditAutoTrigger.Content;
5421
                switch (cbWPEditCamAngle.SelectedIndex)
5422
                {
5423
                    case 0:
5424
                        dtWaypoints.Rows[dgvWP.SelectedIndex][12] = "0";
5425
                        break;
5426
                    case 1:
5427
                        dtWaypoints.Rows[dgvWP.SelectedIndex][12] = "255";
5428
                        break;
5429
                    case 2:
5430
                        dtWaypoints.Rows[dgvWP.SelectedIndex][12] = lblWPEditCamAngle.Content;
5431
                        break;
5432
                }
5433
                dtWaypoints.Rows[dgvWP.SelectedIndex][14] = lblWPEditOut1.Content;
5434
 
5435
                // _clearMapMarkers(typeof(CustomMarkerWP));
5436
                _repositionWPMarker(new PointLatLng((double)dtWaypoints.Rows[dgvWP.SelectedIndex][3], (double)dtWaypoints.Rows[dgvWP.SelectedIndex][4]),oldName);
5437
                _renameWPMarker(oldName, (string)dtWaypoints.Rows[dgvWP.SelectedIndex][2]);
5438
                _clearMapMarkers(typeof(CustomMarkerWPActive));
5439
                _setMarkerColor(_findWPMarker((string)dtWaypoints.Rows[dgvWP.SelectedIndex][2]), (int)dtWaypoints.Rows[dgvWP.SelectedIndex][1]);
5440
                _WPMarkerSetType((string)dtWaypoints.Rows[dgvWP.SelectedIndex][2], (int)dtWaypoints.Rows[dgvWP.SelectedIndex][1]);
5441
               // wpList.Clear();
5442
                if (mRouteWP != null)
5443
                    MainMap.Markers.Remove(mRouteWP);
5444
 
5445
                //for (int k = 0; k < dtWaypoints.Rows.Count; k++)
5446
                //{
5447
                //    _createWP(new PointLatLng((double)dtWaypoints.Rows[k][3], (double)dtWaypoints.Rows[k][4]), (string)dtWaypoints.Rows[k][2], (int)dtWaypoints.Rows[k][1]);
5448
                //}
5449
                _routeUpdate();
5450
                dgvWP.Items.Refresh();
5451
 
5452
            }
5453
 
5454
        }
5455
        private void btnEditWPAdd_Click(object sender, RoutedEventArgs e)
5456
        {
2554 - 5457
            if (tbWPEditLat.Text != "" && tbWPEditLon.Text !="")
2545 - 5458
            {
2554 - 5459
                DataRow dr = dtWaypoints.NewRow();
5460
                dr[0] = dtWaypoints.Rows.Count + 1;
5461
                dr[1] = cbWPEditType.SelectedIndex;
5462
                dr[2] = tbWPEditPrefix.Text + dr[0].ToString();
5463
                dr[3] = Convert.ToDouble(tbWPEditLat.Text.Replace('.', ',')) + 0.00000001;
5464
                dr[4] = Convert.ToDouble(tbWPEditLon.Text.Replace('.', ',')) + 0.00000001;
5465
                dr[5] = lblWPEditAlt.Content;
5466
                switch (cbWPEditHeading.SelectedIndex)
5467
                {
5468
                    case 0:
5469
                        dr[6] = "0";
5470
                        break;
5471
                    case 1:
5472
                        dr[6] = "-" + lblWPEditHeading.Content;
5473
                        break;
5474
                    case 2:
5475
                        dr[6] = lblWPEditHeading.Content;
5476
                        break;
5477
                }
5478
                switch (cbWPEditSpeed.SelectedIndex)
5479
                {
5480
                    case 0:
5481
                        dr[7] = "0";
5482
                        break;
5483
                    case 1:
5484
                        dr[7] = (System.Convert.ToDouble(lblWPEditSpeed.Content.ToString().Replace('.', ',')) * 10).ToString("0");
5485
                        break;
5486
                    case 2:
5487
                        dr[7] = (256 - Convert.ToInt16(lblWPEditSpeed.Content)).ToString();
5488
                        break;
5489
                }
5490
                switch (cbWPEditClimbrate.SelectedIndex)
5491
                {
5492
                    case 0:
5493
                        dr[8] = "255";
5494
                        break;
5495
                    case 1:
5496
                        dr[8] = (System.Convert.ToDouble(lblWPEditClimbrate.Content.ToString().Replace('.', ',')) * 10).ToString("0");
5497
                        break;
5498
                }
5499
                dr[9] = lblWPEditRadius.Content;
5500
                dr[10] = lblWPEditHoldtime.Content;
5501
                dr[11] = lblWPEditAutoTrigger.Content;
5502
                switch (cbWPEditCamAngle.SelectedIndex)
5503
                {
5504
                    case 0:
5505
                        dr[12] = "0";
5506
                        break;
5507
                    case 1:
5508
                        dr[12] = "255";
5509
                        break;
5510
                    case 2:
5511
                        dr[12] = lblWPEditCamAngle.Content;
5512
                        break;
5513
                }
5514
                dr[13] = "";
5515
                dr[14] = lblWPEditOut1.Content;
5516
                dr[15] = "";
5517
                _createWP(new PointLatLng((double)dr[3], (double)dr[4]), (string)dr[2], (int)dr[1], (int)dr[0]);
5518
                if (mRouteWP != null)
5519
                    MainMap.Markers.Remove(mRouteWP);
5520
                _routeUpdate();
5521
                dtWaypoints.Rows.Add(dr);
5522
                dgvWP.Items.Refresh();
2545 - 5523
            }
5524
        }
5525
        private void btnEditWPDel_Click(object sender, RoutedEventArgs e)
5526
        {
5527
            if (dgvWP.SelectedIndex > -1 && dgvWP.SelectedIndex < dtWaypoints.Rows.Count)
5528
            {
5529
                int index = dgvWP.SelectedIndex;
5530
                Dispatcher.Invoke(() => {
5531
                    DataGridRow row;
5532
                    if (_wpEdit > -1 && _wpEdit < dgvWP.ItemContainerGenerator.Items.Count)
5533
                    {
5534
                        row = (DataGridRow)dgvWP.ItemContainerGenerator.ContainerFromIndex(_wpEdit);
5535
                        row.Background = new SolidColorBrush(Colors.Transparent);
5536
                        row.BorderBrush = new SolidColorBrush(Colors.Transparent);
5537
                        row.BorderThickness = new Thickness(0);
5538
                    }
5539
                    if ((int)dtWaypoints.Rows[index][1] == 0 || (int)dtWaypoints.Rows[index][1] == 3)
5540
                        wpList.Remove(new PointLatLng((double)dtWaypoints.Rows[index][3], (double)dtWaypoints.Rows[index][4]));
5541
                    else
5542
                        wpOffset.Remove((int)dtWaypoints.Rows[index][0] + 1);
5543
                    _clearWPMarker((string)dtWaypoints.Rows[index][2]);
5544
                    if (wpActiveMarker != null)
5545
                        MainMap.Markers.Remove(wpActiveMarker);
5546
                    dtWaypoints.Rows[index].Delete();
5547
                    _wpIndex = -1;
5548
                    _wpEdit = -1;
5549
                    for (int i = index; i < dtWaypoints.Rows.Count; i++) //change the index of points behind deleted point + rename to new index
5550
                    {
5551
                        dtWaypoints.Rows[i][0] = i + 1;
5552
                        string s1 = (string)dtWaypoints.Rows[i][2]; //old name of WP (Prefix + index)
5553
                        string s2 = s1.Substring(0, 1) + (i + 1).ToString(); //new name of WP
5554
                        _renameWPMarker(s1, s2);
5555
                        dtWaypoints.Rows[i][2] = s2;
5556
                    }
5557
                    lblWPCount.Content = dtWaypoints.Rows.Count;
5558
                    if (mRouteWP != null)
5559
                        MainMap.Markers.Remove(mRouteWP);
5560
                    _routeUpdate();
5561
 
5562
                    dgvWP.UpdateLayout();
5563
                });
5564
            }
5565
        }
5566
        private void tbWPEdit_TouchDown(object sender, TouchEventArgs e)
5567
        {
5568
            _wpWEdit(sender);
5569
        }
5570
        private void tbWPEdit_KeyDown(object sender, KeyEventArgs e)
5571
        {
5572
            _wpWEdit(sender);
5573
        }
5574
        private void tbWPEdit_MouseDown(object sender, MouseButtonEventArgs e)
5575
        {
5576
            _wpWEdit(sender);
5577
        }
5578
        void _wpWEdit(object sender)
5579
        {
5580
           // if (!((TextBox)sender).IsReadOnly)
5581
            {
5582
                KeyPad.Keypad k = new KeyPad.Keypad(this);
5583
 
5584
                switch (((TextBox)sender).Name)
5585
                {
5586
                    case "tbWPEditLat":
5587
                        k.Title = "Latitude";
5588
                        k.LENGTH = 17;
5589
                        k.MAX = 359.9;
5590
                        break;
5591
                    case "tbWPEditLon":
5592
                        k.Title = "Longitude";
5593
                        k.LENGTH = 17;
5594
                        k.MAX = 359.9;
5595
                        break;
5596
                    case "tbWPEditAlt":
5597
                        k.Title = "Altitude";
5598
                        k.LENGTH = 3;
5599
                        k.MAX = 254;
5600
                        k.disableDecimal();
5601
                        break;
5602
                    case "tbWPEditHeading":
5603
                        k.Title = "Heading";
5604
                        k.LENGTH = 3;
5605
                        k.MAX = 359;
5606
                        k.MIN = 1;
5607
                        k.disableDecimal();
5608
                        break;
5609
                    case "tbWPEditSpeed":
5610
                        k.Title = "Speed";
5611
                        k.LENGTH = 4;
5612
                        k.MAX = 24.7;
5613
                        k.MIN = 0.1;
5614
                        break;
5615
                    case "tbWPEditClimbrate":
5616
                        k.Title = "Climbrate";
5617
                        k.LENGTH = 4;
5618
                        k.MAX = 25.4;
5619
                        k.MIN = 0.1;
5620
                        break;
5621
                    case "tbWPEditRadius":
5622
                        k.Title = "Radius";
5623
                        k.LENGTH = 3;
5624
                        k.MAX = 254;
5625
                        k.disableDecimal();
5626
                        break;
5627
                    case "tbWPEditHoldtime":
5628
                        k.Title = "Holdtime";
5629
                        k.LENGTH = 3;
5630
                        k.MAX = 254;
5631
                        break;
5632
                    case "tbWPEditAutoTrigger":
5633
                        k.Title = "Autotrigger";
5634
                        k.LENGTH = 3;
5635
                        k.MAX = 254;
5636
                        k.disableDecimal();
5637
                        break;
5638
                    case "tbWPEditCamAngle":
5639
                        k.Title = "Camera angle";
5640
                        k.LENGTH = 3;
5641
                        k.MAX = 254;
5642
                        k.MIN = 1;
5643
                        k.disableDecimal();
5644
                        break;
5645
                    case "tbWPEditOut1":
5646
                        k.Title = "OUT1 timer interval";
5647
                        k.LENGTH = 3;
5648
                        k.MAX = 254;
5649
                        k.disableDecimal();
5650
                        break;
5651
                }
5652
                k.Result = ((TextBox)sender).Text;
5653
                if (k.ShowDialog() == true && k.Result.Length > 0)
5654
                    ((TextBox)sender).Text = k.Result;
5655
            }
5656
 
5657
        }
5658
        private void btnWPAddCurrentPos_Click(object sender, RoutedEventArgs e)
5659
        {
5660
            _addWP(new PointLatLng(copter.Position.Lat, copter.Position.Lng),0);
5661
        }
5662
        private void checkBoxWPAddUseCopterHeading_Click(object sender, RoutedEventArgs e)
5663
        {
5664
            _wpAddCopterHeading = (bool)checkBoxWPAddUseCopterHeading.IsChecked;
5665
        }
5666
        private void checkBoxWPAddUseCopterHeight_Click(object sender, RoutedEventArgs e)
5667
        {
5668
            _wpAddCopterHeight = (bool)checkBoxWPAddUseCopterHeight.IsChecked;
5669
        }
5670
        private void btnSaveDefault_Click(object sender, RoutedEventArgs e)
5671
        {
5672
            _wpDefPrefix = tbWPEditPrefix.Text;
5673
            _wpDefAltitude = Convert.ToInt16(lblWPEditAlt.Content);
5674
            switch (cbWPEditHeading.SelectedIndex)
5675
            {
5676
                case 0:
5677
                    _wpDefHeading = 0;
5678
                    break;
5679
                case 1:
5680
                    _wpDefHeading = -Convert.ToInt16(lblWPEditHeading.Content);
5681
                    break;
5682
                case 2:
5683
                    _wpDefHeading = Convert.ToInt16(lblWPEditHeading.Content);
5684
                    break;
5685
            }            
5686
            _wpDefCBoxHeading = cbWPEditHeading.SelectedIndex;
5687
            switch (cbWPEditSpeed.SelectedIndex)
5688
            {
5689
                case 0:
5690
                    _wpDefSpeed = 0;
5691
                    break;
5692
                case 1:
5693
                    _wpDefSpeed = (int)(System.Convert.ToDouble(lblWPEditSpeed.Content.ToString().Replace('.', ',')) * 10);
5694
                    break;
5695
                case 2:
5696
                    _wpDefSpeed = 256 - Convert.ToInt16(lblWPEditSpeed.Content);
5697
                    break;
5698
            }
5699
            _wpDefCBoxSpeed = cbWPEditSpeed.SelectedIndex;
5700
            switch (cbWPEditClimbrate.SelectedIndex)
5701
            {
5702
                case 0:
5703
                    _wpDefClimb = 255;
5704
                    break;
5705
                case 1:
5706
                    _wpDefClimb = (int)(System.Convert.ToDouble(lblWPEditClimbrate.Content.ToString().Replace('.', ',')) * 10);
5707
                    break;
5708
            }
5709
            _wpDefCBoxClimb = cbWPEditClimbrate.SelectedIndex;
5710
            _wpDefRadius = Convert.ToInt16(lblWPEditRadius.Content);
5711
            _wpDefHoldtime = Convert.ToInt16(lblWPEditHoldtime.Content);
5712
            _wpDefAutotrig = Convert.ToInt16(lblWPEditAutoTrigger.Content);
5713
            switch (cbWPEditCamAngle.SelectedIndex)
5714
            {
5715
                case 0:
5716
                    _wpDefCamangle = 0;
5717
                    break;
5718
                case 1:
5719
                    _wpDefCamangle = 255;
5720
                    break;
5721
                case 2:
5722
                    _wpDefCamangle = Convert.ToInt16(lblWPEditCamAngle.Content);
5723
                    break;
5724
            }
5725
            _wpDefCBoxCamangle = cbWPEditCamAngle.SelectedIndex;
5726
            _wpDefOut1 = Convert.ToInt16(lblWPEditOut1.Content);
5727
        }
5728
 
5729
        private void btnWPEditmoveUp_Click(object sender, RoutedEventArgs e)
5730
        {
5731
            if (dgvWP.SelectedIndex > 0 && dgvWP.SelectedIndex < dtWaypoints.Rows.Count)
5732
            {
5733
                int index = dgvWP.SelectedIndex;
5734
                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)
5735
                {
5736
                    PointLatLng x = new PointLatLng((double)dtWaypoints.Rows[index][3], (double)dtWaypoints.Rows[index][4]);
5737
                    int wpListIndex = wpList.IndexOf(x);
5738
                    if (wpListIndex > 0)
5739
                    {
5740
                        wpList.RemoveAt(wpListIndex);
5741
                        wpList.Insert(wpListIndex - 1, x);
5742
                        MainMap.Markers.Remove(mRouteWP);
5743
                        _routeUpdate();
5744
                    }
5745
                }
5746
                DataRow dr = dtWaypoints.Rows[index];
5747
                DataRow newRow = dtWaypoints.NewRow();
5748
                newRow.ItemArray = dr.ItemArray;
5749
                dtWaypoints.Rows.Remove(dr);
5750
                dtWaypoints.Rows.InsertAt(newRow, index - 1);
5751
                dtWaypoints.Rows[index][0] = 100;
5752
                dtWaypoints.Rows[index - 1][0] = index;
5753
                GMapMarker m1 = _findWPMarker(dtWaypoints.Rows[index - 1][2].ToString());
5754
                GMapMarker m2 = _findWPMarker(dtWaypoints.Rows[index][2].ToString());
5755
                dtWaypoints.Rows[index - 1][2] = dtWaypoints.Rows[index - 1][2].ToString().Substring(0, 1) + index.ToString();
5756
                ((CustomMarkerWP)m1.Shape).text.Text = dtWaypoints.Rows[index - 1][2].ToString();
5757
                dtWaypoints.Rows[index][0] = index + 1;
5758
                dtWaypoints.Rows[index][2] = dtWaypoints.Rows[index][2].ToString().Substring(0, 1) + (index+1).ToString();
5759
                ((CustomMarkerWP)m2.Shape).text.Text = dtWaypoints.Rows[index][2].ToString();
5760
                dgvWP.Items.Refresh();
5761
                dgvWP.SelectedIndex = index - 1;
5762
                _dgvWPselectEditRow();
5763
                if (wpOffset.Contains(index)) // calculating offset for wpList (index is 0-based - offset starts with index 1)
5764
                {
5765
                    int iOffset = wpOffset.IndexOf(index);
5766
                    if (iOffset > 0) // if not first element
5767
                    {
5768
                        if (wpOffset[iOffset - 1] < index-1) //if previous element is not immediately before actual offset
5769
                            wpOffset[iOffset] = index-1;  //then decrease offset value by one
5770
                    }
5771
                    else
5772
                        wpOffset[iOffset] = index-1; //if first element, decrease offset by one
5773
                }
5774
                else //selected line is POI
5775
                {
5776
                    if (wpOffset.Contains(index - 1)) // if next point is WP
5777
                    {
5778
                        int iOffset = wpOffset.IndexOf(index - 1);
5779
                        wpOffset[iOffset] = index; //decrease linenumber of following WP
5780
                    }
5781
                }
5782
 
5783
            }
5784
        }
5785
        private void btnWPEditmoveDown_Click(object sender, RoutedEventArgs e)
5786
        {
5787
            if (dgvWP.SelectedIndex > -1 && dgvWP.SelectedIndex < dtWaypoints.Rows.Count - 1)
5788
            {
5789
                int index = dgvWP.SelectedIndex;
5790
                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)
5791
                {
5792
                    PointLatLng x = new PointLatLng((double)dtWaypoints.Rows[index][3], (double)dtWaypoints.Rows[index][4]);
5793
                    int wpListIndex = wpList.IndexOf(x);
5794
                    if (wpListIndex > -1)
5795
                    {
5796
                        wpList.RemoveAt(wpListIndex);
5797
                        if (wpList.Count > wpListIndex)
5798
                            wpList.Insert(wpListIndex + 1, x);
5799
                        else
5800
                            wpList.Add(x);
5801
                        MainMap.Markers.Remove(mRouteWP);
5802
                        _routeUpdate();
5803
                    }
5804
                }
5805
                DataRow dr = dtWaypoints.Rows[index];
5806
                DataRow newRow = dtWaypoints.NewRow();
5807
                newRow.ItemArray = dr.ItemArray;
5808
                dtWaypoints.Rows.Remove(dr);
5809
                dtWaypoints.Rows.InsertAt(newRow, index + 1);
5810
                dtWaypoints.Rows[index][0] = 100;
5811
                dtWaypoints.Rows[index + 1][0] = index + 2;
5812
                GMapMarker m1 = _findWPMarker(dtWaypoints.Rows[index + 1][2].ToString());
5813
                GMapMarker m2 = _findWPMarker(dtWaypoints.Rows[index][2].ToString());
5814
                dtWaypoints.Rows[index + 1][2] = dtWaypoints.Rows[index + 1][2].ToString().Substring(0, 1) + (index+2).ToString();
5815
                ((CustomMarkerWP)m1.Shape).text.Text = dtWaypoints.Rows[index + 1][2].ToString();
5816
                dtWaypoints.Rows[index][0] = index + 1;
5817
                dtWaypoints.Rows[index][2] = dtWaypoints.Rows[index][2].ToString().Substring(0, 1) + (index+1).ToString();
5818
                ((CustomMarkerWP)m2.Shape).text.Text = dtWaypoints.Rows[index][2].ToString();
5819
                dgvWP.Items.Refresh();
5820
                dgvWP.SelectedIndex = index + 1;
5821
                _dgvWPselectEditRow();
5822
                if(wpOffset.Contains(index)) // If selected line is WP
5823
                {
5824
                    int iOffset = wpOffset.IndexOf(index);
5825
                    if(iOffset < wpOffset.Count -1) // if not last element
5826
                    {
5827
                        if (wpOffset[iOffset + 1] > index + 1) //if next element is not immediately after actual offset
5828
                            wpOffset[iOffset] = index + 1;  //then increase offset value by one
5829
                    }
5830
                    else
5831
                        wpOffset[iOffset] = index + 1; //if last element increase offset by one
5832
                }
5833
                else //selected line is POI
5834
                {
5835
                    if (wpOffset.Contains(index + 1)) // if next point is WP
5836
                    {
5837
                        int iOffset = wpOffset.IndexOf(index + 1);
5838
                        wpOffset[iOffset] = index; //decrease linenumber of following WP
5839
                    }
5840
                }
5841
            }
5842
 
5843
        }
5844
 
5845
        private void checkBoxShowWPStatus_Click(object sender, RoutedEventArgs e)
5846
        {
5847
            if (WPStatus.Visibility == Visibility.Visible)
5848
                GridOSD.Margin = new Thickness(GridOSD.Margin.Left, 36 * UIScaleTopSlider.Value + 36, GridOSD.Margin.Right, GridOSD.Margin.Bottom);
5849
            else
5850
                GridOSD.Margin = new Thickness(GridOSD.Margin.Left, 36 * UIScaleTopSlider.Value, GridOSD.Margin.Right, GridOSD.Margin.Bottom);
5851
        }
5852
        private void checkBoxShowWPMaxRange_click(object sender, RoutedEventArgs e)
5853
        {
5854
            if (home != null && checkBoxShowWPMaxRange.IsChecked == true && dWPMaxRange > 0)
5855
            {
5856
                if (cWPBound != null && cWPBound.Tag != null)
5857
                    MainMap.Markers.Remove(cWPBound.Tag as GMapMarker);
5858
 
5859
                createCircle(home.Position, dWPMaxRange);
5860
                if (comboBoxWPMaxRangeColor.SelectionBoxItem != null)
5861
                {
5862
                    string s = _colors[comboBoxWPMaxRangeColor.SelectedIndex];
5863
                    cWPBound.setColor(s);
5864
                }
5865
            }
5866
 
5867
            if (checkBoxShowWPMaxRange.IsChecked == false && (cWPBound != null && cWPBound.Tag != null))
5868
                MainMap.Markers.Remove(cWPBound.Tag as GMapMarker);
5869
        }
5870
        private void checkBoxAutoShowWPEdit_Click(object sender, RoutedEventArgs e)
5871
        {
5872
             _bAutoWPEdit = (bool)checkBoxAutoShowWPEdit.IsChecked;
5873
        }
5874
 
5875
        #endregion WP
5876
        #region GPX
5877
        private void checkBoxGPXLog_Click(object sender, RoutedEventArgs e)
5878
        {
5879
            _bGPXLog = (bool)checkBoxGPXLog.IsChecked;
5880
        }
5881
        void _gpxAdd(double lat,double lon, int elevation)
5882
        {
5883
            DataRow dr = dtGPX.NewRow();
5884
            dr[0] = dtGPX.Rows.Count - 1;
5885
            dr[1] = lat;
5886
            dr[2] = lon;
5887
            dr[3] = elevation;
5888
            dr[4] = DateTime.UtcNow.ToString("s", System.Globalization.CultureInfo.InvariantCulture); //2011-01-14T01:59:01Z
5889
            dtGPX.Rows.Add(dr);
5890
        }
5891
 
5892
        void _saveGPXLog()
5893
        {
5894
            if (!Directory.Exists("GPXLog"))
5895
                Directory.CreateDirectory("GPXLog");
5896
            string SaveFileName = "GPXLog\\" + DateTime.Now.ToString("yyyyMMdd_HHmm") + ".gpx";
5897
            XmlTextWriter myXmlTextWriter = null;
5898
            myXmlTextWriter = new XmlTextWriter(SaveFileName, null);
5899
            NumberFormatInfo nfi = new NumberFormatInfo();
5900
            nfi.NumberDecimalSeparator = ".";
5901
 
5902
            try
5903
            {
5904
                myXmlTextWriter.Formatting = Formatting.Indented;
5905
 
5906
                myXmlTextWriter.WriteStartDocument();
5907
 
5908
                myXmlTextWriter.WriteStartElement("gpx");
5909
 
5910
                myXmlTextWriter.WriteAttributeString("version", "1.0");
5911
                myXmlTextWriter.WriteAttributeString("creator", "MKLiveView v1.0");
5912
                myXmlTextWriter.WriteAttributeString("xmlns:xsi", "http://www.w3.org/2001/XMLSchema-instance");
5913
                myXmlTextWriter.WriteAttributeString("xmlns", "http://www.topografix.com/GPX/1/1");
5914
                myXmlTextWriter.WriteAttributeString("xsi:schemaLocation", "http://www.topografix.com/GPX/1/1/gpx.xsd");
5915
 
5916
                myXmlTextWriter.WriteElementString("time", DateTime.UtcNow.ToString("u", System.Globalization.CultureInfo.InvariantCulture));
5917
 
5918
                myXmlTextWriter.WriteStartElement("trk");
5919
                myXmlTextWriter.WriteStartElement("trkseg");
5920
                for(int i = 0; i< dtGPX.Rows.Count;i++)
5921
                {
5922
                    myXmlTextWriter.WriteStartElement("trkpt");
5923
                    myXmlTextWriter.WriteAttributeString("lat", dtGPX.Rows[i][1].ToString() != "" ? ((double)dtGPX.Rows[i][1]).ToString(nfi) : "");
5924
                    myXmlTextWriter.WriteAttributeString("lon", dtGPX.Rows[i][2].ToString() != "" ? ((double)dtGPX.Rows[i][2]).ToString(nfi) : "");
5925
                    myXmlTextWriter.WriteElementString("ele", dtGPX.Rows[i][3].ToString());
5926
                    myXmlTextWriter.WriteElementString("time", dtGPX.Rows[i][4].ToString());
5927
                    myXmlTextWriter.WriteEndElement();
5928
                }
5929
                myXmlTextWriter.WriteEndElement();
5930
                myXmlTextWriter.WriteEndElement();
5931
                myXmlTextWriter.WriteEndElement();
5932
            }
5933
            catch (Exception e)
5934
            {
5935
                Console.WriteLine("Exception: {0}", e.ToString());
5936
            }
5937
            finally
5938
            {
5939
                if (myXmlTextWriter != null)
5940
                {
5941
                    myXmlTextWriter.Close();
5942
                }
5943
            }
5944
        }
5945
 
5946
        private void btnLoadGPXLog_Click(object sender, RoutedEventArgs e)
5947
        {
5948
            _loadGPXLog();
5949
        }
5950
 
5951
        private void btnClearRoute_Click(object sender, RoutedEventArgs e)
5952
        {
5953
            _clearMapMarkers(typeof(GMapRoute));
5954
        }
5955
        void _loadGPXLog()
5956
        {
5957
 
5958
            Microsoft.Win32.OpenFileDialog fd = new Microsoft.Win32.OpenFileDialog();
5959
            fd.Filter = "GPX-Logfile | *.gpx";
5960
            fd.Multiselect = false;
5961
            if (fd.ShowDialog().Value)
5962
            {
5963
                string file = fd.FileName;
5964
                try
5965
                {
5966
                    XDocument gpxDoc = XDocument.Load(file);
5967
                    XNamespace gpx = XNamespace.Get("http://www.topografix.com/GPX/1/1");
5968
 
5969
                    NumberFormatInfo nfi = new NumberFormatInfo();
5970
                    nfi.NumberDecimalSeparator = ".";
5971
 
5972
                    var tracks = from track in gpxDoc.Descendants(gpx + "trk")
5973
                                 select new
5974
                                 {
5975
                                     Name = track.Element(gpx + "name") != null ? track.Element(gpx + "name").Value : null,
5976
                                     Segs = (
5977
                                         from trackpoint in track.Descendants(gpx + "trkpt")
5978
                                         select new
5979
                                         {
5980
                                             Latitude = trackpoint.Attribute("lat").Value,
5981
                                             Longitude = trackpoint.Attribute("lon").Value,
5982
                                             Elevation = trackpoint.Element(gpx + "ele") != null ?
5983
                                             trackpoint.Element(gpx + "ele").Value : null,
5984
                                             Time = trackpoint.Element(gpx + "time") != null ?
5985
                                             trackpoint.Element(gpx + "time").Value : null
5986
                                         }
5987
                                     )
5988
                                 };
5989
 
5990
                    List<PointLatLng> wpl = new List<PointLatLng>();
5991
                    foreach(var trk in tracks)
5992
                    {
5993
                        foreach(var trkseg in trk.Segs)
5994
                        {
5995
                            if(trkseg.Latitude != "" && trkseg.Longitude !="")
5996
                            wpl.Add(new PointLatLng(Convert.ToDouble(trkseg.Latitude, nfi), Convert.ToDouble(trkseg.Longitude, nfi)));
5997
                        }
5998
 
5999
                    }
6000
                    if(wpl.Count() > 0)
6001
                    {
6002
                        _clearMapMarkers(typeof(GMapRoute));
6003
                        MapRoute mr = new MapRoute(wpl, "flying");
6004
                        Dispatcher.Invoke(() =>
6005
                        {
6006
                            GMapRoute mRoute;
6007
                            if (comboBoxRouteColor.SelectionBoxItem != null)
6008
                            {
6009
                                string s = _colors[comboBoxRouteColor.SelectedIndex];
6010
                                mRoute = new GMapRoute(wpl, _getBrush(s));
6011
                            }
6012
                            else
6013
                                mRoute = new GMapRoute(wpl, null);
6014
 
6015
                            MainMap.Markers.Add(mRoute);
6016
                        });
6017
                    }
6018
 
6019
                }
6020
                catch (Exception e)
6021
                {
6022
                    Console.WriteLine("Exception: {0}", e.ToString());
6023
                }
6024
            }
6025
        }
6026
        #endregion GPX
6027
 
6028
        /// <summary>
6029
        /// switch language
6030
        /// </summary>
6031
        /// <param name="culture">specific culture</param>
6032
        public void ChangeLanguage(string culture)
6033
        {
6034
            // Alle Woerterbuecher finden   
6035
            List<ResourceDictionary> dictionaryList = new List<ResourceDictionary>();
6036
            foreach (ResourceDictionary dictionary in Application.Current.Resources.MergedDictionaries)
6037
            {
6038
                dictionaryList.Add(dictionary);
6039
            }
6040
 
6041
            // Woerterbuch waehlen
6042
            string requestedCulture = string.Format("Localize/localization.{0}.xaml", culture);
6043
            ResourceDictionary resourceDictionary = dictionaryList.FirstOrDefault(d => d.Source.OriginalString == requestedCulture);
6044
            if (resourceDictionary == null)
6045
            {
6046
                // Wenn das gewuenschte Woerterbuch nicht gefunden wird,
6047
                // lade Standard-Woerterbuch
6048
                requestedCulture = "Localize/localization.xaml";
6049
                resourceDictionary = dictionaryList.FirstOrDefault(d => d.Source.OriginalString == requestedCulture);
6050
            }
6051
 
6052
            // Altes Woerterbuch loeschen und Neues hinzufuegen       
6053
            if (resourceDictionary != null)
6054
            {
6055
                Application.Current.Resources.MergedDictionaries.Remove(resourceDictionary);
6056
                Application.Current.Resources.MergedDictionaries.Add(resourceDictionary);
6057
            }
6058
 
6059
            // Hauptthread ueber neues Culture informieren
6060
            Thread.CurrentThread.CurrentCulture = CultureInfo.CreateSpecificCulture(culture);
6061
            Thread.CurrentThread.CurrentUICulture = new CultureInfo(culture);
6062
        }
6063
        private void cbLang_DropDownClosed(object sender, EventArgs e)
6064
        {
6065
            if (cbLang.SelectedIndex > -1)
6066
            {
6067
                _iUILanguage = cbLang.SelectedIndex;
6068
                ChangeLanguage(_UILanguage[_iUILanguage]);
6069
            }
6070
        }
6071
 
6072
        #endregion functions
6073
    }
6074
 
6075
    /// <summary>
6076
    /// formats the wp datatable values for display in datagrid - this is bound in the datagrid as a converter
6077
    /// </summary>
6078
    public class waypointsConverter : IValueConverter
6079
    {
6080
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
6081
        {
6082
            if (value != null)
6083
            {
6084
                switch ((string)parameter)
6085
                {
6086
                    case "Latitude":
6087
                        return value.ToString() + " °";
6088
                    case "Longitude":
6089
                        return value.ToString() + " °";
6090
                    case "Radius":
6091
                        return value.ToString() + " m";
6092
                    case "Altitude":
6093
                        return value.ToString() + " m";
6094
                    case "ClimbRate":
6095
                        return value.ToString() == "255" ? "Auto" : (System.Convert.ToDouble(value) / 10).ToString("0.0 m/s");
6096
                    case "DelayTime":
6097
                        return value.ToString() + " s";
6098
                    case "Heading":
6099
                        return Waypoints.Heading(System.Convert.ToInt32(value));
6100
                    case "Speed":
6101
                        return Waypoints.WPSpeed(System.Convert.ToInt16(value));
6102
                    case "CamAngle":
6103
                        return Waypoints.CAMAngle(System.Convert.ToInt16(value));
6104
                    case "Type":
6105
                        return ((Waypoints.pointType)(System.Convert.ToInt16(value))).ToString();
6106
                    case "AutoTrigger":
6107
                        return value.ToString() == "0" ? "- - -" : value.ToString() + " m";
6108
                    case "Status":
6109
                        return (Waypoints.status)(System.Convert.ToInt16(value));
6110
                }
6111
 
6112
                return value.ToString();
6113
            }
6114
            else return value;
6115
        }
6116
 
6117
        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
6118
        {
6119
            throw new NotImplementedException();
6120
        }
6121
    }
6122
    public class IniFile
6123
    {
6124
        public string path;
6125
 
6126
        [DllImport("kernel32")]
6127
        private static extern long WritePrivateProfileString(string section,
6128
          string key, string val, string filePath);
6129
 
6130
        [DllImport("kernel32.dll", CharSet = CharSet.Auto)]
6131
        static extern uint GetPrivateProfileSectionNames(IntPtr lpszReturnBuffer,
6132
               uint nSize, string lpFileName);
6133
 
6134
        [DllImport("kernel32")]
6135
        private static extern int GetPrivateProfileString(string section,
6136
          string key, string def, StringBuilder retVal,
6137
          int size, string filePath);
6138
 
6139
        public IniFile(string INIPath)
6140
        {
6141
            path = INIPath;
6142
        }
6143
 
6144
        public void IniWriteValue(string Section, string Key, string Value)
6145
        {
6146
            WritePrivateProfileString(Section, Key, Value, this.path);
6147
        }
6148
 
6149
        public string IniReadValue(string Section, string Key)
6150
        {
6151
            StringBuilder temp = new StringBuilder(255);
6152
            int i = GetPrivateProfileString(Section, Key, "", temp, 255, this.path);
6153
            return temp.ToString();
6154
        }
6155
        //Ini_sections auslesen in String-Array
6156
        public string[] IniSectionNames()
6157
        {
6158
 
6159
            //  uint MAX_BUFFER = 32767;
6160
            uint MAX_BUFFER = 8388608;
6161
            IntPtr pReturnedString = Marshal.AllocCoTaskMem((int)MAX_BUFFER);
6162
            uint bytesReturned = GetPrivateProfileSectionNames(pReturnedString, MAX_BUFFER, this.path);
6163
            if (bytesReturned == 0)
6164
            {
6165
                Marshal.FreeCoTaskMem(pReturnedString);
6166
                return null;
6167
            }
6168
            string local = Marshal.PtrToStringAuto(pReturnedString, (int)bytesReturned).ToString();
6169
            Marshal.FreeCoTaskMem(pReturnedString);
6170
            //use of Substring below removes terminating null for split
6171
            return local.Substring(0, local.Length - 1).Split('\0');
6172
 
6173
 
6174
        }
6175
    }
6176
    /// <summary>
6177
    /// Selected Win AI Function Calls
6178
    /// </summary>
6179
    public class WinApi
6180
    {
6181
        [DllImport("user32.dll", EntryPoint = "GetSystemMetrics")]
6182
        public static extern int GetSystemMetrics(int which);
6183
        [DllImport("user32.dll")]
6184
        public static extern void
6185
                SetWindowPos(IntPtr hwnd, IntPtr hwndInsertAfter,
6186
                             int X, int Y, int width, int height, uint flags);
6187
 
6188
        private const int SM_CXSCREEN = 0;
6189
        private const int SM_CYSCREEN = 1;
6190
        private static IntPtr HWND_TOP = IntPtr.Zero;
6191
        private const int SWP_SHOWWINDOW = 64; // 0x0040
6192
 
6193
        public static int ScreenX
6194
        {
6195
            get { return GetSystemMetrics(SM_CXSCREEN); }
6196
        }
6197
 
6198
        public static int ScreenY
6199
        {
6200
            get { return GetSystemMetrics(SM_CYSCREEN); }
6201
        }
6202
 
6203
        public static void SetWinFullScreen(IntPtr hwnd)
6204
        {
6205
            SetWindowPos(hwnd, HWND_TOP, -8, -7, ScreenX+15, ScreenY+14, SWP_SHOWWINDOW);
6206
        }
6207
    }
6208
    /// <summary>
6209
    /// Class used to preserve / restore state of the window
6210
    /// </summary>
6211
    public class WinState
6212
    {
6213
        private WindowState winState;
6214
        private WindowStyle brdStyle;
6215
        private bool topMost;
6216
        private Rect restore;
6217
        private bool IsMaximized = false;
6218
 
6219
        public bool isMaximized
6220
        {
6221
            get { return IsMaximized; }
6222
        }
6223
        public void Maximize(Window targetForm)
6224
        {
6225
            if (!IsMaximized)
6226
            {
6227
                IsMaximized = true;
6228
                Save(targetForm);
6229
                targetForm.WindowState = WindowState.Maximized;
6230
                targetForm.WindowStyle = WindowStyle.None;
6231
                targetForm.Topmost = true;
6232
                WinApi.SetWinFullScreen(new WindowInteropHelper(targetForm).Handle);
6233
            }
6234
        }
6235
 
6236
        public void Save(Window targetForm)
6237
        {
6238
            winState = targetForm.WindowState;
6239
            brdStyle = targetForm.WindowStyle;
6240
            topMost = targetForm.Topmost;
6241
            restore = targetForm.RestoreBounds;
6242
        }
6243
        public void Restore(Window targetForm)
6244
        {
6245
            targetForm.WindowState = winState;
6246
            targetForm.WindowStyle = brdStyle;
6247
            targetForm.Topmost = topMost;
6248
 
6249
            targetForm.Left = restore.Left;
6250
            targetForm.Top = restore.Top;
6251
            targetForm.Height = restore.Height;
6252
            targetForm.Width = restore.Width;
6253
            IsMaximized = false;
6254
        }
6255
    }
6256
 
6257
    public static class BitmapConversion
6258
    {
6259
        public static System.Drawing.Bitmap ToWinFormsBitmap(this BitmapSource bitmapsource)
6260
        {
6261
            using (MemoryStream stream = new MemoryStream())
6262
            {
6263
                BitmapEncoder enc = new BmpBitmapEncoder();
6264
                enc.Frames.Add(BitmapFrame.Create(bitmapsource));
6265
                enc.Save(stream);
6266
                using (var tempBitmap = new System.Drawing.Bitmap(stream))
6267
                {
6268
                    // According to MSDN, one "must keep the stream open for the lifetime of the Bitmap."
6269
                    // So we return a copy of the new bitmap, allowing us to dispose both the bitmap and the stream.
6270
                    return new System.Drawing.Bitmap(tempBitmap);
6271
                }
6272
            }
6273
        }
6274
        public static BitmapSource ToWpfBitmap(this System.Drawing.Bitmap bitmap)
6275
        {
6276
            using (MemoryStream stream = new MemoryStream())
6277
            {
6278
                bitmap.Save(stream, System.Drawing.Imaging.ImageFormat.Bmp); stream.Position = 0;
6279
                BitmapImage result = new BitmapImage();
6280
                result.BeginInit();
6281
                // According to MSDN, "The default OnDemand cache option retains access to the stream until the image is needed."
6282
                // Force the bitmap to load right now so we can dispose the stream.
6283
                result.CacheOption = BitmapCacheOption.OnLoad;
6284
                result.StreamSource = stream;
6285
                result.EndInit();
6286
                result.Freeze();
6287
                return result;
6288
            }
6289
        }
6290
    }
6291
 
6292
}