
/**
 * ---------------------------------------------------------------------
 * $Id: Simulador.java,v 1.0 2013/08/23 
 * Universidad Francisco de Paula Santander 
 * Programa Ingenieria de Sistemas
 *
 * Proyecto: SEED_UFPS
 * ----------------------------------------------------------------------
 */

package simgrafond;

import Graficos.GrafoG;
import Mundo_GrafoND.SimuladorGrafoND;
import java.net.URL;
import java.util.ResourceBundle;
import javafx.animation.Timeline;
import javafx.event.EventHandler;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.Label;
import javafx.scene.control.TextField;
import javafx.scene.image.ImageView;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.Region;
import javafx.scene.paint.Color;
import javafx.scene.shape.Circle;
import javafx.scene.shape.Line;

/**
 * Clase controlador del Vista.FXML donde se crean y manipulan los componente javafx de la Aplicacion.
 * @author Uriel Garcia - Yulieth Pabon
 * @version 1.0
 */

public class Simulador implements Initializable {
    
    @FXML   private Line    linea0, linea1,linea2,linea3,linea4,linea5,linea6,linea7,linea8,linea9,linea10,
                            linea11,linea12,linea13,linea14,linea15,linea16,linea17,linea18,linea19,
                            linea20, linea21,linea22,linea23,linea24,linea25,linea26,linea27,linea28,linea29,
                            linea30, linea31,linea32,linea33,linea34,linea35,linea36,linea37,linea38,linea39,
                            linea40, linea41,linea42,linea43,linea44,linea45,linea46,linea47,linea48,linea49;

    @FXML   private Circle  raiz, nodo1,nodo2,nodo3,nodo4,nodo5,nodo6,nodo7,nodo8,nodo9,nodo10,nodo11,nodo12, nodo13,nodo14,nodo15, nodo16, nodo17, nodo18, nodo19,
                            nodo20, nodo21, nodo22, nodo23, nodo24, nodo25, nodo26, nodo27, nodo28, nodo29, nodo30, nodo31, nodo32, nodo33, nodo34, nodo35, nodo36, nodo37, nodo38, nodo39,
                            nodo40, nodo41, nodo42, nodo43, nodo44, nodo45, nodo46, nodo47, nodo48, nodo49, nodo50, nodo51, nodo52, nodo53, nodo54, nodo55, nodo56, nodo57, nodo58, nodo59,
                            nodo60, nodo61, nodo62, nodo63, nodo64, nodo65, nodo66, nodo67, nodo68, nodo69, nodo70, nodo71, nodo72, nodo73, nodo74, nodo75, nodo76, nodo77, nodo78, nodo79,
                            nodo80, nodo81, nodo82, nodo83, nodo84, nodo85, nodo86, nodo87, nodo88, nodo89, nodo90, nodo91, nodo92, nodo93, nodo94, nodo95, nodo96, nodo97, nodo98, nodo99, piv;
    @FXML   private Label   label0, label1,label2,label3,label4,label5,label6,label7,label8,label9,label10,label11,label12, label13,label14,label15, label16, label17, label18, label19,
                            label20, label21, label22, label23, label24, label25, label26, label27, label28, label29, label30, label31, label32, label33, label34, label35, label36, label37, label38, label39,
                            label40, label41, label42, label43, label44, label45, label46, label47, label48, label49, label50, label51, label52, label53, label54, label55, label56, label57, label58, label59,
                            label60, label61, label62, label63, label64, label65, label66, label67, label68, label69, label70, label71, label72, label73, label74, label75, label76, label77, label78, label79,
                            label80, label81, label82, label83, label84, label85, label86, label87, label88, label89, label90, label91, label92, label93, label94, label95, label96, label97, label98, label99, 
                            labelPiv, area;
   @FXML   private Label   labelp0, labelp1,labelp2,labelp3,labelp4,labelp5,labelp6,labelp7,labelp8,labelp9,labelp10,labelp11,labelp12, labelp13,labelp14,labelp15, labelp16, labelp17, labelp18, labelp19,
                            labelp20, labelp21, labelp22, labelp23, labelp24, labelp25, labelp26, labelp27, labelp28, labelp29, labelp30, labelp31, labelp32, labelp33, labelp34, labelp35, labelp36, labelp37, labelp38, labelp39,
                            labelp40, labelp41, labelp42, labelp43, labelp44, labelp45, labelp46, labelp47, labelp48, labelp49, labelp50, labelp51, labelp52, labelp53, labelp54, labelp55, labelp56, labelp57, labelp58, labelp59,
                            labelp60, labelp61, labelp62, labelp63, labelp64, labelp65, labelp66, labelp67, labelp68, labelp69, labelp70, labelp71, labelp72, labelp73, labelp74, labelp75, labelp76, labelp77, labelp78, labelp79,
                            labelp80, labelp81, labelp82, labelp83, labelp84, labelp85, labelp86, labelp87, labelp88, labelp89, labelp90, labelp91, labelp92, labelp93, labelp94, labelp95, labelp96, labelp97, labelp98, labelp99;
    @FXML   private     TextField   txtRuta, txtPeso;
    @FXML   private     ImageView   borde, borde2, borde3;
    @FXML   private     Label   nota,  msg;  
    @FXML   private     Region region;
    @FXML   private     Timeline    lineaTiempo = new Timeline(); 
    @FXML   private     double lx=0.0, ly=0.0;
    @FXML   private     int turno=-1;
    @FXML   private     SimuladorGrafoND    simulador;
    @FXML   private     Circle  nodos[];
    @FXML   private     Line    lineas[];
    @FXML   private     Label   labels[], pesos[];
    @FXML   private     GrafoG grafoG;
     
    
    @FXML
    private void btDibujar() {    
        region.setOnMouseClicked(new EventHandler<MouseEvent>() {
            @Override
            public void handle(MouseEvent t) {
                asignar(t.getSceneX(),t.getSceneY());
            }
        });
    }
    
