Subversion Repositories Projects

Rev

Details | Last modification | View Log | RSS feed

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