package com.example.unodtantos.appqueology2.controlador;

import android.app.Application;
import android.content.Context;
import android.database.Cursor;

import com.example.unodtantos.appqueology2.modelo.Arista;
import com.example.unodtantos.appqueology2.modelo.DataBaseManagerProyecto;
import com.example.unodtantos.appqueology2.modelo.DataBaseManagerUE;
import com.example.unodtantos.appqueology2.modelo.Estructura;
import com.example.unodtantos.appqueology2.modelo.Nodo;
import com.example.unodtantos.appqueology2.modelo.Vertice;

import java.util.ArrayList;
import java.util.LinkedList;
import java.util.Stack;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;

/**
 * Created by unodtantos on 18/03/2015.
 */
public class Controlador extends Application {

    /*--------------------------------------------------------------------------------------------*/

    // <editor-fold defaultstate="collapsed" desc="Atributos de la clase">

    private Context context;
    private DataBaseManagerProyecto db_p;
    private Estructura estructura;
    private ArrayList medidasPantalla;
    private static final ScheduledExecutorService worker =  Executors.newSingleThreadScheduledExecutor();
    private String ue_seleccionada = "";
    private String ue_seleccionada_grafo = "";
    private String ue_seleccionada_diario = "";
    private String ue_seleccionada_tabla = "";

    // </editor-fold>

    /*--------------------------------------------------------------------------------------------*/

    // <editor-fold defaultstate="collapsed" desc="Constructor de la clase">

    /**
     * Constructor de la clase.
     */
    @Override
    public void onCreate() {
        super.onCreate();
        this.context = getApplicationContext();
        this.db_p = new DataBaseManagerProyecto(this.context);
        this.estructura = new Estructura();
        this.medidasPantalla = new ArrayList();
    }

    // </editor-fold>

    /*--------------------------------------------------------------------------------------------*/

    // <editor-fold defaultstate="collapsed" desc="Transpasando datos entre clases">

    /**
     * Método que se encarga de obtener el id de una realación a partir de los nombres de las UEs
     * que la conforman.
     * @param nombre
     * @param nom_actual
     * @param nom_relacion
     * @param padre_hijo
     * @return
     */
    public String obtenerIdUeRelacion(String nombre, String nom_actual, String nom_relacion,int padre_hijo){

        DataBaseManagerUE db_ue = new DataBaseManagerUE(context, nombre);
        Cursor cursor = db_ue.cargarCursorUEsPadres();
        String id = "";
        while (cursor.moveToNext()){
            if(padre_hijo == 1){
                if (cursor.getString(1).equals(nom_actual) && cursor.getString(2).equals(nom_relacion)) {
                    id = cursor.getString(0);
                }
            } else {
                if (cursor.getString(2).equals(nom_actual) && cursor.getString(1).equals(nom_relacion)) {
                    id = cursor.getString(0);
                }
            }
        }
        return id;
    }

    /**
     * Método que comprueba si existe una relación a partir de los nombre de las UEs que la
     * conforman.
     * @param nombre_bd
     * @param nombre_ue_central
     * @param nombre_ue_relacion
     * @return
     */
    public Boolean comprobarExisteRelacion(String nombre_bd, String nombre_ue_central, String nombre_ue_relacion){

        Boolean encontrado = false;
        DataBaseManagerUE db_ue = new DataBaseManagerUE(context, nombre_bd);
        Cursor cursor = db_ue.cargarCursorUEsPadres();

        while (cursor.moveToNext()) {
            if ((cursor.getString(1).toString().equals(nombre_ue_central) && cursor.getString(2).toString().equals(nombre_ue_relacion)) || (cursor.getString(1).toString().equals(nombre_ue_relacion) && cursor.getString(2).toString().equals(nombre_ue_central))){
                encontrado = true;
            }
        }
        return encontrado;
    }

