Subversion Repositories Projects

Rev

Details | Last modification | View Log | RSS feed

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