using OperationControl.Mapas.Models;
namespace OperationControl.Mapas
{
///
/// Representa o contexto de trabalho atual do módulo de mapas.
///
/// Centraliza o mapa carregado e o estado operacional associado
/// a ele, sem depender de Mapsui, WPF ou qualquer tela.
///
public sealed class MapaWorkspace
{
///
/// Cópia canônica e imutável, por convenção,
/// do mapa no instante em que ele entrou
/// no subsistema.
///
/// Não é alterado por Apply, edição,
/// Undo/Redo ou alterações operacionais.
///
public MapaDocumento? DocumentoFonte { get; private set; }
public MapaDocumento? Documento { get; private set; }
public MapaSelecaoOperacao Selecao { get; private set; } = new();
public MapaRotaRetorno RotaRetorno { get; private set; } = new();
public bool PossuiDocumentoFonte => DocumentoFonte != null && DocumentoFonte.PossuiRuas;
public int QuantidadeRuasFonte => DocumentoFonte?.QuantidadeRuas ?? 0;
public bool PossuiMapa => Documento != null && Documento.PossuiRuas;
public bool PossuiSelecao => Selecao.PossuiSelecao;
public int QuantidadeRuas => Documento?.QuantidadeRuas ?? 0;
public int QuantidadeSelecionadas => Selecao.Quantidade;
///
/// Define um mapa completamente novo.
///
/// Fonte e documento ativo DEVEM ser
/// cópias independentes.
///
public void DefinirNovoDocumento(MapaDocumento documentoFonte, MapaDocumento documentoAtivo)
{
DefinirNovoEstado(
documentoFonte,
documentoAtivo,
new MapaSelecaoOperacao(),
new MapaRotaRetorno()
);
}
public void DefinirNovoEstado(MapaDocumento documentoFonte, MapaDocumento documentoAtivo, MapaSelecaoOperacao selecao, MapaRotaRetorno rotaRetorno)
{
if (documentoFonte == null)
{
throw new ArgumentNullException(
nameof(documentoFonte)
);
}
if (documentoAtivo == null)
{
throw new ArgumentNullException(
nameof(documentoAtivo)
);
}
/*
* Essa igualdade seria um bug arquitetural:
*
* editar Documento significaria editar
* também nosso backup.
*/
if (
ReferenceEquals(
documentoFonte,
documentoAtivo
)
)
{
throw new InvalidOperationException(
"DocumentoFonte e Documento ativo " +
"devem ser instâncias independentes."
);
}
DocumentoFonte =
documentoFonte;
DefinirEstado(
documentoAtivo,
selecao,
rotaRetorno
);
}
///
/// Substitui somente o documento oficial ativo.
///
/// DocumentoFonte não é alterado.
///
/// Útil para fluxos que já possuem uma fonte
/// previamente registrada.
///
public void DefinirDocumento(MapaDocumento documento)
{
DefinirEstado(
documento,
new MapaSelecaoOperacao(),
new MapaRotaRetorno()
);
}
///
/// Remove o mapa atualmente carregado
/// e todo o estado operacional associado.
///
public void Limpar()
{
DocumentoFonte = null;
Documento = null;
Selecao = new MapaSelecaoOperacao();
RotaRetorno = new MapaRotaRetorno();
}
public void DefinirEstado(MapaDocumento documento, MapaSelecaoOperacao selecao, MapaRotaRetorno rotaRetorno)
{
Documento =
documento
?? throw new ArgumentNullException(
nameof(documento)
);
Selecao =
selecao
?? throw new ArgumentNullException(
nameof(selecao)
);
RotaRetorno =
rotaRetorno
?? throw new ArgumentNullException(
nameof(rotaRetorno)
);
}
}
}