Subversion Repositories Projects

Rev

Details | Last modification | View Log | RSS feed

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