using OperationControl.Helpers; using System; using System.Collections.Generic; using System.ComponentModel; using System.Globalization; using System.Windows; using System.Windows.Input; namespace OperationControl.ViewModels { public enum MetodoFixacaoBase { Ntrip = 0, SurveyIn = 1, Manual = 2 } public class MetodoFixacaoItem { public MetodoFixacaoBase Valor { get; set; } public string Nome { get; set; } = string.Empty; } public class PreparacaoMapaBottomViewModel : INotifyPropertyChanged { public event PropertyChangedEventHandler? PropertyChanged; public event Action? CarregarMapaSolicitado; public event Action? FixarBaseSolicitado; public List MetodosFixacaoDisponiveis { get; } = new() { new MetodoFixacaoItem { Valor = MetodoFixacaoBase.Ntrip, Nome = "Utilizando NTRIP" }, new MetodoFixacaoItem { Valor = MetodoFixacaoBase.SurveyIn, Nome = "Modo Survey-In" }, new MetodoFixacaoItem { Valor = MetodoFixacaoBase.Manual, Nome = "Preenchimento manual" } }; private bool _fixacaoEmAndamento; public bool FixacaoEmAndamento { get => _fixacaoEmAndamento; set { if (_fixacaoEmAndamento != value) { _fixacaoEmAndamento = value; OnPropertyChanged(nameof(FixacaoEmAndamento)); OnPropertyChanged(nameof(PodeCarregarMapa)); OnPropertyChanged(nameof(PodeFixarBase)); OnPropertyChanged(nameof(PodeEditarMetodoFixacao)); OnPropertyChanged(nameof(PodeEditarCoordenadasManuais)); } } } public bool PodeCarregarMapa => !FixacaoEmAndamento; public bool PodeEditarMetodoFixacao => !FixacaoEmAndamento; public bool PodeEditarCoordenadasManuais => !FixacaoEmAndamento && MetodoFixacaoSelecionado == MetodoFixacaoBase.Manual; public bool PodeFixarBase { get { if (FixacaoEmAndamento) return true; // permite "Parar" if (MetodoFixacaoSelecionado != MetodoFixacaoBase.Manual) return true; return LatitudeManual.HasValue && LongitudeManual.HasValue && AltitudeManual.HasValue; } } private MetodoFixacaoBase _metodoFixacaoSelecionado = MetodoFixacaoBase.Ntrip; public MetodoFixacaoBase MetodoFixacaoSelecionado { get => _metodoFixacaoSelecionado; set { if (_metodoFixacaoSelecionado != value) { _metodoFixacaoSelecionado = value; OnPropertyChanged(nameof(MetodoFixacaoSelecionado)); OnPropertyChanged(nameof(ExibirCamposManuais)); OnPropertyChanged(nameof(ExibirStatusNormal)); OnPropertyChanged(nameof(ExibirProgresso)); OnPropertyChanged(nameof(PodeEditarCoordenadasManuais)); OnPropertyChanged(nameof(PodeFixarBase)); OnPropertyChanged(nameof(TextoBotaoFixarBase)); if (!FixacaoEmAndamento) { StatusTexto = _metodoFixacaoSelecionado switch { MetodoFixacaoBase.Ntrip => "Método selecionado: NTRIP. A base será fixada via correção RTK pela rede.", MetodoFixacaoBase.SurveyIn => "Método selecionado: Survey-In. A base calculará sua posição média localmente.", MetodoFixacaoBase.Manual => "Método selecionado: Manual. Informe latitude, longitude e altitude conhecidas da base.", _ => "Pronto para fixar a posição da base." }; } } } } public bool ExibirCamposManuais => MetodoFixacaoSelecionado == MetodoFixacaoBase.Manual; public bool ExibirStatusNormal => MetodoFixacaoSelecionado != MetodoFixacaoBase.Manual; public bool ExibirProgresso => MetodoFixacaoSelecionado != MetodoFixacaoBase.Manual; private double? _latitudeManual; public double? LatitudeManual { get => _latitudeManual; private set { if (_latitudeManual != value) { _latitudeManual = value; OnPropertyChanged(nameof(LatitudeManual)); OnPropertyChanged(nameof(PodeFixarBase)); } } } private double? _longitudeManual; public double? LongitudeManual { get => _longitudeManual; private set { if (_longitudeManual != value) { _longitudeManual = value; OnPropertyChanged(nameof(LongitudeManual)); OnPropertyChanged(nameof(PodeFixarBase)); } } } private double? _altitudeManual; public double? AltitudeManual { get => _altitudeManual; private set { if (_altitudeManual != value) { _altitudeManual = value; OnPropertyChanged(nameof(AltitudeManual)); OnPropertyChanged(nameof(PodeFixarBase)); } } } private string _latitudeManualTexto = string.Empty; public string LatitudeManualTexto { get => _latitudeManualTexto; set { if (_latitudeManualTexto != value) { _latitudeManualTexto = value; LatitudeManual = TryParseDouble(value); OnPropertyChanged(nameof(LatitudeManualTexto)); OnPropertyChanged(nameof(PodeFixarBase)); } } } private string _longitudeManualTexto = string.Empty; public string LongitudeManualTexto { get => _longitudeManualTexto; set { if (_longitudeManualTexto != value) { _longitudeManualTexto = value; LongitudeManual = TryParseDouble(value); OnPropertyChanged(nameof(LongitudeManualTexto)); OnPropertyChanged(nameof(PodeFixarBase)); } } } private string _altitudeManualTexto = string.Empty; public string AltitudeManualTexto { get => _altitudeManualTexto; set { if (_altitudeManualTexto != value) { _altitudeManualTexto = value; AltitudeManual = TryParseDouble(value); OnPropertyChanged(nameof(AltitudeManualTexto)); OnPropertyChanged(nameof(PodeFixarBase)); } } } private double _progressoFixacao; public double ProgressoFixacao { get => _progressoFixacao; set { if (Math.Abs(_progressoFixacao - value) > 0.001) { _progressoFixacao = value; OnPropertyChanged(nameof(ProgressoFixacao)); OnPropertyChanged(nameof(ProgressoFixacaoTexto)); } } } public string ProgressoFixacaoTexto => $"{ProgressoFixacao:F0}%"; private string _statusTexto = "Pronto para carregar o mapa e fixar a base."; public string StatusTexto { get => _statusTexto; set { if (_statusTexto != value) { _statusTexto = value; OnPropertyChanged(nameof(StatusTexto)); } } } public string TextoBotaoFixarBase { get { if (FixacaoEmAndamento) return "Parar"; return MetodoFixacaoSelecionado == MetodoFixacaoBase.Manual ? "Aplicar posição manual" : "Fixar posição da base"; } } public ICommand CarregarMapaCommand { get; } public ICommand FixarBaseCommand { get; } public PreparacaoMapaBottomViewModel() { CarregarMapaCommand = new RelayCommand(_ => ExecutarCarregarMapa(), _ => PodeCarregarMapa); FixarBaseCommand = new RelayCommand(_ => ExecutarFixarBase(), _ => PodeFixarBase); } private void ExecutarCarregarMapa() { var dlg = new OpenFileDialog { Filter = "Arquivos de mapa|*.geojson;*.json;*.shp", Title = "Selecione o arquivo de mapa" }; if (dlg.ShowDialog() == DialogResult.OK) { StatusTexto = $"Mapa selecionado: {System.IO.Path.GetFileName(dlg.FileName)}"; CarregarMapaSolicitado?.Invoke(dlg.FileName); } } private void ExecutarFixarBase() { if (FixacaoEmAndamento) { FixarBaseSolicitado?.Invoke( MetodoFixacaoSelecionado, LatitudeManual, LongitudeManual, AltitudeManual); return; } if (MetodoFixacaoSelecionado == MetodoFixacaoBase.Manual) { if (!LatitudeManual.HasValue || !LongitudeManual.HasValue || !AltitudeManual.HasValue) { System.Windows.MessageBox.Show( "Preencha latitude, longitude e altitude para aplicar a posição manual da base.", "Dados incompletos", MessageBoxButton.OK, MessageBoxImage.Warning); return; } StatusTexto = "Pronto para aplicar a posição manual da base."; } FixarBaseSolicitado?.Invoke( MetodoFixacaoSelecionado, LatitudeManual, LongitudeManual, AltitudeManual); } public void AtualizarProgresso(double progresso, string status) { ProgressoFixacao = progresso; StatusTexto = status; } public void IniciarFixacao() { FixacaoEmAndamento = true; OnPropertyChanged(nameof(TextoBotaoFixarBase)); ProgressoFixacao = 0; StatusTexto = MetodoFixacaoSelecionado switch { MetodoFixacaoBase.Ntrip => "Iniciando fixação da base via NTRIP...", MetodoFixacaoBase.SurveyIn => "Iniciando Survey-In da base...", MetodoFixacaoBase.Manual => "Aplicando posição manual da base...", _ => "Iniciando fixação da posição da base..." }; } public void FinalizarFixacao(bool sucesso, string? mensagem = null) { FixacaoEmAndamento = false; OnPropertyChanged(nameof(TextoBotaoFixarBase)); if (MetodoFixacaoSelecionado != MetodoFixacaoBase.Manual) ProgressoFixacao = sucesso ? 100 : ProgressoFixacao; if (!string.IsNullOrWhiteSpace(mensagem)) { StatusTexto = mensagem; } else { StatusTexto = sucesso ? "Fixação da base concluída com sucesso." : "Fixação da base encerrada."; } } public void CancelarFixacao(string? mensagem = null) { FixacaoEmAndamento = false; OnPropertyChanged(nameof(TextoBotaoFixarBase)); StatusTexto = mensagem ?? "Fixação da base cancelada."; } public void LimparCamposManuais() { LatitudeManualTexto = string.Empty; LongitudeManualTexto = string.Empty; AltitudeManualTexto = string.Empty; LatitudeManual = null; LongitudeManual = null; AltitudeManual = null; } private double? TryParseDouble(string? texto) { if (string.IsNullOrWhiteSpace(texto)) return null; texto = texto.Trim().Replace(",", "."); if (double.TryParse( texto, NumberStyles.Any, CultureInfo.InvariantCulture, out var valor)) { return valor; } return null; } private void OnPropertyChanged(string nome) { PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nome)); CommandManager.InvalidateRequerySuggested(); } } }