    /**
     * Método que se encarga de buscar todas las relaciones de una UE.
     * @param padre_hijo
     * @param nombre_bd
     * @param nombre_ue
     * @return
     */
    public ArrayList<String> buscarRelaciones(int padre_hijo, String nombre_bd, String nombre_ue) {

        Cursor cursor;
        ArrayList<String> lista_relaciones = new ArrayList<>();
        DataBaseManagerUE db_ue = new DataBaseManagerUE(context, nombre_bd);

        cursor = db_ue.cargarCursorUEsPadres();

        while (cursor.moveToNext()) {

            if (padre_hijo == 1) {
                if (cursor.getString(1).equals(nombre_ue)) {
                    lista_relaciones.add(cursor.getString(2).toString());
                }
            } else {
                if (cursor.getString(2).equals(nombre_ue)) {
                    lista_relaciones.add(cursor.getString(1).toString());
                }
            }
        }
        return lista_relaciones;
    }

    /**
     * Método que se encarga de comprobar si existe una UE a partir de su nombre.
     * @param nombre_bd
     * @param nombre_ue
     * @return
     */
    public Boolean comprobarExiteUe(String nombre_bd, String nombre_ue) {
        Boolean encontrado = false;
        DataBaseManagerUE db_ue = new DataBaseManagerUE(context, nombre_bd);
        Cursor cursor = db_ue.cargarCursorUEs();
        while (cursor.moveToNext()) {
            if (cursor.getString(1).equals(nombre_ue)) {
                encontrado = true;
            }
        }
        return encontrado;
    }

    /**
     * Método que se encarga de comprobar si existe un Proyecto a partir de su nombre.
     * @param nombre_pr
     * @return
     */
    public Boolean comprobarExisteProyecto(String nombre_pr){

        Cursor cursor = db_p.cargarCursorProyectos();
        Boolean encontrado = false;

        while(cursor.moveToNext() && !encontrado){
            if(cursor.getString(1).toString().equals(nombre_pr)){
                encontrado = true;
            }
        }
        return encontrado;
    }

    /**
     * Método que se encarga de obtener los valores que caracterizan una UE guardándolos en un +
     * objeto del tipo Nodo.
     * @param nombre_p
     * @param nom_ue
     * @return
     */
    public Nodo obtenerDatosUe(String nombre_p, String nom_ue){
        Nodo n = new Nodo();
        DataBaseManagerUE db_ue = new DataBaseManagerUE(this.context, nombre_p);
        Cursor cursor = db_ue.cargarCursorUEs();
        while(cursor.moveToNext()){
            if(cursor.getString(1).toString().equals(nom_ue)){
                n.setId(Integer.parseInt(cursor.getString(0)));
                n.setNombre(cursor.getString(1));
                n.setTipoUe(cursor.getString(2));
                n.setDescripcion(cursor.getString(3));
                n.setFechaCreacionUe(cursor.getString(4));
                n.setDatacion1(cursor.getString(5));
                n.setDatacion2(cursor.getString(6));
                n.setNombreFoto(cursor.getString(7));
                n.setFechaFoto(cursor.getString(9));
                n.setUrlFoto(cursor.getString(8));
                n.setLocalizacion(cursor.getString(10));
            }
        }
        return n;
    }

    /**
     * Método que comprueba a partir de la id de una UE si tiene alguna foto almacenada.
     * @param nombre_p
     * @param id_ue
     * @return
     */
    public Nodo comprobarSiFoto(String nombre_p, int id_ue){

        Nodo n = new Nodo();

        DataBaseManagerUE db_p = new DataBaseManagerUE(context, nombre_p);
        Cursor cursor = db_p.cargarCursorUEs();

        while(cursor.moveToNext()){
            if(cursor.getString(0).toString().equals(String.valueOf(id_ue))){

                if(!cursor.getString(7).equals(null)){
                    n.setNombreFoto(cursor.getString(7));
                    n.setFechaFoto(cursor.getString(9));
                    n.setUrlFoto(cursor.getString(8));
                }
                if(!cursor.getString(10).equals(null)){
                    n.setLocalizacion(cursor.getString(10));
                }
            }
        }
        return n;
    }

    // </editor-fold>

    /*--------------------------------------------------------------------------------------------*/

    // <editor-fold defaultstate="collapsed" desc="Operaciones CRUD BBDD">

    // --------------------------------   INSERTS:   ---------------------------------------

    /**
     * Método que se encarga de insertar un nuevo Proyecto en la BBDD correspondiente.
     * @param nombre_pr
     * @param autor_pr
     * @return
     */
    public long insertarNuevoProyecto(String nombre_pr, String autor_pr){

        return this.db_p.insertarProyecto(nombre_pr, autor_pr);
    }