    @FXML
    private void asignar(double lx, double ly) {    
        boolean rta = false;
        switch(turno){            
            //No hace Nada
            case -1:
            break;   
                
            //Insertar un nuevo Vertice
            case 0:
                if(!this.grafoG.puedeInsertar()){
                    this.impNota("El Simulador para Grafos no puede crear mas Vertices!", 1);
                    return;
                }
                char val = this.grafoG.insertarVertice(lx, ly);
                rta = this.simulador.insertarVertice(val);
                if(rta){
                    this.impNota("Vertice insertado correctamente!", 0);
                    this.pintarTDA();
                }
                else
                    this.impNota("Vertice no se puede insertar!", 1);
            break;
                
            //Asignar el primer vertice de la Arista
            case 1:                
                this.lx = lx;
                this.ly = ly;
                if(this.grafoG.pintarVertice(lx, ly)){
                    this.turno=2;
                    this.impNota("Vertice origen de la Arista seleccionado!", 0);
                }                    
                else
                    this.impNota("No se puede seleccionar el Vertice Origen!",1);
           break;            
            
            //Insertar una nueva Arista
            case 2:
                if(!this.grafoG.puedeInsertarA()){
                    this.impNota("El Simulador para Grafos no puede crear mas Aristas!", 1);
                    return;
                }
                String p = txtPeso.getText();
                if(p.isEmpty()){
                    this.impNota("Debe ingresar un peso para la Arista!", 1);
                    return;
                }
                if(!this.esNumero(p)){
                    this.impNota("El peso de la Arista debe ser un valor numerico!", 1);
                    return;
                }
                int peso = Integer.parseInt(p);
                if(peso<0 || peso>=1000){
                    this.impNota("El peso de la Arista no puede superar el rango permitido: 0 a 999", 1);
                    return;
                }
                txtPeso.setText("");
                if(this.grafoG.insertarArista(this.lx, this.ly, lx, ly, peso)){
                    this.turno=1;
                    String x = this.grafoG.getDatosArista(this.lx, this.ly, lx, ly);
                    rta=this.simulador.insertarArista(x,peso);
                    if(rta){
                        this.pintarTDA();
                        this.impNota("Arista ha sido insertada correctamente!", 0);
                    }else{
                        this.pintarTDA();
                        this.impNota("No se puede insertar la Arista!", 1);
                    }                    
                }                    
                else
                    this.impNota("No se puede seleccionar el Vertice Destino!", 1);
           break;
            
           //Eliminar Vertice
           case 3:
                char valEli = this.grafoG.eliminarVertice(lx, ly);
                rta = valEli!='1'?this.simulador.eliminarVertice(valEli):false;
                if(rta){
                    this.impNota("Vertice eliminado Correctamente!", 0);
                    this.pintarTDA();
                }
                else
                    this.impNota("Vertice no se pudo eliminar!", 1);
           break;
               
           //Asignar el primer vertice de la Arista
           case 4:                
                this.lx = lx;
                this.ly = ly;
                if(this.grafoG.pintarVertice(lx, ly)){
                    this.turno=5;
                    this.impNota("Vertice origen de la Arista seleccionado!", 0);
                }                    
                else
                    this.impNota("No se puede seleccionar el Vertice Origen!",1);
           break;    
           
           //Eliminar Arista
           case 5:
               String yy=this.grafoG.eliminarArista(this.lx, this.ly, lx, ly);
               if(!yy.isEmpty()){
                   this.turno=4;
                    rta=this.simulador.eliminarArista(yy);
                    if(rta){
                        this.pintarTDA();
                        this.impNota("Arista eliminada Correctamente!", 0);
                    }else{
                        this.pintarTDA();
                        this.impNota("No se puede eliminar la Arista con Exito!", 1);
                    }                    
                }                    
                else
                    this.impNota("No se puede seleccionar el Vertice Destino!", 1);
           break;
        }
               
    }
    
    
    
