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) ); } } }