agrobot_base/AgroBase/OperationControl/ViewModels/Views/Operacao/Monitoramento/ParametrizacaoViewModel.cs

583 lines
15 KiB
C#

using AgroBase.Models;
using AgroBase.Models.Operacoes;
using OperationControl.Controls;
using OperationControl.Helpers;
using OperationControl.Models;
using System.ComponentModel;
using System.Windows.Input;
namespace OperationControl.ViewModels.Views.Operacao.Monitoramento
{
public class ParametrizacaoViewModel : INotifyPropertyChanged
{
private OperacaoParametrosModel _parametros = new OperacaoParametrosModel();
public OperacaoParametrosModel Parametros
{
get => _parametros;
set
{
if (_parametros != value)
{
_parametros = value;
AtualizarModoOperacaoAtual(
_parametros?.Modo
?? AgroBase.Models.Enums
.ModoOperacao.NaoDefinido
);
OnPropertyChanged(
nameof(Parametros)
);
}
}
}
private bool _operacaoConcluida;
public bool OperacaoConcluida
{
get => _operacaoConcluida;
set
{
_operacaoConcluida = value;
OnPropertyChanged(nameof(OperacaoConcluida));
}
}
private AgroBase.Models.Enums.ModoOperacao? modoOperacaoAtual { get; set; }
private int _quantidadeRuasMapa;
public int QuantidadeRuasMapa =>
_quantidadeRuasMapa;
private int _quantidadeRuasPercurso;
public int QuantidadeRuasPercurso =>
_quantidadeRuasPercurso;
private int _quantidadeRuasSelecionadasEdicao;
public int QuantidadeRuasSelecionadasEdicao =>
_quantidadeRuasSelecionadasEdicao;
private int _quantidadeCorredores;
public int QuantidadeCorredores
{
get => _quantidadeCorredores;
private set
{
if (
_quantidadeCorredores ==
value
)
{
return;
}
_quantidadeCorredores =
value;
OnPropertyChanged(
nameof(
QuantidadeCorredores
)
);
}
}
private double _distanciaOperacaoMetros;
public double DistanciaOperacaoMetros
{
get => _distanciaOperacaoMetros;
private set
{
if (
Math.Abs(
_distanciaOperacaoMetros -
value
) <
0.001
)
{
return;
}
_distanciaOperacaoMetros =
value;
OnPropertyChanged(
nameof(
DistanciaOperacaoMetros
)
);
}
}
private double _areaOperacaoHectares;
public double AreaOperacaoHectares
{
get => _areaOperacaoHectares;
private set
{
if (
Math.Abs(
_areaOperacaoHectares -
value
) <
0.000001
)
{
return;
}
_areaOperacaoHectares =
value;
OnPropertyChanged(
nameof(
AreaOperacaoHectares
)
);
}
}
private double _larguraMediaCorredorMetros;
public double LarguraMediaCorredorMetros
{
get => _larguraMediaCorredorMetros;
private set
{
if (
Math.Abs(
_larguraMediaCorredorMetros -
value
) <
0.001
)
{
return;
}
_larguraMediaCorredorMetros =
value;
OnPropertyChanged(
nameof(
LarguraMediaCorredorMetros
)
);
}
}
private double? _tempoEstimadoOperacaoSegundos;
public double? TempoEstimadoOperacaoSegundos
{
get => _tempoEstimadoOperacaoSegundos;
private set
{
_tempoEstimadoOperacaoSegundos =
value;
OnPropertyChanged(
nameof(
TempoEstimadoOperacaoSegundos
)
);
}
}
private bool _edicaoMapaAtiva;
public bool EdicaoMapaAtiva =>
_edicaoMapaAtiva;
private bool _edicaoMapaModificada;
public bool EdicaoMapaModificada =>
_edicaoMapaModificada;
public bool PossuiMapaOperacional =>
_quantidadeRuasMapa > 0;
public bool PodeEditarMapa =>
PossuiMapaOperacional &&
!EdicaoMapaAtiva;
public string MapaResumoTexto
{
get
{
if (!PossuiMapaOperacional)
{
return
"Nenhum mapa operacional carregado.";
}
return
$"{QuantidadeRuasMapa} ruas no mapa | " +
$"{QuantidadeRuasPercurso} no percurso";
}
}
public string EstadoEdicaoMapaTexto
{
get
{
if (!PossuiMapaOperacional)
{
return
"Carregue ou leia um mapa para editar.";
}
if (EdicaoMapaAtiva)
{
return EdicaoMapaModificada
? "Edição em andamento • alterações pendentes"
: "Edição em andamento";
}
return
"Pronto para edição.";
}
}
public string SelecaoEdicaoMapaTexto
{
get
{
if (
QuantidadeRuasSelecionadasEdicao ==
1
)
{
return
"1 rua selecionada para edição";
}
return
$"{QuantidadeRuasSelecionadasEdicao} " +
"ruas selecionadas para edição";
}
}
public bool PossuiEstimativaMapa => QuantidadeCorredores > 0 && DistanciaOperacaoMetros > 0;
public string MapaCorredoresTexto =>
QuantidadeCorredores switch
{
0 =>
"Selecione ao menos 2 ruas para formar um corredor.",
1 =>
$"1 corredor • largura média " +
$"{LarguraMediaCorredorMetros:0.00} m",
_ =>
$"{QuantidadeCorredores} corredores • largura média " +
$"{LarguraMediaCorredorMetros:0.00} m"
};
public string MapaDistanciaTexto => $"{DistanciaOperacaoMetros:N0} m";
public string MapaAreaTexto => $"{AreaOperacaoHectares:0.000} ha";
public string MapaTempoEstimadoTexto
{
get
{
if (
!TempoEstimadoOperacaoSegundos
.HasValue
)
{
return "--:--:--";
}
double segundos =
Math.Max(
0,
TempoEstimadoOperacaoSegundos
.Value
);
var duracao =
TimeSpan
.FromSeconds(
segundos
);
long horas =
(long)Math.Floor(
duracao.TotalHours
);
return string.Format(
"{0:00}:{1:00}:{2:00}",
horas,
duracao.Minutes,
duracao.Seconds
);
}
}
public ParametrizacaoViewModel()
{
CarregarParametrosPadraoCommand = new RelayCommand(p => CarregarParametrosPadrao((AgroBase.Models.Enums.ModoOperacao)p));
LerParametrosCommand = new RelayCommand(_ => LerParametrosSolicitado?.Invoke(), _ => !EdicaoMapaAtiva);
SalvarParametrosCommand =new RelayCommand(_ => SalvarParametrosSolicitado?.Invoke(Parametros), _ => !EdicaoMapaAtiva);
EditarMapaCommand = new RelayCommand(_ => EditarMapaSolicitado?.Invoke(), _ => PodeEditarMapa);
CancelarEdicaoMapaCommand = new RelayCommand(_ => CancelarEdicaoMapaSolicitado?.Invoke(), _ => EdicaoMapaAtiva);
ReiniciarOperacaoCommand = new RelayCommand(_ => ReiniciarOperacao());
}
public event Action? LerParametrosSolicitado;
public event Action<OperacaoParametrosModel>? SalvarParametrosSolicitado;
public event Action? EditarMapaSolicitado;
public event Action? CancelarEdicaoMapaSolicitado;
/// <summary>
/// Disparado quando o modo desejado da parametrização muda.
///
/// O Dock usa esse evento para recalcular o modo de
/// interação do mapa sem o MapViewControl conhecer
/// ParametrizacaoViewModel ou estado global da aplicação.
/// </summary>
public event Action<AgroBase.Models.Enums.ModoOperacao>? ModoOperacaoAlterado;
public ICommand LerParametrosCommand { get; }
public ICommand SalvarParametrosCommand { get; }
public ICommand CarregarParametrosPadraoCommand { get; }
public ICommand ReiniciarOperacaoCommand { get; }
public ICommand EditarMapaCommand { get; }
public ICommand CancelarEdicaoMapaCommand { get; }
public Array ModosOperacaoDisponiveis { get; } = Enum.GetValues(typeof(AgroBase.Models.Enums.ModoOperacao));
private void CarregarParametrosPadrao(AgroBase.Models.Enums.ModoOperacao modo)
{
var new_op = OperacaoModel.CarregarParametrosOperacaoPadrao(modo, false);
new_op.Parametros.Descricao = $"{new_op.Parametros.Modo} - Padrão";
Parametros = new_op.Parametros;
if (VariaveisControleOperacao.RoverEmFoco != null)
VariaveisControleOperacao.RoverEmFoco.Modo = modo;
}
private void AtualizarModoOperacaoAtual(AgroBase.Models.Enums.ModoOperacao modo)
{
if (
modoOperacaoAtual.HasValue &&
modoOperacaoAtual.Value == modo
)
{
return;
}
modoOperacaoAtual =
modo;
ModoOperacaoAlterado?
.Invoke(
modo
);
}
private void ReiniciarOperacao()
{
VariaveisControleOperacao.EnviarComandoIniciarOperacao(false, false);
Models.Variaveis.Dock?._vm?._viewOperacaoCenter?.Mapa?.LimparPontosSelecionados();
}
public void AtualizarParametros(OperacaoParametrosModel origem)
{
if (origem == null) return;
Parametros = origem;
OperacaoConcluida = (VariaveisControleOperacao.RoverEmFoco?.DadosLeitura?.Operacao?.Status ?? AgroBase.Models.Enums.StatusOperacao.NaoIniciado) == AgroBase.Models.Enums.StatusOperacao.Concluido;
}
public void AtualizarEstadoMapa(
int quantidadeRuas,
int quantidadeRuasPercurso,
bool edicaoAtiva,
int quantidadeSelecionadasEdicao,
bool edicaoModificada,
int quantidadeCorredores,
double distanciaOperacaoMetros,
double areaOperacaoHectares,
double larguraMediaCorredorMetros,
double? tempoEstimadoOperacaoSegundos)
{
_quantidadeRuasMapa =
Math.Max(
0,
quantidadeRuas
);
_quantidadeRuasPercurso =
Math.Max(
0,
quantidadeRuasPercurso
);
_edicaoMapaAtiva =
edicaoAtiva;
_quantidadeRuasSelecionadasEdicao =
Math.Max(
0,
quantidadeSelecionadasEdicao
);
_edicaoMapaModificada =
edicaoModificada;
QuantidadeCorredores =
quantidadeCorredores;
DistanciaOperacaoMetros =
distanciaOperacaoMetros;
AreaOperacaoHectares =
areaOperacaoHectares;
LarguraMediaCorredorMetros =
larguraMediaCorredorMetros;
TempoEstimadoOperacaoSegundos =
tempoEstimadoOperacaoSegundos;
OnPropertyChanged(
nameof(QuantidadeRuasMapa)
);
OnPropertyChanged(
nameof(QuantidadeRuasPercurso)
);
OnPropertyChanged(
nameof(QuantidadeRuasSelecionadasEdicao)
);
OnPropertyChanged(
nameof(EdicaoMapaAtiva)
);
OnPropertyChanged(
nameof(EdicaoMapaModificada)
);
OnPropertyChanged(
nameof(PossuiMapaOperacional)
);
OnPropertyChanged(
nameof(PodeEditarMapa)
);
OnPropertyChanged(
nameof(MapaResumoTexto)
);
OnPropertyChanged(
nameof(EstadoEdicaoMapaTexto)
);
OnPropertyChanged(
nameof(SelecaoEdicaoMapaTexto)
);
OnPropertyChanged(
nameof(
PossuiEstimativaMapa
)
);
OnPropertyChanged(
nameof(
MapaCorredoresTexto
)
);
OnPropertyChanged(
nameof(
MapaDistanciaTexto
)
);
OnPropertyChanged(
nameof(
MapaAreaTexto
)
);
OnPropertyChanged(
nameof(
MapaTempoEstimadoTexto
)
);
CommandManager
.InvalidateRequerySuggested();
}
public event PropertyChangedEventHandler PropertyChanged;
private void OnPropertyChanged(string nome)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nome));
}
}
}