    /**
     * Método que se encarga de insertar una nueva UE en la BBDD correspondiente.
     * @param nombre_pr
     * @param nom_ue
     * @return
     */
    public long insertarUeActual(String nombre_pr, String nom_ue){
        DataBaseManagerUE db_ue = new DataBaseManagerUE(context, nombre_pr);
        return db_ue.insertarUeActual(nom_ue, "", "", "", "", "", "", "", "", "");
    }

    /**
     * Método que se encarga de insertar una nueva relación en la BBDD correspondiente.
     * @param nombre
     * @param nom_ue_actual
     * @param nom_padre
     * @return
     */
    public long insertarPadreUe(String nombre, String nom_ue_actual, String nom_padre) {
        DataBaseManagerUE db_ue = new DataBaseManagerUE(context, nombre);
        return db_ue.insertarPadre(nom_ue_actual, nom_padre);
    }

    // -----------------------------   SELECTS:   -------------------------------------

    /**
     * Método que permite recuperar todos los Proyectos almacenados.
     * @return
     */
    public Cursor selectCursorProyectos() {
        return db_p.cargarCursorProyectos();
    }

    /**
     * Método que se encarga de recuperar todas las UEs almacenadas para un Proyecto dado.
     * @param nombre
     * @return
     */
    public Cursor selectCursorUes(String nombre) {
        DataBaseManagerUE db_ue = new DataBaseManagerUE(this.context, nombre);
        return db_ue.cargarCursorUEs();
    }

    /**
     * Método que se encarga de recuperar todas las relaciones almacenadas para un Proyecto dado.
     * @param nombre
     * @return
     */
    public Cursor selectCursorUesPadres(String nombre) {
        DataBaseManagerUE db_ue = new DataBaseManagerUE(this.context, nombre);
        return db_ue.cargarCursorUEsPadres();
    }

    /**
     * Método que se encarga de recupera de la BBDD la última UE almacenada.
     * @param nombre_pr
     * @return
     */
    public ArrayList<String> selectUltimaUe(String nombre_pr){
        ArrayList datos_ue = new ArrayList();
        DataBaseManagerUE db_ue = new DataBaseManagerUE(this.context, nombre_pr);
        Cursor cursor = db_ue.cargarCursorUEs();
        cursor.moveToLast();
        int n = cursor.getCount();
        if (n > 0) {
            String nom = cursor.getString(1);
            datos_ue.add(nom);
            datos_ue.add(cursor.getString(4));
        }

        return datos_ue;
    }

    /**
     * Método que se encarga de recuperar la última relación almacenada en la BBDD correspondiente.
     * @param nombre_pr
     * @return
     */
    public ArrayList<String> selectUltimaRelacion(String nombre_pr){
        ArrayList datos_relacion = new ArrayList();
        DataBaseManagerUE db_ue = new DataBaseManagerUE(this.context, nombre_pr);
        Cursor cursor = db_ue.cargarCursorUEsPadres();
        int n = cursor.getCount();
        if (n > 0) {
            cursor.moveToLast();
            String nom = cursor.getString(1);
            datos_relacion.add(nom);
        }

        return datos_relacion;
    }

    // -------------------------------   DELETES:   -------------------------------------

    /**
     * Método que se encarga de eliminar un Proyecto determinado.
     * @param id
     * @return
     */
    public long eliminarProyecto(String id){
        return this.db_p.eliminarProyecto(id);
    }

    /**
     * Método que se encarga de eliminar una UE a partir de su id.
     * @param nombre_p
     * @param id
     * @return
     */
    public long eliminarUeId(String nombre_p, String id){
        DataBaseManagerUE db_ue = new DataBaseManagerUE(context, nombre_p);
        return db_ue.eliminarUE(id);
    }

    /**
     * Método que se encarga de eliminar una UE a partir de su nombre.
     * @param nombre_p
     * @param nom
     * @return
     */
    public long eliminarUePorNombre(String nombre_p, String nom){
        String id = null;
        DataBaseManagerUE db_ue =  new DataBaseManagerUE(context, nombre_p);
        Cursor cursor = db_ue.cargarCursorUEs();
        while(cursor.moveToNext()){
            if(cursor.getString(1).toString().equals(nom)){
                id = String.valueOf(cursor.getInt(0));
            }
        }
        return db_ue.eliminarUePorId(id);
    }

