Subversion Repositories Projects

Rev

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

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