SearchPatrolSettings LoadSettings()
        {
            SearchPatrolSettings settings = null;

            try
            {
                if (File.Exists(settingsFile))
                {
                    var json = File.ReadAllText(settingsFile);
                    settings = JsonConvert.DeserializeObject <SearchPatrolSettings>(json);
                }
            }
            catch (Exception e)
            {
                MessageBox.Show($"Error loading settings: {e}");
            }
            if (settings == null)
            {
                settings = new SearchPatrolSettings
                {
                    MinRange            = searchPatrol.TargetRangeKmMin,
                    MaxRange            = searchPatrol.TargetRangeKmMax,
                    TargetDirection     = searchPatrol.TargetDirection,
                    DirectionRandomness = searchPatrol.DirectionRandomness,
                    TargetFoundDistance = searchPatrol.TargetFoundDistance,
                    TargetChoices       = searchPatrol.TargetChoices,
                    TextAnnouncement    = searchPatrol.ShowTextAnnouncements
                };
            }

            settings.TargetChoices.RemoveAll(t => removeTargetTypes.Contains(t));

            return(settings);
        }
        public SearchPatrolViewModel()
        {
            settings = LoadSettings();
            foreach (var t in searchPatrol.TargetChoices)
            {
                searchPatrol.SetTargetEnabled(t, settings.TargetChoices.Contains(t));
            }

            searchPatrol.TargetRangeKmMin    = MinRange.Value = settings.MinRange;
            searchPatrol.TargetRangeKmMax    = MaxRange.Value = settings.MaxRange;
            searchPatrol.TargetDirection     = TargetDirection.Value = settings.TargetDirection;
            searchPatrol.DirectionRandomness = DirectionRandomness.Value = settings.DirectionRandomness;
            searchPatrol.TargetFoundDistance = TargetFoundDistance.Value = settings.TargetFoundDistance;

            MinRange.PropertyChanged += (sender, args) =>
            {
                settings.MinRange = searchPatrol.TargetRangeKmMin = MinRange.Value;
                if (MinRange.Value > MaxRange.Value)
                {
                    settings.MaxRange = MaxRange.Value = MinRange.Value;
                }
                SaveSettings();
            };

            MaxRange.PropertyChanged += (sender, args) =>
            {
                settings.MaxRange = searchPatrol.TargetRangeKmMax = MaxRange.Value;
                if (MaxRange.Value < MinRange.Value)
                {
                    settings.MinRange = MinRange.Value = MaxRange.Value;
                }
                SaveSettings();
            };

            TargetDirection.PropertyChanged += (sender, args) =>
            {
                settings.TargetDirection = searchPatrol.TargetDirection = TargetDirection.Value;
                SaveSettings();
            };

            TargetFoundDistance.PropertyChanged += (sender, args) =>
            {
                settings.TargetFoundDistance = searchPatrol.TargetFoundDistance = TargetFoundDistance.Value;
                SaveSettings();
            };

            DirectionRandomness.PropertyChanged += (sender, args) =>
            {
                settings.DirectionRandomness = searchPatrol.DirectionRandomness = DirectionRandomness.Value;
                SaveSettings();
            };

            VoiceAnnouncement.Value            = settings.VoiceAnnouncement;
            VoiceAnnouncement.PropertyChanged += (sender, args) =>
            {
                settings.VoiceAnnouncement = VoiceAnnouncement.Value;
                SaveSettings();
            };

            VoiceVolume.Value            = settings.VoiceVolume;
            VoiceVolume.PropertyChanged += (sender, args) =>
            {
                if (VoiceVolume.Value < 0)
                {
                    VoiceVolume.Value = 0;
                }
                if (VoiceVolume.Value > 100)
                {
                    VoiceVolume.Value = 100;
                }
                speechSynth.Volume = settings.VoiceVolume = VoiceVolume.Value;
                SaveSettings();
            };

            searchPatrol.ShowTextAnnouncements = TextAnnouncement.Value = settings.TextAnnouncement;
            TextAnnouncement.PropertyChanged  += (sender, args) =>
            {
                settings.TextAnnouncement = searchPatrol.ShowTextAnnouncements = TextAnnouncement.Value;
                SaveSettings();
            };

            CmdPlaceTarget     = new BaseCommand((p) => { PlaceTarget(); });
            CmdCopyTargetInfo  = new BaseCommand((o) => { CopyTargetInfo(); });
            CmdPasteTargetInfo = new BaseCommand((o) => { PasteTargetInfo(); });

            CreateTargetProp(AircraftIsChecked);
            CreateTargetProp(GroundVehicleIsChecked);
            CreateTargetProp(WindmillIsChecked);
            CreateTargetProp(BoatIsChecked);
            CreateTargetProp(FishingBoatIsChecked);
            CreateTargetProp(YachtIsChecked);
            CreateTargetProp(CargoShipIsChecked);
            CreateTargetProp(CruiseShipIsChecked);
            CreateTargetProp(AnimalIsChecked);
            CreateTargetProp(HumanIsChecked);
            CreateTargetProp(WindsockIsChecked);

            searchPatrol.OnAnnouncement += OnAnnouncement;

            timer.Interval = new TimeSpan(0, 0, 0, 1, 0);
            timer.Tick    += new EventHandler(OnTick);
            timer.Start();
        }