    /**
     * Método que se encarga de eliminar una relación a partir de su id.
     * @param nombre_bd
     * @param id
     * @return
     */
    public long eliminarPadrePorId(String nombre_bd, String id) {
        DataBaseManagerUE db_ue =  new DataBaseManagerUE(context, nombre_bd);
        return db_ue.eliminarPadrePorId(id);
    }

    /**
     * Método que se encarga de borrar la BBDD correspondiente.
     * @param nombre_p
     */
    public void borrarDataBase(String nombre_p){

        DataBaseManagerUE db_ue = new DataBaseManagerUE(context,nombre_p);
        db_ue.eliminarTablas(nombre_p);
        boolean result = deleteDatabase(nombre_p);
    }

    // ------------------------------    UPDATE:   -------------------------------------

    /**
     * Método que se encarga de actualizar los datos de una UE dada.
     * @param nombre_pr
     * @param datos_ue
     * @return
     */
    public long actualizarDatosUeCentral(String nombre_pr, Nodo datos_ue){
        String id = null;
        DataBaseManagerUE db_ue = new DataBaseManagerUE(context, nombre_pr);
        Cursor cursor = db_ue.cargarCursorUEs();
        while(cursor.moveToNext()){
            if(cursor.getString(1).toString().equals(datos_ue.getNombre().toString())){
                id = cursor.getString(0);
            }
        }
        return db_ue.actualizarDatosUeCentralParcial(datos_ue.getNombre(), datos_ue.getTipoUe(), datos_ue.getDescripcion(), datos_ue.getDatacion1(), datos_ue.getDatacion2(), id);
    }

    /**
     * Método que se encarga de actualizar los datos de una UE dada.
     * @param nombre_pr
     * @param datos_ue
     * @return
     */
    public long actualizarDatosUeCentral2(String nombre_pr, Nodo datos_ue){
        String id = null;
        DataBaseManagerUE db_ue = new DataBaseManagerUE(context, nombre_pr);
        Cursor cursor = db_ue.cargarCursorUEs();
        while(cursor.moveToNext()){
            if(cursor.getString(1).toString().equals(datos_ue.getNombre().toString())){
                id = cursor.getString(0);
            }
        }
        return db_ue.actualizarDatosUeCentralCompleto(datos_ue.getNombre(), datos_ue.getTipoUe(), datos_ue.getDescripcion(), datos_ue.getDatacion1(), datos_ue.getDatacion2(), datos_ue.getNombreFoto(), datos_ue.getFechaFoto(), datos_ue.getUrlFoto(), datos_ue.getLocalizacion(), id);
    }

    /**
     * Método que se encarga de actualizar las relaciones.
     * @param nombre_p
     * @param nombre_vieja
     * @param nombre_nueva
     * @return
     */
    public Boolean actualizarPadres(String nombre_p, String nombre_vieja, String nombre_nueva){

        DataBaseManagerUE db_p = new DataBaseManagerUE(context, nombre_p);
        Cursor cursor = db_p.cargarCursorUEsPadres();
        Boolean result = true;

        while(cursor.moveToNext()) {
            if (cursor.getString(1).equals(nombre_vieja) || cursor.getString(2).equals(nombre_vieja)) {
                long eliminar_p = eliminarPadrePorId(nombre_p, cursor.getString(0).toString());
                if (eliminar_p == -1) {
                    return false;
                } else {
                    if (cursor.getString(1).equals(nombre_vieja)) {
                        long insertar_p = insertarPadreUe(nombre_p, nombre_nueva, cursor.getString(2));
                        if (insertar_p == -1) {
                            return false;
                        }
                    } else {
                        long insertar_p = insertarPadreUe(nombre_p, cursor.getString(1), nombre_nueva);
                        if (insertar_p == -1) {
                            return false;
                        }
                    }
                }
            }
        }

        return result;
    }

