package com.example.unodtantos.appqueology2.controlador;

import android.annotation.TargetApi;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.graphics.Color;
import android.graphics.Typeface;
import android.graphics.drawable.ColorDrawable;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup.LayoutParams;
import android.widget.Button;
import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;

import com.example.unodtantos.appqueology2.R;
import com.example.unodtantos.appqueology2.modelo.Nodo;

import java.util.ArrayList;


/**
 * Created by unodtantos on 09/03/2015.
 */
public class AreaTrabajoActual extends Activity {

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

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

    protected  static final int REQUEST_CODE_1 = 10;
    protected  static final int REQUEST_CODE_2 = 100;
    protected  static final int REQUEST_CODE_3 = 1000;
    protected  static final int REQUEST_CODE_4 = 10000;

    private Controlador controlador;
    private String nombre_proyecto;
    private String nombre_ue_actual;
    private FragmentMenuAnimado menu_animado;

    private ArrayList<Button> lista_btns_padres;
    private Button btn_central;
    private ArrayList<Button> lista_btns_hijos;

    private Context context;
    private Typeface font;

    // </editor-fold>

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

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

    /**
     * Constructor de la clase.
     * @param savedInstanceState
     */
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_area_trabajo);

        inicializacionVariables();
        inicializacionMenuAnimado(savedInstanceState);
        alertInstrucciones();

        final Handler handler = new Handler();  //Para lanzar el metodo tras 1 seg.
        handler.postDelayed(new Runnable() {
            @Override
            public void run() {
                menu_animado.abrirSubmenus(true);
            }
        }, 1000);
    }

    // </editor-fold>

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

    // <editor-fold defaultstate="collapsed" desc="Inicializacion">

    /**
     * Método que permite inicializar el fragment que representa el menu animado.
     * @param savedInstanceState
     */
    private void inicializacionMenuAnimado(Bundle savedInstanceState){

        if (savedInstanceState == null) {
            getFragmentManager().beginTransaction()
                    .add(R.id.container, this.menu_animado)
                    .commit();
        }
    }

    /**
     * Método que permite modificar el aspecto de las variables necesarias para el correcto
     * funcionamiento de la clase.
     */
    private void inicializacionVariables(){

        this.controlador = (Controlador) getApplicationContext();
        this.context = this;
        this.nombre_proyecto = getIntent().getExtras().getString("nombre_proyecto");
        this.nombre_ue_actual = "";
        this.menu_animado = new FragmentMenuAnimado();
        this.menu_animado.setContext(context);
        this.menu_animado.setNombre_proyecto(nombre_proyecto);
        this.menu_animado.setUe_actual("");
        this.lista_btns_padres = new ArrayList<>();
        this.btn_central = new Button(getApplicationContext());
        this.lista_btns_hijos = new ArrayList<>();
        this.font = Typeface.createFromAsset(getAssets(), "gloriahallelujah.ttf");

    }

    // </editor-fold>

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

    // <editor-fold defaultstate="collapsed" desc="Capturando eventos">

    /**
     * Capturando evento onClick para crear una nueva relación de anterioridad.
     * @param view
     */
    public void onClickBotonNuevoPadre(View view){
        alertAsignarNombreUeRelacion(1);
        menu_animado.cerrarSubmenus(true);
    }

    /**
     * Capturando evento onClick para crear una nueva relación posterior.
     * @param view
     */
    public void onClickBotonNuevoHijo(View view){
        alertAsignarNombreUeRelacion(2);
        menu_animado.cerrarSubmenus(true);
    }

    /**
     * Capturando evento onClick para crear una nueva UE.
     * @param view
     */
    public void onClickBotonNuevoNodoCentral(View view){
        alertAgregarNodoCentral();
        menu_animado.cerrarSubmenus(true);
    }

    /**
     * Capturando evento onClick que permite modificar los datos de la UE cargada y con la que se
     * pretende trabajar.
     * @param btn
     */
    public void capturarEventoBtnNodoCentral(Button btn){
        btn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent = new Intent(getApplicationContext(), DatosNodoCentral.class);
                intent.putExtra("nombre_ue", btn_central.getText().toString());
                intent.putExtra("nombre_bd", nombre_proyecto);
                startActivityForResult(intent, REQUEST_CODE_1);
            }
        });
    }

    /**
     * Capturando evento onClick del botón que permite buscar una UE y cargarla así como todas
     * sus relaciones.
     * @param view
     */
    public void onClickBotonIrUe(View view){
        alertIrUe();
        menu_animado.cerrarSubmenus(true);
    }


    /**
     * Método que permite capturar el evento onLongClick y que permite eliminar una relación de
     * anterioridad o posterior.
     * @param btn
     * @param padre_hijo
     */
    public void capturarEventoBtnRelacionOnLongClick(Button btn, final int padre_hijo){
        btn.setOnLongClickListener(new View.OnLongClickListener() {
            @Override
            public boolean onLongClick(final View v) {
                alertConfirmacionEliminarRelacion(v, padre_hijo);
                return false;
            }
        });
    }

    /**
     * Capturando el evento onClick de alguna de las relaciones de anterioridad o posterior.
     * Permite cargar dicha UE en el nodo central, para poder trabajar con ella.
     * @param btn
     */
    public void capturarEventoBtnRelacionOnClick(final Button btn){
        btn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                irUE(btn.getText().toString());
            }
        });
    }

    /**
     * Método que permite capturar el evento onClick del botón que muestra las instrucciones de
     * uso de la vista Área de Trabajo.
     * @param alertDialog
     * @param promptsView
     */
    public void capturaEventoBtnAlertInstrucciones(final AlertDialog alertDialog, View promptsView){

        Button btn = (Button) promptsView.findViewById(R.id.btn_alert_instrucciones_aceptar);
        btn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if(nombre_ue_actual.isEmpty()) {
                    deshabilitarVistaotonesPadresHijos();
                }
                if(btn_central != null) {
                    String nnn = (String) btn_central.getText();
                    if (!nnn.isEmpty()) {
                        menu_animado.cerrarSubmenus(true);
                    }
                }
                alertDialog.dismiss();
            }
        });
    }

    // </editor-fold>

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

    // <editor-fold defaultstate="collapsed" desc="Alerts">

    /**
     * Método que configura el comportamiento del Alert que permite mostrar las instrucciones de
     * uso de la vista Área de Trabajo.
     */
    public void alertInstrucciones(){

        LayoutInflater li = LayoutInflater.from(context);
        final View promptsView = li.inflate(R.layout.activity_dialogo_instrucciones_area_trabajo, null);

        AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(context);
        alertDialogBuilder.setView(promptsView);

        AlertDialog alertDialog = alertDialogBuilder.create();
        alertDialog.show();

        capturaEventoBtnAlertInstrucciones(alertDialog, promptsView);

        aspectoAlertInstrucciones(alertDialog, promptsView);
    }

    /**
     * Método que configura el Alert que permite agregar una nueva UE.
     */
    private void alertAgregarNodoCentral(){

        LayoutInflater li = LayoutInflater.from(context);
        final View promptsView = li.inflate(R.layout.activity_dialogo_nueva_ue_central, null);

        AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(context);
        alertDialogBuilder.setView(promptsView);

        alertDialogBuilder
                .setCancelable(false)
                .setPositiveButton("Aceptar", new DialogInterface.OnClickListener() {
                    @TargetApi(Build.VERSION_CODES.JELLY_BEAN)
                    public void onClick(DialogInterface dialog, int whichButton) {

                        EditText etxt_nom_ue = (EditText) promptsView.findViewById(R.id.etxt_nombre_ue_central);
                        String nom_ue = etxt_nom_ue.getText().toString();

                        if (!nom_ue.isEmpty()) {
                            Boolean encontrado = controlador.comprobarExiteUe(nombre_proyecto, nom_ue);
                            if (encontrado) {
                                Toast.makeText(getApplicationContext(), "Lo siento, ya existe una UE con ese nombre, no pueden crearse duplicados. Inténtalo con otro nombre.", Toast.LENGTH_LONG).show();
                            } else {
                                long result = controlador.insertarUeActual(nombre_proyecto, nom_ue);
                                if (result != -1) {
                                    crearNodoCentralVista(nom_ue);
                                } else {
                                    Toast.makeText(getApplicationContext(), "Lo siento, se ha producido un error a la hora de guardar la UE.", Toast.LENGTH_LONG).show();
                                }
                            }
                        } else {
                            Toast.makeText(getApplicationContext(), "No se creo la UE, ya que no has introducido su nombre.", Toast.LENGTH_LONG).show();
                        }
                    }
                })
                .setNegativeButton("Cancelar", new DialogInterface.OnClickListener() {
                    public void onClick(DialogInterface dialog, int whichButton) {
                        dialog.cancel();
                    }
                });

        AlertDialog alertDialog = alertDialogBuilder.create();
        alertDialog.show();

        aspectoAlertAgregarNodoCentral(alertDialog, promptsView);
    }

    /**
     * Método que configura el Alert que permite crear una nueva relación tanto de anterioridad
     * como posterior.
     * @param padre_hijo
     */
    private void alertAsignarNombreUeRelacion(final int padre_hijo) {

        LayoutInflater li = LayoutInflater.from(context);
        final View promptsView = li.inflate(R.layout.activity_dialogo_nueva_relacion, null);

        AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(context);
        alertDialogBuilder.setView(promptsView);

        alertDialogBuilder
                .setCancelable(false)
                .setPositiveButton(" Aceptar ", new DialogInterface.OnClickListener() {
                    public void onClick(DialogInterface dialog, int id) {

                        EditText etxt_nom_ue_relacion = (EditText) promptsView.findViewById(R.id.etxt_nombre_ue_relacion);
                        String nom_ue_relacion = etxt_nom_ue_relacion.getText().toString();

                        if (nom_ue_relacion.isEmpty()) {
                            Toast.makeText(getApplicationContext(), "No se puede crear una relación ya que no has introducido su nombre.", Toast.LENGTH_LONG).show();
                        } else {
                            String nom_ue_central = btn_central.getText().toString();
                            if (nom_ue_relacion.equals(nom_ue_central)) {
                                Toast.makeText(getApplicationContext(), "La UE central tiene el mismo nombre que la relación que quieres crear. Lo siento, dicha accion no se puede realizar.", Toast.LENGTH_LONG).show();
                            } else {
                                ArrayList result = controlador.agregarNodoRelacion(nombre_proyecto, nom_ue_relacion, nom_ue_central, padre_hijo); // Se comprueba si crea ciclo
                                Boolean ciclo = (Boolean) result.get(0);
                                if (!ciclo) {
                                    Boolean encontrado = controlador.comprobarExiteUe(nombre_proyecto, nom_ue_relacion); //Se inserta en la BBDD si es necesario
                                    if (!encontrado) {
                                        long resultado = controlador.insertarUeActual(nombre_proyecto, nom_ue_relacion);
                                        if (resultado == -1) {
                                            Toast.makeText(getApplicationContext(), "Lo siento, se ha producido un error al guardar los datos.", Toast.LENGTH_LONG).show();
                                        } else {
                                            agregarParentescoVista(padre_hijo, nom_ue_relacion); // Muestra la rellacion en la vista
                                        }
                                    } else {
                                        agregarParentescoVista(padre_hijo, nom_ue_relacion); // Muestra la rellacion en la vista
                                    }
                                } else {
                                    Toast.makeText(getApplicationContext(), "Atencion, esta relacion crea un ciclo.", Toast.LENGTH_LONG).show();
                                    Toast.makeText(getApplicationContext(), "Los nodos implicados son: " + result.get(1).toString(), Toast.LENGTH_LONG).show();
                                }
                            }
                        }
                    }
                })
                .setNegativeButton("Cancelar", new DialogInterface.OnClickListener() {
                    public void onClick(DialogInterface dialog, int id) {
                        dialog.cancel();
                    }
                });

        AlertDialog alertDialog = alertDialogBuilder.create();
        alertDialog.show();

        aspectoAlertNombreUeRelacion(alertDialog, promptsView);
    }

    /**
     * Método que configura el Alert que permite cargar una UE y sus relaciones en la vista
     * Área de Trabajo.
     */
    private void alertIrUe(){

        LayoutInflater li = LayoutInflater.from(context);
        final View promptsView = li.inflate(R.layout.activity_dialogo_buscar_ue, null);

        AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(context);
        alertDialogBuilder.setView(promptsView);

        alertDialogBuilder
                .setCancelable(false)
                .setPositiveButton(" Aceptar ", new DialogInterface.OnClickListener() {
                    public void onClick(DialogInterface dialog, int id) {

                        EditText etxt_nombre = (EditText) promptsView.findViewById(R.id.etxt_nombre_ue_buscar);
                        String nombre_ue = etxt_nombre.getText().toString();

                        if (nombre_ue.isEmpty()) {
                            Toast.makeText(getApplicationContext(), "No se te puede mostrar la UE que buscas ya que no has introducido su nombre.", Toast.LENGTH_LONG).show();
                        } else {
                            Boolean encontrado = controlador.comprobarExiteUe(nombre_proyecto, nombre_ue);
                            if (encontrado) {
                                irUE(nombre_ue);
                            } else {
                                Toast.makeText(getApplicationContext(), "Lo siento, esa UE no existe!, trata de intentarlo con otra", Toast.LENGTH_LONG).show();
                            }
                        }
                    }
                })
                .setNegativeButton("Cancelar", new DialogInterface.OnClickListener() {
                    public void onClick(DialogInterface dialog, int id) {
                        dialog.cancel();
                    }
                });

        AlertDialog alertDialog = alertDialogBuilder.create();
        alertDialog.show();

        aspectoAlertIrUe(alertDialog, promptsView);
    }

    /**
     * Método que configura el Alert que pide la confirmación del usuario de que realmente desea
     * modificar los datos de la UE cargada en el nodo central de la vista Área de Trabajo.
     * @param nom_ue_central_nueva
     * @param datos_ue
     */
    private void alertConfirmacionModificarUe(final String nom_ue_central_nueva, final Nodo datos_ue){

        LayoutInflater li = LayoutInflater.from(context);
        View promptsView = li.inflate(R.layout.activity_dialogo_confirmar_cambiar_nombre_ue, null);

        AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(context);
        alertDialogBuilder.setView(promptsView);

        alertDialogBuilder
                .setCancelable(false)
                .setPositiveButton(" Aceptar ", new DialogInterface.OnClickListener() {
                    public void onClick(DialogInterface dialog, int id) {
                        long eliminado = controlador.eliminarUePorNombre(nombre_proyecto, nombre_ue_actual);
                        if (eliminado != -1) {
                            long insertado = controlador.insertarUeActual(nombre_proyecto, nom_ue_central_nueva);
                            if (insertado != -1) {
                                long actualizado = controlador.actualizarDatosUeCentral2(nombre_proyecto, datos_ue);
                                if (actualizado == -1) {
                                    Toast.makeText(getApplicationContext(), "Lo siento, se ha producido un error al actulizar los datos. Hay inconsistencias en el proyecto.", Toast.LENGTH_LONG).show();
                                } else {
                                    Boolean result = controlador.actualizarPadres(nombre_proyecto, nombre_ue_actual, nom_ue_central_nueva);
                                    if (result) {
                                        acciones(nom_ue_central_nueva);
                                    } else {
                                        Toast.makeText(getApplicationContext(), "Lo siento, se ha producido un error al actulizar los datos. Hay inconsistencias en el proyecto.", Toast.LENGTH_LONG).show();
                                    }
                                }
                            } else {
                                Toast.makeText(getApplicationContext(), "Lo siento, se ha producido un error al actulizar los datos. Hay inconsistencias en el proyecto.", Toast.LENGTH_LONG).show();
                            }
                        } else {
                            Toast.makeText(getApplicationContext(), "Lo siento, se ha producido un error al actulizar los datos.", Toast.LENGTH_LONG).show();
                        }
                    }
                })
                .setNegativeButton("Cancelar", new DialogInterface.OnClickListener() {
                    public void onClick(DialogInterface dialog, int id) {
                        dialog.cancel();
                    }
                });

        AlertDialog alertDialog = alertDialogBuilder.create();
        alertDialog.show();

        aspectoAlertConfirmarModificar(alertDialog, promptsView);
    }

    /**
     * Método que configura el Alert que pide la confirmación del usuario para eliminar una relación.
     * @param v
     * @param padre_hijo
     */
    private void alertConfirmacionEliminarRelacion(final View v, final int padre_hijo){

        LayoutInflater li = LayoutInflater.from(context);
        View promptsView = li.inflate(R.layout.activity_dialogo_confirmar_eliminar_relacion, null);

        AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(context);
        alertDialogBuilder.setView(promptsView);

        alertDialogBuilder
                .setCancelable(false)
                .setPositiveButton("Aceptar", new DialogInterface.OnClickListener() {
                    public void onClick(DialogInterface dialog, int whichButton) {
                        eliminarParentescoVista(v, padre_hijo);
                    }
                })

                .setNegativeButton("Cancelar", new DialogInterface.OnClickListener() {
                    public void onClick(DialogInterface dialog, int whichButton) {
                        dialog.cancel();
                    }
                });

        AlertDialog alertDialog = alertDialogBuilder.create();
        alertDialog.show();

        aspectoAlertConfirmarEliminar(alertDialog, promptsView);
    }

    /**
     * Método que configura el Alert que muestra la información de la última UE y relación
     * almacenada en la Base de Datos correspondiente.
     */
    public void alertUltimaUe(){

        LayoutInflater li = LayoutInflater.from(context);
        final View promptsView = li.inflate(R.layout.activity_dialogo_ultima_ue, null);

        AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(context);
        alertDialogBuilder.setView(promptsView);

        final ArrayList<String> datos_ue = controlador.selectUltimaUe(nombre_proyecto);
        TextView txt_nom_ue = (TextView) promptsView.findViewById(R.id.textView29);
        TextView txt_fecha_ue = (TextView) promptsView.findViewById(R.id.textView30);
        if (datos_ue.size() == 0) {
            txt_nom_ue.setText("Ninguna UE creada.");
            txt_fecha_ue.setText("---");
        } else {
            txt_nom_ue.setText(datos_ue.get(0));
            txt_fecha_ue.setText(datos_ue.get(1));
        }

        final ArrayList<String> datos_relacion = controlador.selectUltimaRelacion(nombre_proyecto);
        TextView txt_nom_relacion = (TextView) promptsView.findViewById(R.id.textView32);
        if(datos_relacion.size()==0){
            txt_nom_relacion.setText("Ninguna relación creada.");
        } else {
            txt_nom_relacion.setText(datos_relacion.get(0));
        }

        alertDialogBuilder
                .setCancelable(false)
                .setPositiveButton("Aceptar", new DialogInterface.OnClickListener() {
                    public void onClick(DialogInterface dialog, int whichButton) {
                        dialog.cancel();
                    }
                });

        AlertDialog alertDialog = alertDialogBuilder.create();
        alertDialog.show();

        aspectoAlertUltimaUe(alertDialog, promptsView);
    }

        // </editor-fold>

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

    // <editor-fold defaultstate="collapsed" desc="Aspecto Alerts">

    /**
     * Método que configura el aspecto del Alert que muestra las instrucciones de uso de la vista
     * Área de Trabajo.
     * @param alertDialog
     * @param promptsView
     */
    private void aspectoAlertInstrucciones(AlertDialog alertDialog, View promptsView){

        alertDialog.getWindow().setBackgroundDrawable(new ColorDrawable(android.graphics.Color.TRANSPARENT));

        TextView nueva_ue = (TextView) promptsView.findViewById(R.id.textView2);
        TextView buscar_ue = (TextView) promptsView.findViewById(R.id.textView);
        TextView nueva_relacion = (TextView) promptsView.findViewById(R.id.textView3);
        TextView menu_desplegable = (TextView) promptsView.findViewById(R.id.textView4);
        TextView diario = (TextView) promptsView.findViewById(R.id.textView5);
        TextView grafo = (TextView) promptsView.findViewById(R.id.textView6);
        TextView tabla = (TextView) promptsView.findViewById(R.id.textView7);
        TextView ultima_inserc = (TextView) promptsView.findViewById(R.id.textView25);
        TextView limpiar = (TextView) promptsView.findViewById(R.id.textView33);
        TextView info = (TextView) promptsView.findViewById(R.id.textView24);
        nueva_ue.setTypeface(this.font);
        buscar_ue.setTypeface(this.font);
        nueva_relacion.setTypeface(this.font);
        menu_desplegable.setTypeface(this.font);
        diario.setTypeface(this.font);
        grafo.setTypeface(this.font);
        tabla.setTypeface(this.font);
        ultima_inserc.setTypeface(this.font);
        limpiar.setTypeface(this.font);
        info.setTypeface(this.font);
        nueva_ue.setTextColor(Color.WHITE);
        buscar_ue.setTextColor(Color.WHITE);
        nueva_relacion.setTextColor(Color.WHITE);
        menu_desplegable.setTextColor(Color.WHITE);
        diario.setTextColor(Color.WHITE);
        grafo.setTextColor(Color.WHITE);
        tabla.setTextColor(Color.WHITE);
        ultima_inserc.setTextColor(Color.WHITE);
        limpiar.setTextColor(Color.WHITE);
        info.setTextColor(Color.WHITE);

        aspectoBotonInstrucciones(promptsView);
    }

    /**
     * Método que configura el Alert que se lanza cuando el usuario clica el botón que permite
     * crear una nueva UE y cargarla en el nodo central de la vista Área de Trabajo.
     * @param alertDialog
     * @param promptsView
     */
    private void aspectoAlertAgregarNodoCentral(AlertDialog alertDialog, View promptsView){

        alertDialog.getWindow().setBackgroundDrawable(new ColorDrawable(android.graphics.Color.TRANSPARENT));

        TextView titulo = (TextView) promptsView.findViewById(R.id.fuente17);
        TextView mensaje = (TextView) promptsView.findViewById(R.id.fuente18);
        titulo.setTypeface(this.font);
        mensaje.setTypeface(this.font);

        aspectoBotonesPosNeg(alertDialog);
    }

    /**
     * Método que configura el Alert que se muestra cuando el usuario pretende agregar una nueva
     * realción.
     * @param alertDialog
     * @param promptsView
     */
    private void aspectoAlertNombreUeRelacion(AlertDialog alertDialog, View promptsView){

        alertDialog.getWindow().setBackgroundDrawable(new ColorDrawable(android.graphics.Color.TRANSPARENT));

        TextView titulo = (TextView) promptsView.findViewById(R.id.titulo);
        TextView nom = (TextView) promptsView.findViewById(R.id.fuente16);
        titulo.setTypeface(this.font);
        nom.setTypeface(this.font);

        aspectoBotonesPosNeg(alertDialog);
    }

    /**
     * Método que permite configurar el aspecto del Alert que permite buscar y cargar una nueva UE
     * en el nodo central de la vista Área de Trabajo.
     * @param alertDialog
     * @param promptsView
     */
    private void aspectoAlertIrUe(AlertDialog alertDialog, View promptsView){

        alertDialog.getWindow().setBackgroundDrawable(new ColorDrawable(android.graphics.Color.TRANSPARENT));

        TextView titulo = (TextView) promptsView.findViewById(R.id.fuente19);
        TextView nom_ue = (TextView) promptsView.findViewById(R.id.fuente20);
        titulo.setTypeface(this.font);
        nom_ue.setTypeface(this.font);

        aspectoBotonesPosNeg(alertDialog);
    }

    /**
     * Método que permite configurar el aspecto del Alert que pide la confirmación al usuario de que
     * realmente desea modificar los datos de la UE cargada en el nodo central de la vista
     * Área de Trabajo.
     * @param alertDialog
     * @param promptsView
     */
    private void aspectoAlertConfirmarModificar(AlertDialog alertDialog, View promptsView){

        alertDialog.getWindow().setBackgroundDrawable(new ColorDrawable(android.graphics.Color.TRANSPARENT));

        TextView titulo = (TextView) promptsView.findViewById(R.id.fuente22);
        TextView nom = (TextView) promptsView.findViewById(R.id.fuente23);
        titulo.setTypeface(this.font);
        nom.setTypeface(this.font);

        aspectoBotonesPosNeg(alertDialog);
    }

    /**
     * Método que permite modificar el aspecto del Alert que pide la confirmación al usuario de que
     * realmente desea eliminar una relación.
     * @param alertDialog
     * @param promptsView
     */
    private void aspectoAlertConfirmarEliminar(AlertDialog alertDialog, View promptsView){

        alertDialog.getWindow().setBackgroundDrawable(new ColorDrawable(android.graphics.Color.TRANSPARENT));

        TextView titulo = (TextView) promptsView.findViewById(R.id.fuente20);
        TextView mensaje = (TextView) promptsView.findViewById(R.id.fuente21);
        titulo.setTypeface(this.font);
        mensaje.setTypeface(this.font);

        aspectoBotonesPosNeg(alertDialog);
    }

    /**
     * Método que permite configurar el aspecto del Alert que muestra la información de la última
     * UE y relación almacenada en la base de datos correspondiente.
     * @param alertDialog
     * @param promptsView
     */
    private void aspectoAlertUltimaUe(AlertDialog alertDialog, View promptsView){

        alertDialog.getWindow().setBackgroundDrawable(new ColorDrawable(android.graphics.Color.TRANSPARENT));

        TextView txt_t = (TextView) promptsView.findViewById(R.id.textView26);
        TextView txt_nom_ue_t = (TextView) promptsView.findViewById(R.id.textView27);
        TextView txt_fecha_ue_t = (TextView) promptsView.findViewById(R.id.textView28);
        TextView txt_nom_relacion_t = (TextView) promptsView.findViewById(R.id.textView31);
        TextView txt_nom_ue = (TextView) promptsView.findViewById(R.id.textView29);
        TextView txt_fecha_ue = (TextView) promptsView.findViewById(R.id.textView30);
        TextView txt_nom_relacion = (TextView) promptsView.findViewById(R.id.textView32);
        txt_t.setTypeface(this.font);
        txt_nom_ue_t.setTypeface(this.font);
        txt_fecha_ue_t.setTypeface(this.font);
        txt_nom_relacion_t.setTypeface(this.font);
        txt_nom_ue.setTypeface(this.font);
        txt_fecha_ue.setTypeface(this.font);
        txt_nom_relacion.setTypeface(this.font);

        aspectoBotonesPosNeg(alertDialog);
    }

    /**
     * Método que permite configurar el aspecto de los botones "Aceptar" y "Cancelar" de los Alerts
     * descritos anteriormente.
     * @param alertDialog
     */
    private void aspectoBotonesPosNeg(AlertDialog alertDialog){

        Button btn_cancelar = alertDialog.getButton(DialogInterface.BUTTON_NEGATIVE);
        Button btn_aceptar = alertDialog.getButton(DialogInterface.BUTTON_POSITIVE);

        if(btn_cancelar != null && btn_aceptar != null){

            btn_aceptar.setBackgroundDrawable(getResources().getDrawable(R.drawable.dialog_button_selector));
            btn_aceptar.setTextColor(Color.WHITE);
            btn_aceptar.setTypeface(this.font);
            btn_cancelar.setBackgroundDrawable(getResources().getDrawable(R.drawable.dialog_button_selector));
            btn_cancelar.setTextColor(Color.WHITE);
            btn_cancelar.setTypeface(this.font);

            LinearLayout.LayoutParams params = (LinearLayout.LayoutParams) btn_aceptar.getLayoutParams();
            params.setMargins(20, 0, 0, 0);
            btn_aceptar.setLayoutParams(params);
        }
    }

    /**
     * Método que permite configurar el aspecto del botón "Aceptar" del Alert que muestra las
     * instrucciones de uso de la vista Área de Trabajo.
     * @param promptsView
     */
    private void aspectoBotonInstrucciones (View promptsView){

        Button btn = (Button) promptsView.findViewById(R.id.btn_alert_instrucciones_aceptar);
        btn.setBackgroundDrawable(getResources().getDrawable(R.drawable.dialog_button_selector));
        btn.setTextColor(Color.WHITE);
        btn.setTypeface(this.font);
    }

    // </editor-fold>

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

    // <editor-fold defaultstate="collapsed" desc="Agregar padres, central e hijos a la vista">

    /**
     * Método que realiza las acciones pertinentes para añadir una nueva UE en el nodo central
     * de la vista Área de Trabajo.
     * @param nom_ue_nodo_central
     */
    private void crearNodoCentralVista(String nom_ue_nodo_central){

        vaciarPantallaTrabajo();

        Button btn = crearBoton(nom_ue_nodo_central);

        capturarEventoBtnNodoCentral(btn);

        LinearLayout lnly = (LinearLayout) findViewById(R.id.lnlh_2);
        LayoutParams lp = new LayoutParams(250, 250);
        lnly.addView(btn, lp);

        this.btn_central = btn;
        this.nombre_ue_actual = nom_ue_nodo_central;
        menu_animado.setUe_actual(nom_ue_nodo_central);

        controlador.cargarEstructura(nombre_proyecto);
        habilitarVistaBotonesPadresHijos();
    }

    /**
     * Método que realiza las acciones pertinentes para añadir una nueva relación de anterioridad
     * o posterior.
     * @param padre_hijo
     * @param nombre_ue
     */
    private void agregarParentescoVista(int padre_hijo, String nombre_ue){

        Button btn = crearBoton(nombre_ue);

        // Se captura el evento del boton
        capturarEventoBtnRelacionOnLongClick(btn, padre_hijo);
        capturarEventoBtnRelacionOnClick(btn);

        LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(LayoutParams.WRAP_CONTENT,LayoutParams.WRAP_CONTENT);
        LinearLayout lnly;

        if(padre_hijo == 1){
            params.setMargins(20, 20, 0, 0);
            lnly = (LinearLayout) findViewById(R.id.lnlh_1);
            lista_btns_padres.add(btn);
        }else{
            params.setMargins(20,0,0,20);
            lnly = (LinearLayout) findViewById(R.id.lnlh_3);
            lista_btns_hijos.add(btn);
        }
        btn.setLayoutParams(params);
        lnly.addView(btn);

        insertarParentescoBBDD(padre_hijo, nombre_ue);
    }

    /**
     * Método que realiza las acciones pertinentes para agregar todas las relaciones de una UE
     * recientemente cargada en el nodo central de la vista Àrea de Trabajo.
     * @param nombre_ue
     * @param padre_hijo
     */
    public void agregarParentescosVista(String nombre_ue, int padre_hijo){

        ArrayList<String> lista_nombres = controlador.buscarRelaciones(padre_hijo, this.nombre_proyecto, nombre_ue);

        for(int i=0; i<lista_nombres.size(); i++) {
            agregarParentescoVista(padre_hijo, lista_nombres.get(i));
        }
    }

    /**
     * Método que realiza las acciones pertinentes para eliminar una relación de anterioridad o
     * posterioridad.
     * @param v
     * @param padre_hijo
     */
    public void eliminarParentescoVista(View v, int padre_hijo){

        ArrayList<Button> lista_botones = new ArrayList<>();
        LinearLayout lnly;

        if(padre_hijo == 1){
            lista_botones = lista_btns_padres;
            lnly = (LinearLayout) findViewById(R.id.lnlh_1);
        }else{
            lista_botones = lista_btns_hijos;
            lnly = (LinearLayout) findViewById(R.id.lnlh_3);
        }

        for (int i = 0; i < lista_botones.size(); i++) {
            if (lista_botones.get(i) == v) {
                String nom_ue = lista_botones.get(i).getText().toString();
                String id = controlador.obtenerIdUeRelacion(nombre_proyecto, nombre_ue_actual, nom_ue, padre_hijo);
                long result = controlador.eliminarPadrePorId(nombre_proyecto, id);
                if(result == -1) {
                    Toast.makeText(getApplicationContext(), "Lo siento se ha producido un error a la hora de eliminar dicha relacion", Toast.LENGTH_LONG).show();
                }else{
                    lnly.removeView(lista_botones.get(i));
                    lista_botones.remove(i);
                    controlador.cargarEstructura(nombre_proyecto);
                }
            }
        }
    }

    /** Método que se encarga de crear los botones y darles el aspecto deseado. Cada botón representa
     * una relación o UE.
     * @param nombre_ue
     * @return
     */
    @TargetApi(Build.VERSION_CODES.JELLY_BEAN)
    private Button crearBoton(String nombre_ue){

        Button btn = new Button(getApplicationContext());
        btn.setText(nombre_ue);
        btn.setBackground(getResources().getDrawable(R.drawable.div_menu_1));
        btn.setTextColor(Color.BLACK);
        btn.setTypeface(font);

        return btn;
    }

    /**
     * Método que se encarga de gestionar el cargado de la UE buscada en la Vista Área de Trabajo
     * así como de todas sus relaciones.
     * @param nombre_ue
     */
    public void irUE(String nombre_ue){

        crearNodoCentralVista(nombre_ue);
        agregarParentescosVista(nombre_ue, 1); // Se agregan los padres
        agregarParentescosVista(nombre_ue, 2); // Se agregan los hijos
    }

    /**
     * Método que se encarga de realizar las acciones pertinentes tras cargar una nueva UE en el
     * nodo central de la vista Área de Trabajo.
     * @param nom_ue_actual_nueva
     */
    public void acciones(String nom_ue_actual_nueva){

        this.nombre_ue_actual = nom_ue_actual_nueva;

        btn_central.setText(nom_ue_actual_nueva);
        menu_animado.setUe_actual(nom_ue_actual_nueva);

        controlador.cargarEstructura(nombre_proyecto);

    }

    /**
     * Método que muestra los botones que permiten añadir relaciones. Solo se habilitan cuando
     * ha sido cargado previamente una UE en el nodo central de la vista Área de Trabajo.
     */
    public void habilitarVistaBotonesPadresHijos(){

        LinearLayout lnly_g = (LinearLayout) findViewById(R.id.lnly_gen);
        lnly_g.setBackgroundResource(0);
        LinearLayout lnly = (LinearLayout) findViewById(R.id.lnly_gen_2);
        lnly.setBackgroundResource(R.drawable.div_menu_3);
        Button btn = (Button) findViewById(R.id.btn_nuevo_padre);
        Button btn1 = (Button) findViewById(R.id.btn_nuevo_hijo);

        btn.setVisibility(View.VISIBLE);
        btn1.setVisibility(View.VISIBLE);
    }

    /**
     * Método que oculta los botones que permiten agregar una nueva relación de anterioridad o
     * posterior.
     */
    public void deshabilitarVistaotonesPadresHijos(){

        LinearLayout lnly_g = (LinearLayout) findViewById(R.id.lnly_gen);
        lnly_g.setBackgroundResource(R.drawable.div_menu_3);
        LinearLayout lnly = (LinearLayout) findViewById(R.id.lnly_gen_2);
        lnly.setBackgroundResource(0);
        Button btn = (Button) findViewById(R.id.btn_nuevo_padre);
        Button btn1 = (Button) findViewById(R.id.btn_nuevo_hijo);

        btn.setVisibility(View.INVISIBLE);
        btn1.setVisibility(View.INVISIBLE);

    }

    /**
     * Método que permite vaciár la vista Área de Trabajo de todas las UEs y relaciones, así como
     * deshabilitar los botones que permiten agregar relaciones.
     */
    public void vaciarPantallaTrabajo() {

        LinearLayout lnly_padres = (LinearLayout) findViewById(R.id.lnlh_1);
        LinearLayout lnly_actual = (LinearLayout) findViewById(R.id.lnlh_2);
        LinearLayout lnly_hijos = (LinearLayout) findViewById(R.id.lnlh_3);

        lnly_padres.removeAllViews();
        lnly_actual.removeAllViews();
        lnly_hijos.removeAllViews();

        this.lista_btns_padres.clear();
        this.btn_central = null;
        this.lista_btns_hijos.clear();

        this.nombre_ue_actual = "";
        this.menu_animado.setUe_actual("");
    }

    /**
     * Método que en función de si es una relación de anterioridad o posterior le comunica al
     * controlador que ha de insertar en la base de datos la nueva UE o relación creada.
     * @param padre_hijo
     * @param nombre_ue
     */
    private void insertarParentescoBBDD(int padre_hijo, String nombre_ue){
        Boolean encontrado = controlador.comprobarExisteRelacion(this.nombre_proyecto, this.nombre_ue_actual, nombre_ue);
        if (!encontrado) {
            if (padre_hijo == 1) {
                controlador.insertarPadreUe(this.nombre_proyecto, this.nombre_ue_actual, nombre_ue);
            } else {
                controlador.insertarPadreUe(this.nombre_proyecto, nombre_ue, this.nombre_ue_actual);
            }
        }
    }

    // </editor-fold>

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

    // <editor-fold defaultstate="collapsed" desc="Respuestas del startResultActivity">

    /**
     * Método que recoge las respuestas de las diferentes Activities llamadas desde la vista
     * Área de Trabajo.
     * @param requestCode
     * @param resultCode
     * @param data
     */
    @Override
    protected void onActivityResult(int requestCode,int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);

        if (requestCode == REQUEST_CODE_1) { // Nodo central
            Nodo n = (Nodo) data.getExtras().getSerializable("datos_ue");
            if(!nombre_ue_actual.equals(n.getNombre())) {
                alertConfirmacionModificarUe(n.getNombre(), n);
            }else{
                long actualizado = controlador.actualizarDatosUeCentral(nombre_proyecto, n);
                if (actualizado == -1) {
                    Toast.makeText(getApplicationContext(), "Lo siento, se ha producido un error al actulizar los datos. Hay inconsistencias en el proyecto.", Toast.LENGTH_LONG).show();
                }
            }
            if(!n.getLocalizacion().isEmpty()){
                long result_gps = controlador.actualizarGPS(nombre_proyecto, nombre_ue_actual, n.getLocalizacion());
                if(result_gps == -1){
                    Toast.makeText(getApplicationContext(), "Lo siento, se ha producido un error al guardar el punto GPS.", Toast.LENGTH_LONG).show();
                }
            }
            if(!n.getNombreFoto().isEmpty()){
                long result_foto = controlador.actualizarFoto(nombre_proyecto, nombre_ue_actual, n.getNombreFoto(), n.getFechaFoto(), n.getUrlFoto());
                if(result_foto == -1){
                    Toast.makeText(getApplicationContext(), "Lo siento, se ha producido un error al guardar la foto.", Toast.LENGTH_LONG).show();
                }
            }
        }

        if (requestCode == REQUEST_CODE_4) { // Diario Excavacion
            this.nombre_ue_actual = controlador.getUe_seleccionada();
            controlador.setUe_seleccionada_diario("");
            if (this.nombre_ue_actual.isEmpty()) {
                vaciarPantallaTrabajo();
            } else {
                irUE(this.nombre_ue_actual);
            }
        }

        if (requestCode == REQUEST_CODE_2) { // Grafo
            this.nombre_ue_actual = controlador.getUe_seleccionada_grafo();
            controlador.setUe_seleccionada_grafo("");
            if (this.nombre_ue_actual.isEmpty()) {
                vaciarPantallaTrabajo();
            } else {
                irUE(this.nombre_ue_actual);
            }
        }

        if (requestCode == REQUEST_CODE_3) { // Tabla
            this.nombre_ue_actual = controlador.getUe_seleccionada_tabla();
            controlador.setUe_seleccionada_tabla("");
            if (this.nombre_ue_actual.isEmpty()){
                vaciarPantallaTrabajo();
            } else {
                irUE(this.nombre_ue_actual);
            }
        }

        if(btn_central != null) {  // Si hay una UE cargada se cierra el submenu para que no moleste.
            String nnn = (String) this.btn_central.getText();
            if (!nnn.isEmpty()) {
                menu_animado.cerrarSubmenus(true);
            }
        }
    }

    // </editor-fold>

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

}
