Subversion Repositories Projects

Rev

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