    /**
     * Método que se encarga de actualizar las relaciones descendientes de una UE dada.
     * @param nombre_pr
     * @param nodo
     * @return
     */
    public Boolean actualizarDescendientes(String nombre_pr, Nodo nodo){

        Boolean resultado = true;

        long result = eliminarUeId(nombre_pr, String.valueOf(nodo.getId()));
        if(result == -1){
            resultado = false;
        }

        DataBaseManagerUE db_ue = new DataBaseManagerUE(this.context, nombre_pr);
        Cursor cursor = db_ue.cargarCursorUEsPadres();
        while(cursor.moveToNext()){
            if(cursor.getString(1).toString().equals(nodo.getNombre().toString()) || cursor.getString(2).toString().equals(nodo.getNombre().toString())){
                long result2 = eliminarPadrePorId(nombre_pr, cursor.getString(0).toString());
                if(result2 == -1){
                    resultado = false;
                }else{

                }
            }
        }

        return resultado;
    }

    /**
     * Método que permite actualizar los datos relacionados con la foto asociada a una UE dada.
     * @param nombre_pr
     * @param nombre_ue
     * @param nombre_foto
     * @param fecha_foto
     * @param uri
     * @return
     */
    public long actualizarFoto(String nombre_pr, String nombre_ue, String nombre_foto, String fecha_foto, String uri){
        String id = null;
        DataBaseManagerUE db_ue = new DataBaseManagerUE(context, nombre_pr);
        Cursor cursor = db_ue.cargarCursorUEs();
        while(cursor.moveToNext()){
            if (cursor.getString(1).toString().equals(nombre_ue)){
                id = cursor.getString(0);
            }
        }
        return db_ue.actualizarFoto(nombre_ue, nombre_foto, fecha_foto, uri, id);
    }

    /**
     * Método que se encarga de actualizar los datos relativos al GPS de una UE dada.
     * @param nombre_pr
     * @param nombre_ue
     * @param punto
     * @return
     */
    public long actualizarGPS(String nombre_pr, String nombre_ue, String punto){
        String id = null;
        DataBaseManagerUE db_ue = new DataBaseManagerUE(context, nombre_pr);
        Cursor cursor = db_ue.cargarCursorUEs();
        while(cursor.moveToNext()){
            if(cursor.getString(1).toString().equals(nombre_ue)){
                id = cursor.getString(0);
            }
        }
        return db_ue.actualizarGPS(nombre_ue, punto, id);
    }

    // </editor-fold>

    /*--------------------------------------------------------------------------------------------*/

    // <editor-fold defaultstate="collapsed" desc="Controlando la Estructura">

    /**
     * Método que se encarga de agregar un nuevo vértice a la estructura.
     * @param nombre_proyecto
     * @param nom_relacion
     * @param nom_ue_central
     * @param padre_hijo
     * @return
     */
    public ArrayList agregarNodoRelacion(String nombre_proyecto, String nom_relacion, String nom_ue_central, int padre_hijo) {

        Boolean encontrado = comprobarExiteUe(nombre_proyecto, nom_relacion);
        if(!encontrado){
            estructura.agregarNodoRelacion(nom_relacion);
        }

        Vertice v1 = obtenerVertice(nombre_proyecto, nom_relacion);
        Vertice v2 = obtenerVertice(nombre_proyecto, nom_ue_central);

        if(padre_hijo == 1) {
            estructura.agregarArista(v1, v2, 1);
        } else {
            estructura.agregarArista(v2, v1, 1);
        }

        ArrayList ciclo = estructura.isCycle(v1);

        return ciclo;
    }

    /**
     * Método que se encarga de cargar la estructura a partir de los datos almacenados en la BBDD
     * correspondiente.
     * @param nombre_pr
     * @return
     */
    public Boolean cargarEstructura(String nombre_pr){

        this.estructura = new Estructura();
        Boolean result = false;
        Cursor cursor_ues = selectCursorUes(nombre_pr);
        ArrayList<String> s = new ArrayList<>();
        while(cursor_ues.moveToNext()){
            String nombre_ue = cursor_ues.getString(1);
            estructura.agregarVertice(nombre_ue);
            s.add(nombre_ue);
        }

        Cursor cursor_padres = selectCursorUesPadres(nombre_pr);
        while(cursor_padres.moveToNext()){

            String padre = cursor_padres.getString(2);
            String hijo = cursor_padres.getString(1);

            Vertice p = estructura.buscarVertice(padre);
            Vertice h = estructura.buscarVertice(hijo);
            estructura.agregarArista(p,h,1);

            for(int i=0; i<s.size();i++){
                if(s.get(i).equals(hijo)){
                    s.remove(i);
                }
            }
        }

        Vertice inicio = estructura.getV_inicio();
        for(int i=0; i<s.size();i++){
            Vertice v = estructura.buscarVertice(s.get(i));
            estructura.agregarArista(inicio,v,1);
        }

      comprobarRedundancia(nombre_pr);

      return result;
    }

