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