    @FXML
    private void btInsVertice() {    
        try{  
            this.pintarTDA();
            msg.setText("Seleccione la posicion donde desea Insertar el Nuevo Vertice.");
            msg.setVisible(true);
            this.turno = 0;
            this.grafoG.reajustarColores();
            this.impNota("Insertando Vertices..", 0);
        }catch(Exception e){
            this.impNota("No se puede seleccionar el Elemento!", 1); 
        }
    }
    
    @FXML
    private void btInsArista() {    
        try{
            this.pintarTDA();
            msg.setText("Seleccione el primer Vertice de la Arista y acontinuacion el siguiente Vertice.");
            msg.setVisible(true);
            this.turno = 1;
            this.grafoG.reajustarColores();
            this.impNota("Insertando Aristas..", 0);
        }catch(Exception e){
            this.impNota("No se puede seleccionar el Elemento!", 1); 
        }
    }
    
    @FXML
    private void btEliVertice() {    
        try{  
            this.pintarTDA();
            msg.setText("Seleccione la posicion donde se ubica Vertice a eliminar.");
            msg.setVisible(true);
            this.turno = 3;
            this.grafoG.reajustarColores();
            this.impNota("Eliminando Vertices..", 0);
        }catch(Exception e){
            this.impNota("No se puede seleccionar el Elemento!", 1); 
        }
    }
    
    @FXML
    private void btEliArista() {    
        try{  
            this.pintarTDA();
            msg.setText("Seleccione el primer Vertice de la Arista y acontinuacion el siguiente Vertice.");
            msg.setVisible(true);
            this.turno = 4;
            this.grafoG.reajustarColores();
            this.impNota("Eliminando Aristas..", 0);
        }catch(Exception e){
            this.impNota("No se puede seleccionar el Elemento!", 1); 
        }
    }
    
    @FXML
    private void btMatrizAdy(){
        try{
            if(!this.simulador.estaVacioGrafo()){
                this.turno= -1;
                this.invisibles();
                this.area.setText(this.simulador.getMatrizAdyacencia());
                this.area.setVisible(true);
                this.impNota("Matriz de Adyacencia del Grafo determinada!", 0); 
                return;
            }
            this.impNota("El Grafo aun no posee Elementos!", 1);             
        }catch(Exception e){
            this.impNota("No se puede calcular la Matriz!", 1); 
        }
    }
    
    @FXML
    private void btMatrizInci(){
        try{
            if(!this.simulador.estaVacioGrafo()){
                this.turno= -1;
                this.invisibles();
                this.area.setText(this.simulador.getMatrizIncidencia());
                this.area.setVisible(true);
                this.impNota("Matriz de Incidencia del Grafo determinada!", 0); 
                return;
            }
            this.impNota("El Grafo aun no posee Elementos!", 1); 
        }catch(Exception e){
            this.impNota("No se puede calcular la Matriz!", 1); 
        }
    }
    
    @FXML
    private void btRuta(){
        try{
            String val = this.txtRuta.getText();
            txtRuta.setText("");
            this.turno = -1;
            if(val.isEmpty()){
                impNota("Debe ingresar los Nodos!",1);
                return;
            }
            if(this.simulador.estaVacioGrafo()){
                impNota("El Grafo no posee Elementos!",1);
                return;
            }  
            if(this.simulador==null){
                impNota("Debe crear primero un Grafo!",1);
                return;
            }
            
            //determinacion de la ruta
            if(val.length()<3 || !val.contains("-")){
                impNota("Debe ingresar una cadena v1-v2, donde v1 y v2 son los vertices a ubicar!",1);
                return;
            }
            char v1 = val.charAt(0);
            char v2 = val.charAt(2);
            if(!estaVertice(v1) || !estaVertice(v2)){
                impNota("Alguno de los Vertices no es correcto!",1);
                return;
            }
            
            this.pintarTDA();
            String ruta = this.simulador.getRutaEntre(v1,v2);            
            if(!ruta.equalsIgnoreCase("No existe ruta posible estre los Nodos!")){
                msg.setText("Ruta entre ("+String.valueOf(v1)+"-"+String.valueOf(v2)+"):   "+ruta);
                msg.setVisible(true);
                this.impNota("Ruta entre Nodos determinada!", 0); 
                this.grafoG.animacion(0,ruta,this.lineaTiempo);
                return;
            }
            msg.setText("No existe dicha ruta entre los Vertices ingresados: ("+String.valueOf(v1)+"-"+String.valueOf(v2)+")");
            msg.setVisible(true);
            this.impNota("No se puede encontrar la Ruta entre los Nodos!", 1); 
            
        }catch(Exception e){
            this.impNota("No se puede calcular la ruta entre Vertices!", 1); 
        }
    }
    