    /**
     * Método que se encarga de comprobar si existen redundancias en las relaciones y de ser así
     * eliminarlas.
     * @param nombre_p
     */
    public void comprobarRedundancia(String nombre_p){



        ArrayList<ArrayList> caminos = new ArrayList<>();


        caminos = calcularRedundancias(caminos);
        eliminarRedundancias(caminos, nombre_p);
    }

    /**
     * Método que se encarga de calcular las redundancias.
     * @param caminos
     * @return
     */
    private ArrayList<ArrayList> calcularRedundancias(ArrayList<ArrayList> caminos){

        LinkedList lista_vertices = estructura.getVertices();
        ArrayList paquete = new ArrayList<>();
        ArrayList<String> control = new ArrayList<>();
        ArrayList<String> control2 = new ArrayList<>();

        Vertice v_inicio = new Vertice();
        v_inicio = estructura.getV_inicio();

        for (int i=0;i<lista_vertices.size(); i++){
            Vertice w = (Vertice) lista_vertices.get(i);
            int num_padres = obtenerNumeroPadres(w);
            w.setNum_padres(num_padres);
            w.setState(0);
        }

        Stack stack = new Stack();

        stack.push(v_inicio);
        v_inicio.setState(1);

        while (!stack.isEmpty()) {

            Vertice v = (Vertice) stack.peek();
            Vertice vv = estructura.adyacentesHijosNoVisitadosDesdeVertice(v);

            if(vv != null) {

                vv.setUltimo_padre(v.getElemento().toString());

                control.add(vv.getElemento().toString());
                control2 = (ArrayList<String>) control.clone();
                paquete.add(vv.getElemento().toString());
                paquete.add(control2);
                caminos.add(paquete);

                ArrayList<String> visitados = new ArrayList<>();
                visitados = v.getVisitados();
                visitados.add(vv.getElemento().toString());
                v.setVisitados(visitados);

                stack.push(vv);

            } else {

                Vertice ver = (Vertice) stack.pop();

                for (int i = 0; i < control.size(); i++) {
                    if (control.get(i).equals(ver.getElemento().toString())) {
                        control.remove(control.get(i));
                        ver.setNum_padres(ver.getNum_padres() - 1);
                    }
                }
            }
            paquete=new ArrayList<>();
        }

        return caminos;
    }

