// Last edited on 2001-05-15 23:15:55 by mc726 // Mantém o estado lógico da aplicacao, e provê os comandos do usuário. import java.lang.Math; import java.awt.Graphics; import java.awt.Rectangle; import java.awt.Color; import java.io.FileWriter; import java.io.IOException; import Planta; import Trecho; import Servico; import Nodo; import Retangulo; import Ponto; import Escala; import EscalaImpl; import Gravura; import GravuraImpl; import Planta; import PlantaImpl; import Desenhador; import Otimizador; import OtimizadorImpl; import Localizador; import LocalizadorImpl; import InterfaceGrafica; public class EngenhoImpl extends Engenho { // A planta da cidade: private Planta _planta; // Um localizador para esta planta: private Localizador _loc = null; // Estado global da interface: private int _modo; private Logradouro[] _logradouros = null; // Logradouros selecionados pelo usuario private Elemento[] _selecoes = null; // Elementos selecionados pelo usuario private int maxSel = 0; // Max objs selecionado simultaneamente private Nodo[] _caminhos = null; // Caminho(s) encontrado (ou null) private TipoDeServico _tipoDesejado; // Tipo de servico desejado/encontrado. private double _custoMaximo; // Custo máximo especificado/encontrado. private int _numDesejado; // Numero máximo desejado de servicos. // Modos de operação: final static public int MODO_INICIAL = 0; // Estado inicial da interface final static public int MODO_MELHOR_CAMINHO = 1; // Busca de melhor caminho ativada final static public int MODO_ENUM_SERVICOS = 2; // Busca de servicos ativada final static public int MAX_MODO = MODO_ENUM_SERVICOS; // Max valor do modo // Modulos utilitarios: private Otimizador otimizador; private Desenhador desenhador = new DesenhadorImpl(); // A interface gráfica: private InterfaceGrafica raiz; // Cor do fundo do mapa: Color corFundoMapa = new Color(255, 245, 240); public EngenhoImpl(Planta pl, InterfaceGrafica z) // Inicializa a aplicação { this._planta = pl; this.otimizador = new OtimizadorImpl(this._planta); this.raiz = z; mudaModo(MODO_INICIAL); } ////////////////////////////////////////////////////////////////////// // Rotinas que interrogam o estado do engenho: // public int modo() { return _modo; } public Planta planta() { return _planta; } public Logradouro[] logradouros() { return _logradouros; } public Elemento[] selecoes() { return _selecoes; } public Nodo[] caminhos() { return _caminhos; } public TipoDeServico tipoDesejado() { return _tipoDesejado; } public double custoMaximo() { return _custoMaximo; } public int numDesejado() { return _numDesejado; } public Localizador loc() { if (_loc == null) { _loc = new LocalizadorImpl(_planta); } return _loc; } ////////////////////////////////////////////////////////////////////// // Rotinas que modificam o estado do engenho e // notificam a interface gráfica: // public void mudaModo(int md) { if ((md >= 0) && (md < MAX_MODO)) { _modo = md; } else { throw new Error("mudaModo: modo invalido"); } mudaCaminho(null); mudaSelecoes(null); switch ( _modo ) { case MODO_INICIAL : raiz.mensagem("Modo INICIAL"); maxSel = 0; break; case MODO_MELHOR_CAMINHO : raiz.mensagem("Modo MELHOR_CAMINHO"); maxSel = 2; break; case MODO_ENUM_SERVICOS : raiz.mensagem("Modo MODO_ENUM_SERVICOS"); maxSel = 1; break; } raiz.avisoMudouModo(_modo); } public void cutucaElemento(Elemento ob) { raiz.mensagem("Elemento cutucado: " + ob.toString()); switch ( _modo ) { case MODO_INICIAL : raiz.mensagem("Evento ignorado"); break; case MODO_MELHOR_CAMINHO : selecionaElementoParaMelhorCaminho(ob); break; case MODO_ENUM_SERVICOS : selecionaElementoParaEnumServicos(ob); break; } } public void mudaTipoDesejado(String tipo) { raiz.mensagem("Tipo de servico = " + tipo); _tipoDesejado = achaTipoDeServico(tipo); if (tipoDesejado() == null) { raiz.mensagem("O tipo de servico \"" + tipo + "\" não existe."); } enumeraServicosPorTipoECusto(); } public void mudaCustoMaximo(double cMax) { raiz.mensagem("Custo maximo = " + cMax); _custoMaximo = cMax; enumeraServicosPorTipoECusto(); } public void mudaNumeroDesejado(int num) { raiz.mensagem("Numero desejado = " + num); _numDesejado = num; enumeraServicosPorTipoECusto(); } // Imprime o mapa (restrito ao foco) e o caminho destacado: // public void imprimeMapa(String nome, Retangulo mR) { String fileName = nome + ".ps"; raiz.mensagem("imprimeMapa nao implementado"); } public void desenhaMapa(Gravura g, Retangulo mR) { // Pinta fundo do mapa e define janela de corte: g.mudaCorDoPincel(corFundoMapa); g.mudaCorDaPena(null); g.retangulo(mR); g.mudaLimites(mR); // Desenha a planta: Trecho[] T = loc().todosTrechosDentro(mR); Esquina[] Q = loc().todasEsquinasDentro(mR); Servico[] S = loc().todosServicosDentro(mR); Logradouro[] log = logradouros(); Elemento[] sel = selecoes(); Nodo[] cam = caminhos(); desenhador.desenhaMapa(g, T, Q, S, log, sel, cam); } ////////////////////////////////////////////////////////////////////// // MÉTODOS INTERNOS // Seleciona mais um argumento (Trecho, Servico, ...) // para o otimizador de caminhos, e invoca este // se houver argumentos suficientes: // private void selecionaElementoParaMelhorCaminho(Elemento ob) { mudaCaminho(null); selecionaElemento(ob); calculaCaminhoOtimo(); } // Invoca o otimizador de caminhos, se houver condicoes: // private void calculaCaminhoOtimo() { Elemento[] sel = selecoes(); if ((sel == null) || (sel.length == 0)) { raiz.mensagem("Selecione o local de partida."); } else if (sel.length == 1) { raiz.mensagem("Selecione o local de destino."); } else { Elemento orig = sel[sel.length-2]; Elemento dest = sel[sel.length-1]; raiz.mensagem("Procurando caminho otimo..."); Nodo[] cam = new Nodo[1]; cam[0] = otimizador.melhorCaminho(orig, dest); mudaCaminho(cam); mudaSelecoes(null); } } // Seleciona um argumento (Trecho, Servico, ...) // para o enumerador de servicos, e invoca este último: // private void selecionaElementoParaEnumServicos(Elemento ob) { mudaCaminho(null); selecionaElemento(ob); enumeraServicosPorTipoECusto(); } private void enumeraServicosPorTipoECusto() { if (modo() != MODO_ENUM_SERVICOS) { mudaModo(MODO_ENUM_SERVICOS); } Elemento[] sel = selecoes(); if (tipoDesejado() == null) { raiz.mensagem("Especifique um tipo de servico"); } else if (custoMaximo() < 0) { raiz.mensagem("Especifique um custo máximo não negativo"); } else if (numDesejado() <= 0) { raiz.mensagem("Especifique um numero positivo de respostas"); } else if ((sel == null) || (sel.length < 1)) { raiz.mensagem("Selecione o ponto de referência."); } else { raiz.mensagem("Enumerando serviços requisitados..."); Elemento orig = sel[sel.length-1]; TipoDeServico tipo = tipoDesejado(); double cMax = custoMaximo(); int nMax = numDesejado(); Nodo[] cam = otimizador.enumServicos(orig, tipo, cMax, nMax); mudaCaminho(cam); mudaSelecoes(null); } } // Acrescenta o trecho à fila de trechos selecionados, // jogando fora o mais antigo se houver excesso: // private void selecionaElemento(Elemento ob) { if (ob != null) { Elemento[] sel = selecoes(); int nSel = (sel == null ? 0 : sel.length); int nCop = (nSel < maxSel ? nSel : maxSel); Elemento[] selNovas = new Elemento[nCop + 1]; for (int k=0; k