    @FXML
    private void btDijkstra(){
        try{
            String val = this.txtRuta.getText();
            txtRuta.setText("");
            this.turno = -1;
            if(val.isEmpty()){
                impNota("Debe ingresar los Nodos!",1);
                return;
            }
            if(this.simulador.estaVacioGrafo()){
                impNota("El Grafo no posee Elementos!",1);
                return;
            }  
            if(this.simulador==null){
                impNota("Debe crear primero un Grafo!",1);
                return;
            }
            
            //determinacion de la ruta
            if(val.length()<3 || !val.contains("-")){
                impNota("Debe ingresar una cadena v1-v2, donde v1 y v2 son los vertices a ubicar!",1);
                return;
            }
            char v1 = val.charAt(0);
            char v2 = val.charAt(2);
            if(!estaVertice(v1) || !estaVertice(v2)){
                impNota("Alguno de los Vertices no es correcto!",1);
                return;
            }
            
            this.pintarTDA();
            String ruta = this.simulador.getDijkstra(v1,v2);           
            if(!ruta.equalsIgnoreCase("No existe ruta posible estre los Nodos!")){
                msg.setText("Ruta minima por Dijkstra entre ("+String.valueOf(v1)+"-"+String.valueOf(v2)+"):   "+ruta);
                msg.setVisible(true);
                this.impNota("Ruta minima Dijkstra entre Nodos calculada!", 0); 
                this.grafoG.animacion(0,ruta,this.lineaTiempo);
                return;
            }
            msg.setText("No existe dicha ruta entre los Vertices ingresados: ("+String.valueOf(v1)+"-"+String.valueOf(v2)+")");
            msg.setVisible(true);
            this.impNota("No se puede encontrar la Ruta entre los Nodos!", 1); 
            
        }catch(Exception e){
            this.impNota("No se puede calcular la ruta Dijkstra!", 1); 
        }
    }
    
    @FXML
    private void btCostoMinimo(){
        try{
            String val = this.txtRuta.getText();
            txtRuta.setText("");
            this.turno = -1;
            if(val.isEmpty()){
                impNota("Debe ingresar los Nodos!",1);
                return;
            }
            if(this.simulador.estaVacioGrafo()){
                impNota("El Grafo no posee Elementos!",1);
                return;
            }  
            if(this.simulador==null){
                impNota("Debe crear primero un Grafo!",1);
                return;
            }
            
            //determinacion de la ruta
            if(val.length()<3 || !val.contains("-")){
                impNota("Debe ingresar una cadena v1-v2, donde v1 y v2 son los vertices a ubicar!",1);
                return;
            }
            char v1 = val.charAt(0);
            char v2 = val.charAt(2);
            if(!estaVertice(v1) || !estaVertice(v2)){
                impNota("Alguno de los Vertices no es correcto!",1);
                return;
            }
            
            this.pintarTDA();
            String ruta = this.simulador.getDijkstra(v1,v2);           
            if(!ruta.equalsIgnoreCase("No existe ruta posible estre los Nodos!")){
                msg.setText("Costo de Ruta Minima ("+String.valueOf(v1)+"-"+String.valueOf(v2)+"):   "+this.simulador.getCostoRutaMinima(v1,v2));
                msg.setVisible(true);
                this.impNota("Costo de Ruta minima Dijkstra entre Nodos calculada!", 0); 
                this.grafoG.animacion(0,ruta,this.lineaTiempo);
                return;
            }
            msg.setText("No existe dicha ruta entre los Vertices ingresados: ("+String.valueOf(v1)+"-"+String.valueOf(v2)+")");
            msg.setVisible(true);
            this.impNota("No se puede encontrar el Costo de Ruta entre los Nodos!", 1); 
        }catch(Exception e){
            this.impNota("No se puede calcular el costo minimo de la Ruta!", 1); 
        }
    }
    
    @FXML
    private void btCirEuleriano(){
        try{
        if(this.simulador.estaVacioGrafo()){
                impNota("El Grafo no posee Elementos!",1);
                return;
            }  
        if(this.simulador==null){
            impNota("Debe crear primero un Grafo!",1);
            return;
        }
        this.turno = -1;
        this.pintarTDA();
        String ruta = this.simulador.getCicloEuleriano();
        if(!ruta.equalsIgnoreCase("No existe Ciclo Euleriano en el Grafo!")){
            msg.setText("Ciclo Euleriano del Grafo:  "+ruta);
            msg.setVisible(true);
            this.impNota("Ciclo Euleriano calculado!", 0); 
            this.grafoG.animacion(0,ruta,this.lineaTiempo);
            return;
        }
        msg.setText("No existe Ciclo Euleriano en el Grafo!");
        msg.setVisible(true);
        this.impNota("Ciclo Euleriano no Encontrado!", 1); 
        }catch(Exception e){
            this.impNota("No se puede determinar el Ciclo Euleriano", 1); 
        }
    }
    
