package pckMapa;

import java.util.*;

/**
 * Mapa
 *    Representa um conjunto de trechos e conexões que definem
 * um mapa.
 * @author Fernando de Almeida Galdino RA 970705   
 */
public class Mapa {

  private Vector vTrecho = new Vector();
  public Vector vConexao = new Vector();
  private String nomeArquivo = "";
  
  /**
   * para, ao criar um mapa, indicar o nome do arquivo
   */
  public Mapa(String nomeArquivo) {
    setNomeArquivo (nomeArquivo);
  }

  /**
   * Seta o nome do arquivo para carregar o mapa.
   * Ao nome do arquivo será adicionado .trechos e 
   * .esquinas no momento da carga.
   */
  public void setNomeArquivo(String val) {
    nomeArquivo = val;
  }

  /**
   * Dado um trecho t, possibilidades(t) devolve todos os trechos para onde
   * pode-se ir a partir de t.
   * Para determinar possibilidades(t) considera-se:
   * * todos os trechos que passam pelo pontoFinal de t menos o próprio trecho
   * * retorna-se então todos os trechos onde o pontoFinal de t = pontoInicial
   *   dos demais trechos. 
   */
  public Trecho[] possibilidades( Trecho t ) {
    // PRESERVE:BEGIN
    // Insert your preservable code here...
    Trecho tt = procurarTrecho( t.getId() );
    if (tt != null && tt.getFim() != null) {
         return tt.getInicio().getTrechos();
    }
    return null;
    // PRESERVE:END
  }
  
  public Trecho[] possibilidades( int t) {
    return possibilidades( procurarTrecho(t) );
  }

  /**
   * pode(t1, t2)
   *   Verifica se é permitido ir do trecho t1 para o
   * trecho t2.
   */
  public boolean pode(Trecho t1, Trecho t2) {
    Trecho t[] = possibilidades(t1);
    for (int i=0; i < t.length; i++)
      if (t[i] == t2) 
        return true;
    return false;
  }
  
  /**
   * pode(t1, t2)
   *   Verifica se é permitido ir do trecho t1 para o
   * trecho t2, considerando-se os id´s dos trechos.
   */
  public boolean pode(int t1, int t2) {
    Trecho tt1 = procurarTrecho(t1);
    Trecho tt2 = procurarTrecho(t2);
    return pode(tt1, tt2);
  }
  
  
  /**
   * Devolve o trecho correspondente ao id indicado.
   */
  public Trecho procurarTrecho(int id) {
    for (int i = 0; i< vTrecho.size(); i++) {
      Trecho t2 = (Trecho) vTrecho.elementAt( i );
      if (t2.getId() == id) {
        return t2;
      }
    }
    return null;
  }

  /**
   * Verifica se um trecho identificado por id já
   * existe no mapa. Se existir, devolve esse Trecho.
   * Caso contrário, cria um novo trecho.
   */
  private Trecho criarTrecho(int id) {
    Trecho t = procurarTrecho(id);
    if (t == null) {
      t = new Trecho();
      t.setId( id );
      vTrecho.addElement( t );
    }
    return t;
  }
  
  /**
   *   Verifica se um ponto (x, y) ja existe. Se
   * existir, devolve esse ponto. Caso contrario,
   * retorna null.
   */
  private Conexao procurarPonto(double x, double y) {
    for (int i = 0; i< vConexao.size(); i++) {
      Conexao p2 = (Conexao) vConexao.elementAt( i );
      if (p2.getPonto().getX() == x && p2.getPonto().getY() == y) {
        return p2;
      }
    }
    return null;
  }

  /**
   * Verifica se o ponto (x, y) ja existe. Se existir,
   * devolve esse Conexao. Senao cria um novo objeto Conexao.
   */
  private Conexao criarPonto(double x, double y) {
    Conexao p = procurarPonto(x, y);
    if (p==null) {
      p = new Conexao(x, y);
      vConexao.addElement( p );
    }
    return (p);
  }

  /**
   * A partir do nome do arquivo indicado, carrega os
   * trechos e conexoes existentes.
   * @author Fernando Galdino
   *         Arthur
   *         Andre
   */
  public void carregarMapa() {
    // PRESERVE:BEGIN
    // Insert your preservable code here...
    try {
      Vector vt = (new LeitorArquivo()).mtObtemDadosArquivo(nomeArquivo + ".trechos");
      for (int x = 0; x < vt.size(); x++) {
        RecordT rd = (RecordT)vt.elementAt(x);
        Trecho t1 = criarTrecho( Integer.parseInt(rd.getCampo1().trim()) );
      }
    } catch (Exception e) {
      e.printStackTrace();
    }

      PegaEsquinas.nomeArquivo = nomeArquivo + ".esquinas";
      PegaEsquinas pEsquina =  new PegaEsquinas();

      Vector vetorEsquinas = pEsquina.vetorEsquinas;
      System.out.println(vetorEsquinas.size());
      for (int i=0;i < vetorEsquinas.size();i++){
        Esquina esquina = (Esquina)vetorEsquinas.elementAt(i);
        Conexao p = criarPonto( esquina.getPosicaoX(), esquina.getPosicaoY() );
        Vector saem = new Vector();
        saem = esquina.getTrechosSaem();
        for (int j=0; j < saem.size(); j++) {
          Integer trechoSae = (Integer)saem.elementAt(j);
          Trecho t = criarTrecho( trechoSae.intValue() );
          p.adicionarTrecho( t, false );
        }
        Vector entram = new Vector();
        entram = esquina.getTrechoChegam();
        for (int j=0; j < entram.size(); j++) {
          Integer trechoEnt = (Integer)entram.elementAt(j);
          Trecho t = criarTrecho( trechoEnt.intValue() );
          p.adicionarTrecho( t, true );
        }
      }
    // PRESERVE:END
  }

  /**
   * Devolve todos os trechos armazenados em Mapa
   * como um vetor de trechos.
   */
  public Trecho[] getTrechos() {
    Trecho t[] = new Trecho[ vTrecho.size() ];
    vTrecho.copyInto( t );
    return t;
  }

  /**
   * Retorna um trecho de id indicado.
   */
  public Trecho getTrecho(int id) {
    return procurarTrecho( id );
  }

  /**
   * Devolve todas as conexões armazenados em Mapa
   * como um vetor de conexões.
   */
  public Conexao[] getConexoes() {
    Conexao p[] = new Conexao[ vConexao.size() ];
    vConexao.copyInto( p );
    return p;
  }

  /**
   * Para testar a classe.
   */
  public static void main(String args[]) {
    Mapa m = new Mapa( (args.length >= 1) ? args[0] : "unicamp" );
    System.out.println( "Inicio" );
    m.carregarMapa();
    Trecho t[] = m.possibilidades( 345 );
    if (t != null) {
      System.out.print( "Possibilidades: " );
      for (int i=0; i < t.length; i++)
        System.out.println( t[i].getId() );
    }
    System.out.println( "Fim" );
  }

}
