package pckDesenho;

import pckInterface.*;
import java.awt.*;
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{
/**
 * Membros Responsaveis pelo modulo
 * Cleber Valgas Mira : 980866
 * Claus Aranha : 980863
 **/

    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(Gravura g ){
	// percorre todas as arestas descritas no mapa,
	// desenhando-as.
	// *** TO DO ***
	g.modoSET();
	desenhaArestas(g,arestas);
    }
    
    
    
    public void apagarMapa(Gravura g ){
	// percorre todas as arestas descritas no mapa,
	// desenhando-as.
	// *** TO DO ***
	g.modoSET();
	apagaArestas(g,arestas);
    }
    
    
    
    public void desenhaArestas(Gravura g, Vector arestas){
	
	// Desenha as vias com as cores e largura estabelecidas.
	
	
        for(int i=0; i < arestas.size(); i++) { 
	    
	    g.mudaCorDaPena(((Aresta)arestas.get(i)).getCor());    
            desenhaAresta(g, (Aresta)arestas.get(i)); 
	}
    }

    public void apagaArestas(Gravura g, Vector arestas){	
	// Desenha as vias com as cores e largura estabelecidas.
       
	    g.mudaCorDaPena(Color.white);
	
        for(int i=0; i < arestas.size(); i++) { 

            desenhaAresta(g, (Aresta)arestas.get(i)); 
	}
	

    }
   
    private static void desenhaAresta(Gravura g, Aresta arest){
	// Desenha a aresta "arest".
	/* int dPista = 2*rPista + 1; 
	   int rAresta = (arest.numeroDePistas() * dPista)/2;
	   g.mudaRaioDaPena( rAresta ); */
	g.linha((int)arest.getVerticeInicial().getX(),
		(int)arest.getVerticeInicial().getY(),
		(int)arest.getVerticeFinal().getX(),
		(int)arest.getVerticeFinal().getY());
    }

    /**
     * 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.
     *          cor - a cor que deve setar uma rota:
     *          preto, azul claro, azul, azul escuro, verde claro, verde, verde escuro,
     *          amarelo claro, amarelo, amarelo escuro, laranja claro, laranja, laranja escuro,
     *          vermelho claro, vermelho, vermelho escuro sao as cores validas.
     * Saida: nada.
     */
     public void pintarRota(Rota rota, String cor){
	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()).getId()==
		    ((Trecho)passos[i].trecho()).getId()){
		    ((Aresta)arestas.get(j)).setCor(cor);
		    break;
		}
    }
    
    /** 
     * Marca uma aresta no mapa, mudando sua cor.
     * Entrada: um trecho ou passo a ser colorido. 
     *          cor - a cor que deve setar uma rota:
     *          preto, azul claro, azul, azul escuro, verde claro, verde, verde escuro,
     *          amarelo claro, amarelo, amarelo escuro, laranja claro, laranja, laranja escuro,
     *          vermelho claro, vermelho, vermelho escuro sao as cores validas.
     * Saida: nada.
     */
    
    public void pintarAresta(Trecho trecho, String cor){
	for (int i=0; i<arestas.size();i++)
	    if (((Trecho)((Aresta)arestas.get(i)).getTrechoEquivalente()).getId()== trecho.getId()){
		((Aresta)arestas.get(i)).setCor(cor);
		break;
	    }
    }
     public void pintarAresta(Passo passo, String cor){
	for (int i=0; i<arestas.size();i++)
	    if (((Trecho)((Aresta)arestas.get(i)).getTrechoEquivalente()).getId()==
		((Trecho)passo.trecho()).getId()){
		((Aresta)arestas.get(i)).setCor(cor);
		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 
}// Fim de Desenhador