    @FXML
    private void btCirHamiltoniano(){
        try{
        if(this.simulador.estaVacioGrafo()){
                impNota("El Grafo no posee Elementos!",1);
                return;
            }  
        if(this.simulador==null){
            impNota("Debe crear primero un Grafo!",1);
            return;
        }
        this.turno = -1;
        this.pintarTDA();
        String ruta = this.simulador.getCicloHamiltoniano();
        if(!ruta.equalsIgnoreCase("No existe Ciclo Hamiltoniano en el Grafo!")){
            msg.setText("Ciclo Hamiltoniano del Grafo:  "+ruta);
            msg.setVisible(true);
            this.impNota("Ciclo Hamiltoniano calculado!", 0); 
            this.grafoG.animacion(0,ruta,this.lineaTiempo);
            return;
        }
        msg.setText("No existe Ciclo Hamiltoniano en el Grafo!");
        msg.setVisible(true);
        this.impNota("Ciclo Hamiltoniano no Encontrado!", 1); 
        }catch(Exception e){
            this.impNota("No se puede determinar el Ciclo Hamiltoniano!", 1); 
        }
    }
    
    @FXML
    private void btCamEuleriano(){
        try{
        if(this.simulador.estaVacioGrafo()){
                impNota("El Grafo no posee Elementos!",1);
                return;
            }  
        if(this.simulador==null){
            impNota("Debe crear primero un Grafo!",1);
            return;
        }
        this.turno = -1;
        this.pintarTDA();
        String ruta = this.simulador.getCaminoEuleriano();
        if(!ruta.equalsIgnoreCase("No existe Camino Euleriano en el Grafo!")){
            msg.setText("Camino Euleriano del Grafo:  "+ruta);
            msg.setVisible(true);
            this.impNota("Camino Euleriano calculado!", 0); 
            this.grafoG.animacion(0,ruta,this.lineaTiempo);
            return;
        }
        msg.setText("No existe Camino Euleriano en el Grafo!");
        msg.setVisible(true);
        this.impNota("Camino Euleriano no Encontrado!", 1);       
        }catch(Exception e){
            this.impNota("No se puede determinar el Camino Euleriano!", 1); 
        }
    }
    
    @FXML
    private void btCamHamiltoniano(){
        try{
        if(this.simulador.estaVacioGrafo()){
                impNota("El Grafo no posee Elementos!",1);
                return;
            }  
        if(this.simulador==null){
            impNota("Debe crear primero un Grafo!",1);
            return;
        }
        this.turno = -1;
        this.pintarTDA();
        String ruta = this.simulador.getCaminoHamiltoniano();
        if(!ruta.equalsIgnoreCase("No existe Camino Hamiltoniano en el Grafo!")){
            msg.setText("Camino Hamiltoniano del Grafo:  "+ruta);
            msg.setVisible(true);
            this.impNota("Camino Hamiltoniano calculado!", 0); 
            this.grafoG.animacion(0,ruta,this.lineaTiempo);
            return;
        }
        msg.setText("No existe Camino Hamiltoniano en el Grafo!");
        msg.setVisible(true);
        this.impNota("Camino Hamiltoniano no Encontrado!", 1);  
        }catch(Exception e){
            this.impNota("No se puede determinar el Camino Hamiltoniano!", 1); 
        }
    }
    
    @FXML
    private void btBEP(){
        try{
            if(this.simulador.estaVacioGrafo()){
                impNota("El Grafo no posee Elementos!",1);
                return;
            }  
            if(this.simulador==null){
                impNota("Debe crear primero un Grafo!",1);
                return;
            }
            this.turno = -1;
            this.pintarTDA();
            String ruta = this.simulador.getBEP(this.grafoG.getPrimerVertice());
            if(!ruta.equalsIgnoreCase("No se puede determinar la BEP del Grafo!")){
                msg.setText("Busqueda en Profundidad:  "+ruta);
                msg.setVisible(true);
                this.impNota("Busqueda en Profunidad determinada", 0); 
                this.grafoG.animacion(1,ruta,this.lineaTiempo);  
                return;
            }
            this.impNota("Busqueda en Profunidad no se puede determinar", 1); 
            
        }catch(Exception e){
            this.impNota("No se puede calcular la Busqueda en Profundidad (BEP)!", 1); 
        }
    }
    
    @FXML
    private void btBEA(){
        try{
            if(this.simulador.estaVacioGrafo()){
                impNota("El Grafo no posee Elementos!",1);
                return;
            }  
            if(this.simulador==null){
                impNota("Debe crear primero un Grafo!",1);
                return;
            }
             this.turno = -1;
            this.pintarTDA();
            String ruta = this.simulador.getBEA(this.grafoG.getPrimerVertice());
            if(!ruta.equalsIgnoreCase("No se puede determinar la BEA del Grafo!")){
                msg.setText("Busqueda en Anchura:  "+ruta);
                msg.setVisible(true);
                this.impNota("Busqueda en Anchura determinada", 0); 
                this.grafoG.animacion(1,ruta,this.lineaTiempo);  
                return;
            }
            this.impNota("Busqueda en Anchura no se puede determinar", 1); 
        }catch(Exception e){
            this.impNota("No se puede calcular la Busqueda en Anchura (BEA)!", 1); 
        }
    }
    
