Subversion Repositories Projects

Rev

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

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