private void Device_MouseDoubleClick(object sender, MouseButtonEventArgs e)
 {
     if (SelectedDevice != null)
     {
         CurrentStep = SelectedDevice.StartsWith("Serial") ? Steps.WaitForDeviceConfirm : Steps.WaitForConnection;
         AdvanceStateMachine();
     }
 }
        private void AdvanceStateMachine()
        {
            switch (CurrentStep)
            {
            case Steps.Idle:                     // Clicked on device
                CurrentStep    = Steps.WaitForDeviceConfirm;
                ShowNextButton = true;
                break;

            case Steps.WaitForDeviceConfirm:                     // Clicked on Next
                CurrentStep    = SelectedDevice.StartsWith("Serial") ? Steps.WaitForBaudrate : Steps.WaitForConnection;
                ShowBaudRate   = CurrentStep == Steps.WaitForBaudrate;
                ShowNextButton = !string.IsNullOrEmpty(SelectedBaudRate);
                break;

            case Steps.WaitForBaudrate:
            case Steps.WaitForConnection:
                GPSStatus     = $"Connecting to OAT on {SelectedDevice}{(SelectedDevice.StartsWith("Serial") ? " at " + SelectedBaudRate + " baud" : "")}";
                ShowGPSStatus = true;
                CurrentStep   = Steps.CheckHardware;
                break;

            case Steps.CheckHardware:
                // NOP
                break;

            case Steps.WaitForLevel:
                // Turn off the Level
                var doneEvent = new AutoResetEvent(false);
                _sendCommand(":XL0#,#", (a) => { doneEvent.Set(); });
                doneEvent.WaitOne();

                if (_mountViewModel.IsAddonSupported("GPS"))
                {
                    CurrentStep       = Steps.WaitForGPS;
                    ShowGPSStatus     = true;
                    _startedGPSWaitAt = DateTime.UtcNow;
                }
                else
                {
                    ShowManualLocation = true;
                    CurrentStep        = Steps.ConfirmLocation;
                }
                break;

            case Steps.WaitForGPS:
                // We have a GPS, but the user is too impatient. We'll assume the location that OAT has stored is accurate and use that.
                ShowManualLocation = true;
                CurrentStep        = Steps.ConfirmLocation;
                GPSStatus          = "GPS acquisition cancelled, please enter location:";
                var   locDoneEvent = new AutoResetEvent(false);
                bool  gotLoc = false;
                float lat = 0, lng = 0;
                _sendCommand(":Gt#,#", (a) => { gotLoc = a.Success && TryParseLatLong(a.Data, ref lat); });
                _sendCommand(":Gg#,#", (a) => { gotLoc = gotLoc && a.Success && TryParseLatLong(a.Data, ref lng); locDoneEvent.Set(); });
                locDoneEvent.WaitOne();
                if (gotLoc)
                {
                    Latitude  = lat;
                    Longitude = 180.0f - lng;
                }
                break;

            case Steps.ConfirmLocation:
                GPSStatus = "Sync'd! Setting OAT location...";
                Task.Run(() => _mountViewModel.SetSiteLatitude(Latitude)).Wait();
                Task.Run(() => _mountViewModel.SetSiteLongitude(Longitude)).Wait();
                Settings.Default.SiteLatitude  = Latitude;
                Settings.Default.SiteLongitude = Longitude;
                Settings.Default.SiteAltitude  = Altitude;
                Settings.Default.Save();
                CurrentStep = Steps.Completed;
                break;

            case Steps.Completed:
                this.Result = true;
                this.Close();
                break;

            default: break;
            }
        }