    @FXML
    private void salir() {  
        System.exit(0);
    }
    
    
    private void cargarLineas() {
        
        this.lineas = new Line[50];        
        this.lineas[0]= linea0;this.lineas[1]= linea1;this.lineas[2]= linea2;this.lineas[3]= linea3;this.lineas[4]= linea4;
        this.lineas[5]= linea5;this.lineas[6]= linea6;this.lineas[7]= linea7;this.lineas[8]= linea8;this.lineas[9]= linea9;
        this.lineas[10]= linea10;this.lineas[11]= linea11;this.lineas[12]= linea12;this.lineas[13]= linea13;this.lineas[14]= linea14;
        this.lineas[15]= linea15;this.lineas[16]= linea16;this.lineas[17]= linea17;this.lineas[18]= linea18;this.lineas[19]= linea19;
        this.lineas[20]= linea20;this.lineas[21]= linea21;this.lineas[22]= linea22;this.lineas[23]= linea23;this.lineas[24]= linea24;
        this.lineas[25]= linea25;this.lineas[26]= linea26;this.lineas[27]= linea27;this.lineas[28]= linea28;this.lineas[29]= linea29;
        this.lineas[30]= linea30;this.lineas[31]= linea31;this.lineas[32]= linea32;this.lineas[33]= linea33;this.lineas[34]= linea34;
        this.lineas[35]= linea35;this.lineas[36]= linea36;this.lineas[37]= linea37;this.lineas[38]= linea38;this.lineas[39]= linea39;        
        this.lineas[40]= linea40;this.lineas[41]= linea41;this.lineas[42]= linea42;this.lineas[43]= linea43;this.lineas[44]= linea44;
        this.lineas[45]= linea45;this.lineas[46]= linea46;this.lineas[47]= linea47;this.lineas[48]= linea48;this.lineas[49]= linea49;        
        for(int i=0; i<this.lineas.length; i++){
            this.lineas[i].setVisible(false);  
            this.lineas[i].setFill(Color.BLACK);
        }            
        }
    
