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