    /**
     * Método que se encarga de eliminar las redundancias.
     * @param caminos
     * @param nombre_p
     */
    private void eliminarRedundancias(ArrayList<ArrayList> caminos, String nombre_p){

        for(int i=0;i<caminos.size();i++){
            for(int j=0;j<caminos.size();j++){
                if(caminos.get(i) != caminos.get(j)){
                    if(caminos.get(i).get(0).toString().equals(caminos.get(j).get(0).toString())){
                        ArrayList<String> l_1 = (ArrayList<String>) caminos.get(i).get(1);
                        ArrayList<String> l_2 = (ArrayList<String>) caminos.get(j).get(1);
                        ArrayList<String> lista_no_eliminar = new ArrayList<>();
                        ArrayList<String> lista_eliminar = new ArrayList<>();

                        if(l_1.size() > l_2.size()) {
                            lista_no_eliminar = l_1;
                            lista_eliminar = l_2;
                        }else{
                            lista_no_eliminar = l_2;
                            lista_eliminar = l_1;
                        }

                        Boolean contiene = true;
                        Boolean encontrado;
                        for(int kk=0; kk<lista_eliminar.size();kk++) {
                            encontrado = false;
                            for (int k = 0; k < lista_no_eliminar.size(); k++) {
                                if (lista_eliminar.get(kk).toString().equals(lista_no_eliminar.get(k).toString())) {
                                    encontrado= true;
                                }
                            }
                            if(!encontrado){
                                contiene = false;
                            }
                        }
                        if(contiene){
                            String v1_eliminar="";
                            String v2_eliminar="";
                            Boolean en = false;
                            int cont_no_eli = lista_no_eliminar.size()-1;
                            int cont_eli = lista_eliminar.size()-1;

                            while(!en){
                                if(!lista_eliminar.get(cont_eli).equals(lista_no_eliminar.get(cont_no_eli))) {
                                    v2_eliminar = lista_eliminar.get(cont_eli + 1);
                                    en = true;
                                }else{
                                    cont_eli--;
                                    cont_no_eli--;
                                }
                            }

                            Boolean enc = false;
                            int cont_eli2 = 0;
                            int cont_no_eli2 = 0;
                            while(!enc){
                                if(!lista_eliminar.get(cont_eli2).equals(lista_no_eliminar.get(cont_no_eli2))) {
                                    v1_eliminar = lista_eliminar.get(cont_eli2-1);
                                    enc=true;
                                }else{
                                    cont_eli2++;
                                    cont_no_eli2++;
                                }
                            }

                            eliminarArista(nombre_p, v1_eliminar, v2_eliminar);
                        }
                    }
                }
            }
        }
    }

    /**
     * Método que se encarga de obtener el número de padres de un vértice.
     * @param v
     * @return
     */
    public int obtenerNumeroPadres(Vertice v){

        LinkedList padres_directos = new LinkedList();
        padres_directos = estructura.adyacentesPadres(v);
        int num_padres = padres_directos.size();

        return num_padres;
    }

    /**
     * Método que se encarga de obtener en un LinkedList el conjunto de aristas de la estructura.
     * @return
     */
    public LinkedList obtenerAristas(){
        return estructura.getAristas();
    }

    /**
     * Método que se encarga de obtener en un LinkedList el conjunto de vértices de la estructura.
     * @return
     */
    public LinkedList obtenerVertices(){
        return estructura.getVertices();
    }

    /**
     * Método que se encarga de obtener un vértice a partir de su nombre.
     * @param nombre_p
     * @param nom_v
     * @return
     */
    public Vertice obtenerVertice(String nombre_p, String nom_v){
        LinkedList vertices = estructura.getVertices();
        for(int i=0;i<vertices.size();i++){
            Vertice v = (Vertice) vertices.get(i);
            if(v.getElemento().toString().equals(nom_v)){
                return v;
            }
        }
        return null;
    }

    /**
     * Método que se encarga de obtener los vértices adyacentes de un vértice dado.
     * @param nombre_p
     * @param nombre_v
     * @return
     */
    public LinkedList obtenerAdyacentes(String nombre_p, String nombre_v){
        Vertice v = estructura.buscarVertice(nombre_v);
        LinkedList v_adyacentes = estructura.adyacentesVertice(v);
        return v_adyacentes;
    }

    /**
     * Método que se encarga de eliminar una arista de la estructura.
     * @param nombre
     * @param nombre_actual
     * @param nombre_hijo
     */
    public void eliminarArista(String nombre, String nombre_actual, String nombre_hijo) {
        for(int i=0;i<estructura.getAristas().size();i++){
            Arista a = (Arista) estructura.getAristas().get(i);
            Vertice v1 = a.getV1();
            Vertice v2 = a.getV2();

            if(a.getV1().getElemento().toString().equals(nombre_actual) && a.getV2().getElemento().toString().equals(nombre_hijo)){
                estructura.borrarArista(a);
            }
        }
    }

