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
        
    //Metodos
    /**
     * Define o construtor de um mapa. Ele cria um mapa vazio.
     * Entrada: Nada
     * Saida: Nada
     */    

    public DesenhadorImpl(){
	 arestas = 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() );
    }

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

	arestas = 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() );
    }

    /**
     * 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.
	// *** TO DO ***
    }
    
    /**
     * 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.
	// *** TO DO ***
    }
    /**
     * 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;
	for (i = 0; i <= arestas.size(); i++)
	    {
		((Aresta)arestas.get(i)).multInicial(fator);
		((Aresta)arestas.get(i)).multFinal(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 <= arestas.size(); i++)
	    {
		tempvertice = ((Aresta)arestas.get(i)).getVerticeInicial();
		if (tempvertice.getX() > maiorX) maiorX = tempvertice.getX();
		if (tempvertice.getY() > maiorY) maiorY = tempvertice.getY();
		tempvertice = ((Aresta)arestas.get(i)).getVerticeFinal();
		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 <= arestas.size(); i++)
	    {
		// tempvertice = (Vertice)vertices.get(i);
		for (j = 0; j < viradas; j++);
		{
		    maiorX = ((Aresta)arestas.get(i)).getVerticeInicial().getX();
		    maiorY = ((Aresta)arestas.get(i)).getVerticeInicial().getY(); 
		    // variaveis temporarias.
		    // mudanca de quadrante.
		    ((Aresta)arestas.get(i)).setInicialX(maiorY);
		    ((Aresta)arestas.get(i)).setInicialY((centroX*2) - maiorX);
		}
		for (j = 0; j < viradas; j++);
		{
		    maiorX = ((Aresta)arestas.get(i)).getVerticeFinal().getX();
		    maiorY = ((Aresta)arestas.get(i)).getVerticeFinal().getY(); 
		    // variaveis temporarias.
		    // mudanca de quadrante.
		    ((Aresta)arestas.get(i)).setFinalX(maiorY);
		    ((Aresta)arestas.get(i)).setFinalY((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.length;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.length;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.length;i++){
 
            tempAresta = new Aresta((Trecho)trechos[i]);
 
            arestas.add( tempAresta );
        }    
        return arestas;
 
    }//fim de trecho2Aresta 
    /*
    public Vector  getVertices(Vector arestas ){
 
        Aresta tempAresta;
	Vertice tempVertice, compVertice ;
        Vector vertices;
	int xtemp, ytemp, j;
	boolean dontexist;
	
        for(int i=0;i<arestas.size();i++){
            dontexist = true;
	    j = 0;
	    tempAresta = (Aresta)arestas.get(i);
	    
	    xtemp = ((Vertice)tempAresta.getVerticeInicial()).getX();
	    ytemp = ((Vertice)tempAresta.getVerticeInicial()).getY();
	    tempVertice = new Vertice(xtemp, ytemp);
            while(((dontexist))&&(j<vertices.size()))
		{
		    compVertice = (Vertice)vertices.get(j);
		    dontexist = 
			(((compVertice.getX()!=tempVertice.getX())||
			  (compVertice.getY()!=tempVertice.getY()))&&
			 dontexist);
		    j++;
		}
	    if (dontexist) vertices.add(tempVertice);
	    
	    dontexist = true;
	    j = 0;
	    xtemp = ((Vertice)tempAresta.getVerticeFinal()).getX();
	    ytemp = ((Vertice)tempAresta.getVerticeFinal()).getY();
	    tempVertice = new Vertice(xtemp, ytemp);
	    while(((dontexist))&&(j<vertices.size()))
		{
		    compVertice = (Vertice)vertices.get(j);
		    dontexist = 
			(((compVertice.getX()!=tempVertice.getX())||
			  (compVertice.getY()!=tempVertice.getY()))&&
			 dontexist);
		    j++;
		}
	    if (dontexist) vertices.add(tempVertice);
	}
        return vertices;
    }//fim de getVertices
    */
}// Fim de Desenhador








