Subversion Repositories Projects

Rev

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

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