    /**
     * Método que se encarga de calcular los momentos.
     * @return
     */
    public ArrayList<ArrayList> obtenerMomentos(){

        ArrayList<ArrayList> momentos = new ArrayList<>();
        ArrayList<String> momento = new ArrayList<>();
        ArrayList<Integer> grados = new ArrayList<>(); // Se utiliza para saber si ya existe un array para ese grado.
        ArrayList<Integer> grado = new ArrayList<>();
        ArrayList<ArrayList> momento_grado = new ArrayList<>();

        grados.add(0);
        grado.add(0);
        momento.add(estructura.getV_inicio().getElemento().toString());
        momento_grado.add(grado);
        momento_grado.add(momento);
        momentos.add(momento_grado);

        LinkedList vertices_ll = estructura.getVertices();
        ArrayList vertices = new ArrayList();
        for(int i=0;i<vertices_ll.size();i++){
            vertices.add(vertices_ll.get(i));
        }

        for(int i = 1; i<vertices.size(); i++){
            Vertice v = (Vertice) vertices.get(i);
            int grado_v = estructura.encontrarGrado(v);

            if(comprobarSiEsta(grados, grado_v)){
                for(int j=0; j<momentos.size();j++){
                    ArrayList g = (ArrayList) momentos.get(j).get(0);
                    if(g.get(0) == grado_v){
                        ArrayList m = (ArrayList) momentos.get(j).get(1);
                         momentos.get(j).remove(1);
                        m.add(v.getElemento().toString());
                        momentos.get(j).add(m);
                    }
                }

            }else{
                grados.add(grado_v);
                grado = new ArrayList<>();
                grado.add(grado_v);

                momento=new ArrayList<>();
                momento.add(v.getElemento().toString());
                momento_grado = new ArrayList<>();
                momento_grado.add(grado);
                momento_grado.add(momento);
                momentos.add(momento_grado);
            }
        }

        return momentos;
    }

    /**
     * Método que se encarga de comprobar si hay un Array creado para un grado dado.
     * @param a
     * @param n
     * @return
     */
    public Boolean comprobarSiEsta(ArrayList<Integer> a, int n){

        Boolean encontrado = false;
        for(int i = 0; i < a.size(); i++){
            if(a.get(i) == n){
                encontrado = true;
            }
        }

        return encontrado;
    }

    /**
     * Método que se encarga de obtener todos los parentescos de una UE a partir de su nombre.
     * @param nombre_ue
     * @return
     */
    public ArrayList<String> obtenerTodosParentescos(String nombre_ue){

        ArrayList<String> hijos = estructura.obtenerTodosHijos(nombre_ue);
        ArrayList<String> padres = estructura.obtenerTodosPadres(nombre_ue);

        for(int i=0;i<padres.size();i++){
            hijos.add(padres.get(i)); // Se juntan los dos arrays en uno (ya que es pintar todos de rojo
        }

        return hijos;
    }

    /**
     * Método que se encarga de obtener los hijos no visitados de un vértice.
     * @param v
     * @return
     */
    public Vertice obtenerAdyacentesHijosNoVisitados(Vertice v) {
        return estructura.adyacentesHijosNoVisitados(v);
    }

    /**
     * Método que permite obtener el vértice o nodo raíz.
     * @return
     */
    public Vertice obtenerVerticeInicio() {
        return estructura.getV_inicio();
    }

    // </editor-fold>

    /*--------------------------------------------------------------------------------------------*/

    // <editor-fold defaultstate="collapsed" desc="Getters and Setters">

    public String getUe_seleccionada() {
        return ue_seleccionada;
    }

    public void setUe_seleccionada(String ue_seleccionad) {
        this.ue_seleccionada = ue_seleccionad;
    }

    public ArrayList getMedidasPantalla() {
        return medidasPantalla;
    }

    public void setMedidasPantalla(ArrayList medidasPantalla) {
        this.medidasPantalla = medidasPantalla;
    }

    public String getUe_seleccionada_grafo() {
        return ue_seleccionada_grafo;
    }

    public void setUe_seleccionada_grafo(String ue_seleccionada_grafo) {
        this.ue_seleccionada_grafo = ue_seleccionada_grafo;
    }

    public String getUe_seleccionada_diario() {
        return ue_seleccionada_diario;
    }

    public void setUe_seleccionada_diario(String ue_seleccionada_diario) {
        this.ue_seleccionada_diario = ue_seleccionada_diario;
    }

    public String getUe_seleccionada_tabla() {
        return ue_seleccionada_tabla;
    }

    public void setUe_seleccionada_tabla(String ue_seleccionada_tabla) {
        this.ue_seleccionada_tabla = ue_seleccionada_tabla;
    }

    // </editor-fold>

    /*--------------------------------------------------------------------------------------------*/

}