    private void cargarNodos() {
        //Creando la pila de circulos
        this.nodos = new Circle[100];        
        this.nodos[0]= raiz;this.nodos[1]= nodo1;this.nodos[2]= nodo2;this.nodos[3]= nodo3;this.nodos[4]= nodo4;
        this.nodos[5]= nodo5;this.nodos[6]= nodo6;this.nodos[7]= nodo7;this.nodos[8]= nodo8;this.nodos[9]= nodo9;
        this.nodos[10]= nodo10;this.nodos[11]= nodo11;this.nodos[12]= nodo12;this.nodos[13]= nodo13;this.nodos[14]= nodo14;
        this.nodos[15]= nodo15;this.nodos[16]= nodo16;this.nodos[17]= nodo17;this.nodos[18]= nodo18;this.nodos[19]= nodo19;
        this.nodos[20]= nodo20;this.nodos[21]= nodo21;this.nodos[22]= nodo22;this.nodos[23]= nodo23;this.nodos[24]= nodo24;
        this.nodos[25]= nodo25;this.nodos[26]= nodo26;this.nodos[27]= nodo27;this.nodos[28]= nodo28;this.nodos[29]= nodo29;
        this.nodos[30]= nodo30;this.nodos[31]= nodo31;this.nodos[32]= nodo32;this.nodos[33]= nodo33;this.nodos[34]= nodo34;
        this.nodos[35]= nodo35;this.nodos[36]= nodo36;this.nodos[37]= nodo37;this.nodos[38]= nodo38;this.nodos[39]= nodo39;
        this.nodos[40]= nodo40;this.nodos[41]= nodo41;this.nodos[42]= nodo42;this.nodos[43]= nodo43;this.nodos[44]= nodo44;
        this.nodos[45]= nodo45;this.nodos[46]= nodo46;this.nodos[47]= nodo47;this.nodos[48]= nodo48;this.nodos[49]= nodo49;
        this.nodos[50]= nodo50;this.nodos[51]= nodo51;this.nodos[52]= nodo52;this.nodos[53]= nodo53;this.nodos[54]= nodo54;
        this.nodos[55]= nodo55;this.nodos[56]= nodo56;this.nodos[57]= nodo57;this.nodos[58]= nodo58;this.nodos[59]= nodo59;
        this.nodos[60]= nodo60;this.nodos[61]= nodo61;this.nodos[62]= nodo62;this.nodos[63]= nodo63;this.nodos[64]= nodo64;
        this.nodos[65]= nodo65;this.nodos[66]= nodo66;this.nodos[67]= nodo67;this.nodos[68]= nodo68;this.nodos[69]= nodo69;
        this.nodos[70]= nodo70;this.nodos[71]= nodo71;this.nodos[72]= nodo72;this.nodos[73]= nodo73;this.nodos[74]= nodo74;
        this.nodos[75]= nodo75;this.nodos[76]= nodo76;this.nodos[77]= nodo77;this.nodos[78]= nodo78;this.nodos[79]= nodo79;
        this.nodos[80]= nodo80;this.nodos[81]= nodo81;this.nodos[82]= nodo82;this.nodos[83]= nodo83;this.nodos[84]= nodo84;
        this.nodos[85]= nodo85;this.nodos[86]= nodo86;this.nodos[87]= nodo87;this.nodos[88]= nodo88;this.nodos[89]= nodo89;
        this.nodos[90]= nodo90;this.nodos[91]= nodo91;this.nodos[92]= nodo92;this.nodos[93]= nodo93;this.nodos[94]= nodo94;
        this.nodos[95]= nodo95;this.nodos[96]= nodo96;this.nodos[97]= nodo97;this.nodos[98]= nodo98;this.nodos[99]= nodo99;                
        //Creando la pila de Labels
        this.labels = new Label[100];        
        this.labels[0]= label0;this.labels[1]= label1;this.labels[2]= label2;this.labels[3]= label3;this.labels[4]= label4;
        this.labels[5]= label5;this.labels[6]= label6;this.labels[7]= label7;this.labels[8]= label8;this.labels[9]= label9;
        this.labels[10]= label10;this.labels[11]= label11;this.labels[12]= label12;this.labels[13]= label13;this.labels[14]= label14;
        this.labels[15]= label15;this.labels[16]= label16;this.labels[17]= label17;this.labels[18]= label18;this.labels[19]= label19;
        this.labels[20]= label20;this.labels[21]= label21;this.labels[22]= label22;this.labels[23]= label23;this.labels[24]= label24;
        this.labels[25]= label25;this.labels[26]= label26;this.labels[27]= label27;this.labels[28]= label28;this.labels[29]= label29;
        this.labels[30]= label30;this.labels[31]= label31;this.labels[32]= label32;this.labels[33]= label33;this.labels[34]= label34;
        this.labels[35]= label35;this.labels[36]= label36;this.labels[37]= label37;this.labels[38]= label38;this.labels[39]= label39;
        this.labels[40]= label40;this.labels[41]= label41;this.labels[42]= label42;this.labels[43]= label43;this.labels[44]= label44;
        this.labels[45]= label45;this.labels[46]= label46;this.labels[47]= label47;this.labels[48]= label48;this.labels[49]= label49;
        this.labels[50]= label50;this.labels[51]= label51;this.labels[52]= label52;this.labels[53]= label53;this.labels[54]= label54;
        this.labels[55]= label55;this.labels[56]= label56;this.labels[57]= label57;this.labels[58]= label58;this.labels[59]= label59;
        this.labels[60]= label60;this.labels[61]= label61;this.labels[62]= label62;this.labels[63]= label63;this.labels[64]= label64;
        this.labels[65]= label65;this.labels[66]= label66;this.labels[67]= label67;this.labels[68]= label68;this.labels[69]= label69;
        this.labels[70]= label70;this.labels[71]= label71;this.labels[72]= label72;this.labels[73]= label73;this.labels[74]= label74;
        this.labels[75]= label75;this.labels[76]= label76;this.labels[77]= label77;this.labels[78]= label78;this.labels[79]= label79;
        this.labels[80]= label80;this.labels[81]= label81;this.labels[82]= label82;this.labels[83]= label83;this.labels[84]= label84;
        this.labels[85]= label85;this.labels[86]= label86;this.labels[87]= label87;this.labels[88]= label88;this.labels[89]= label89;
        this.labels[90]= label90;this.labels[91]= label91;this.labels[92]= label92;this.labels[93]= label93;this.labels[94]= label94;
        this.labels[95]= label95;this.labels[96]= label96;this.labels[97]= label97;this.labels[98]= label98;this.labels[99]= label99;        
        
        this.pesos = new Label[100];        
        this.pesos[0]= labelp0;this.pesos[1]= labelp1;this.pesos[2]= labelp2;this.pesos[3]= labelp3;this.pesos[4]= labelp4;
        this.pesos[5]= labelp5;this.pesos[6]= labelp6;this.pesos[7]= labelp7;this.pesos[8]= labelp8;this.pesos[9]= labelp9;
        this.pesos[10]= labelp10;this.pesos[11]= labelp11;this.pesos[12]= labelp12;this.pesos[13]= labelp13;this.pesos[14]= labelp14;
        this.pesos[15]= labelp15;this.pesos[16]= labelp16;this.pesos[17]= labelp17;this.pesos[18]= labelp18;this.pesos[19]= labelp19;
        this.pesos[20]= labelp20;this.pesos[21]= labelp21;this.pesos[22]= labelp22;this.pesos[23]= labelp23;this.pesos[24]= labelp24;
        this.pesos[25]= labelp25;this.pesos[26]= labelp26;this.pesos[27]= labelp27;this.pesos[28]= labelp28;this.pesos[29]= labelp29;
        this.pesos[30]= labelp30;this.pesos[31]= labelp31;this.pesos[32]= labelp32;this.pesos[33]= labelp33;this.pesos[34]= labelp34;
        this.pesos[35]= labelp35;this.pesos[36]= labelp36;this.pesos[37]= labelp37;this.pesos[38]= labelp38;this.pesos[39]= labelp39;
        this.pesos[40]= labelp40;this.pesos[41]= labelp41;this.pesos[42]= labelp42;this.pesos[43]= labelp43;this.pesos[44]= labelp44;
        this.pesos[45]= labelp45;this.pesos[46]= labelp46;this.pesos[47]= labelp47;this.pesos[48]= labelp48;this.pesos[49]= labelp49;
        this.pesos[50]= labelp50;this.pesos[51]= labelp51;this.pesos[52]= labelp52;this.pesos[53]= labelp53;this.pesos[54]= labelp54;
        this.pesos[55]= labelp55;this.pesos[56]= labelp56;this.pesos[57]= labelp57;this.pesos[58]= labelp58;this.pesos[59]= labelp59;
        this.pesos[60]= labelp60;this.pesos[61]= labelp61;this.pesos[62]= labelp62;this.pesos[63]= labelp63;this.pesos[64]= labelp64;
        this.pesos[65]= labelp65;this.pesos[66]= labelp66;this.pesos[67]= labelp67;this.pesos[68]= labelp68;this.pesos[69]= labelp69;
        this.pesos[70]= labelp70;this.pesos[71]= labelp71;this.pesos[72]= labelp72;this.pesos[73]= labelp73;this.pesos[74]= labelp74;
        this.pesos[75]= labelp75;this.pesos[76]= labelp76;this.pesos[77]= labelp77;this.pesos[78]= labelp78;this.pesos[79]= labelp79;
        this.pesos[80]= labelp80;this.pesos[81]= labelp81;this.pesos[82]= labelp82;this.pesos[83]= labelp83;this.pesos[84]= labelp84;
        this.pesos[85]= labelp85;this.pesos[86]= labelp86;this.pesos[87]= labelp87;this.pesos[88]= labelp88;this.pesos[89]= labelp89;
        this.pesos[90]= labelp90;this.pesos[91]= labelp91;this.pesos[92]= labelp92;this.pesos[93]= labelp93;this.pesos[94]= labelp94;
        this.pesos[95]= labelp95;this.pesos[96]= labelp96;this.pesos[97]= labelp97;this.pesos[98]= labelp98;this.pesos[99]= labelp99;        
    
        for(int i=0; i<100; i++){
            nodos[i].setVisible(false);
            nodos[i].setFill(Color.GREENYELLOW);
            nodos[i].setStroke(Color.GREEN);
            nodos[i].setRadius(12.0);
            labels[i].setVisible(false);
            pesos[i].setVisible(false);
        }
        this.msg.setLayoutY(450.0);
        this.msg.setVisible(false);        
    }
    
    
    @FXML
    private void impNota(String nota, int tipo){
        String cab = "";
        if(tipo==0){
            cab="Exito, ";
            this.nota.setTextFill(Color.BLACK);
            this.borde.setImage(borde2.getImage());
        }            
        if(tipo==1){
            cab="Error, ";
            this.nota.setTextFill(Color.BLACK);
            this.borde.setImage(borde3.getImage());
        }
        this.nota.setVisible(true);
        this.nota.setText(cab+nota);
    }
    
