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