package pckDesenho;


import java.util.*;
import pckPlano.*;
import pckMapa.*;

/**
 * Titulo: Desenhador
 * Descricao: A classe Desenhador eh a classe principal que chama todas as
 *            funcoes publicas de Desenho. Ela eh composta por um
 *            conjunto de vertices e as arestas que os ligam contem
 *            metodos para desenho de mapa e rotas.
 * @author GRUPO-A
 * @version 0.2
 */

public class DesenhadorImpl{

    private static final int numero_arestas = 512;  //Numero maximo de arestas
    private Vector arestas;  //Arestas
    private Vector vertices; //Vertices
    
    //Metodos
    /**
     * Define o construtor de um mapa. Ele cria um mapa vazio.
     * Entrada: Nada
     * Saida: Nada
     */    

    public DesenhadorImpl(){
	 arestas = new Vector(numero_arestas);
	 vertices = new Vector(numero_arestas);
    }

    /**
     * Cria um mapa retirando informacoes da representacao de mapa.
     * Entrada: Requer uma representacao de mapa com arestas acessiveis
     *          com pontos iniciais e finais tambem acessiveis.
     * Saida: Nada
     */
    public DesenhadorImpl(Mapa mapa){
	arestas =  trecho2Aresta( mapa.getTrechos() );
	vertices =   getVertices( arestas );
    }

    /**
     * Remove todas as informacoes de um mapa
     * Entrada: Nada
     * Saida: Nada
     */
    public void limparMapa(){

	arestas = null;
	vertices = null;

    } 


    /**
     * Carrega um mapa com as informacoes da representacao
     * Entrada: uma representacao de mapa com arestas acessiveis
     * Saida: Nada
     */
    
    public void carregarMapa(Mapa mapa){
    
	limparMapa();

	arestas =  trecho2Aresta( mapa.getTrechos() );
	vertices =   getVertices( arestas );
	

    }

    /**
     * Desenha o mapa na tela com as informacoes contidas
     * Entrada: Nada
     * Saida: Nada
     */
    public void desenharMapa(){
	// percorre todas as arestas descritas no mapa,
	// desenhando-as.
	Aresta temp;
	for(int i = 0; i < arestas.size(); i++){
	    temp = (Aresta)arestas.get(i);
	    temp.desenharAresta();
	}
    }
    
    /**
     * Apaga o mapa da tela, de forma a deixa-la limpa.
     * Entrada: Nada
     * Saida: Nada
     */
    public void apagarMapa(){
	// percorre todas as arestas descritas no mapa,
	// apagando-as.
	Aresta temp;
	for(int i = 0; i < arestas.size(); i++){
	    temp = (Aresta)arestas.get(i);
	    temp.apagarAresta();
	}
    }
    /**
     * Altera os atributos de desenho do mapa de forma que, da proxima vez 
     * que ele for desenhado, ele esteja maior ou menor, em proporcao ao
     * fator utilizado. Ou seja, para aproximar o mapa, e' necessario 
     * executar esta funcao, apagar e redesenhar o mapa.
     * Entrada: fator - um float que diz a proporcao do novo mapa em relacao
     *          ao atual.
     * Saida: nada.
     */
    public void aproximarMapa(float fator){
	// simplerrimo. Multiplica cada vertice individualmente
	int i;
	Vertice tempvertice;
	for (i = 0; i <= vertices.size(); i++)
	    {
		tempvertice = (Vertice)vertices.get(i);
		tempvertice.multiplicaCoordenada(fator);
	    }
    }

    /**
     * Altera os atributos de desenho do mapa de forma que, da proxima vez 
     * que ele for desenhado, ele esteja transposto em proporcao ao
     * fator utilizado. Ou seja, para girar o mapa, e' necessario 
     * executar esta funcao, apagar e redesenhar o mapa.
     * Entrada: viradas. A funcao gira o mapa 90 graus no sentido horario,
     *          e a entrada diz quantas vezes deve-se girar o mapa.
     * Saida: nada.
     */
    public void girarMapa(int viradas){
	int i, j, quadrante;
	Vertice tempvertice;
	int maiorX, maiorY; // armazenam as maiores coordenadas do mapa.
	int centroX, centroY; // armazenam o centro do mapa.
	viradas = viradas%4; // viradas deve ser 0, 1, 2, ou 3.
	maiorX = 0;
	maiorY = 0;
	for (i = 0; i <= vertices.size(); i++)
	    {
		tempvertice = (Vertice)vertices.get(i);
		if (tempvertice.getX() > maiorX) maiorX = tempvertice.getX();
		if (tempvertice.getY() > maiorY) maiorY = tempvertice.getY();
	    }
	centroY = maiorY/2;
	centroX = maiorX/2; // pode estar errado, e ser necessario
	// substituir por uma divisao inteira. CentroXY deve ser int.
	for (i = 0; i <= vertices.size(); i++)
	    {
		tempvertice = (Vertice)vertices.get(i);
		for (j = 0; j < viradas; j++);
		{
		    maiorX = tempvertice.getX();
		    maiorY = tempvertice.getY(); // variaveis temporarias.
		    // mudanca de quadrante.
		    tempvertice.setX(maiorY);
		    tempvertice.setY((centroX*2) - maiorX);
		}

	    }
    }
    /** 
     * Marca uma rota no mapa, mudando a cor das arestas pertencentes
     * aquela rota, de acordo com uma funcao do numero de rotas que 
     * passa por um dado trecho.
     * Entrada: rota - um objeto que contenha a informacao de todas 
     *          as arestas pertecentes aquela rota.
     * Saida: nada.
     */
     public void desenharRota(Rota rota){
	Passo passos[]=rota.passos();
	for (int i=0;i<passos.size();i++)
	    for (int j=0;j<arestas.size();j++)
		if (((Trecho)((Aresta)arestas.get(j)).getTrechoEquivalente()).id()==
		    ((Trecho)passos[i].trecho()).id()){
		    ((Aresta)arestas.get(j)).setCor(1);
		    break;
		}
    }

    /**
     * Desmarca uma rota no mapa, mudando a cor das arestas pertecentes
     * aquela rota, de acordo com uma funcao do numero de rotas que
     * passa por um dado trecho.
     * Entrada: rota - um objeto que contenha a informacao de todas
     *          as arestas pertecentes aquela rota.
     * Saida: nada.
     */
    public void apagarRota(Rota rota){
       Passo passos[]=rota.passos();
	for (int i=0;i<passos.size();i++)
	    for (int j=0;j<arestas.size();j++)
		if (((Trecho)((Aresta)arestas.get(j)).getTrechoEquivalente()).id()==
		    ((Trecho)passos[i].trecho()).id()){
		    ((Aresta)arestas.get(j)).setCor(-1);
		    break;
		}
   }
  
    public Vector  trecho2Aresta(Trecho[] trechos){
 
        Aresta tempAresta;
        Vector arestas;
 
        for(int i=0;i<trechos.size();i++){
 
            tempAresta = new Aresta((Trecho)trechos.get(i));
 
            arestas.add( tempAresta );
        }    
        return arestas;
 
    }//fim de trecho2Aresta 

    public Vector  getVertices(Vector arestas ){
 
        Aresta tempAresta;
 
        Vector vertices;
 
        for(int i=0;i<arestas.size();i++){
 
            tempAresta = (Aresta)arestas.get(i);
 
 
            vertices.add( new Vertice( arestas.getVerticeInicial(),
                                       arestas.getVerticeFinal())
                        );  

        }
        return vertices;
    }//fim de getVertices

}// Fim de Desenhador








