Subversion Repositories Projects

Rev

Rev 2431 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

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