    @Override
    @FXML
    public void initialize(URL url, ResourceBundle rb) {
        try{
            this.grafoG = new GrafoG();
            this.inicializar();
            grafoG.cargarNodos(this.nodos);
            grafoG.cargarLabels(this.labels);
            grafoG.cargarLineas(this.lineas);
            grafoG.cargarPesos(this.pesos);
            grafoG.cargarVals();
            this.simulador = new SimuladorGrafoND();
            this.lineaTiempo = new Timeline();        
            this.pintarTDA();
        this.impNota("El Simulador para GrafoND<T> ha iniciado!",0);
        }catch(Exception e){
            this.impNota("El Simulador para GrafoND<T> no puede iniciar!",1);
        }
    }
    
    @FXML
    private void inicializar() {
        //Creando la pila de lineas
        this.cargarLineas();
        this.cargarNodos();
    }
    
    @FXML
    private boolean esNumero(String val){
    try{
        Integer.parseInt(val);
    }catch(Exception e){
        return (false);
    }
    return (true);
    }
    
    @FXML
    private void pintarTDA(){
        try{            
            this.invisibles();
            this.grafoG.pintarGrafo();   
            
        }catch(Exception e){
            this.impNota("No se puede pintar la Estructura",1);
        }
    }

    private void invisibles() {
        for(int i=0; i<this.nodos.length; i++){
            nodos[i].setVisible(false);
            nodos[i].setFill(Color.GREENYELLOW);
            nodos[i].setStroke(Color.GREEN);
        }            
        for(int i=0; i<this.labels.length; i++)
            labels[i].setVisible(false);
        for(int i=0; i<this.pesos.length; i++){
            pesos[i].setVisible(false);
            pesos[i].setTextFill(Color.BLACK);
        }            
        for(int i=0; i<this.lineas.length; i++){
            lineas[i].setVisible(false);
            lineas[i].setStroke(Color.BLACK);
        }            
        this.area.setVisible(false);
        this.msg.setVisible(false);
    }

    private boolean estaVertice(char v1) {
        return (this.simulador.estaVertice(v1));
    }
    
    
    
}