package com.example.unodtantos.appqueology2.controlador;

import android.annotation.TargetApi;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.graphics.Color;
import android.graphics.Typeface;
import android.graphics.drawable.ColorDrawable;
import android.os.Build;
import android.os.Bundle;
import android.support.v7.app.ActionBar;
import android.support.v7.app.ActionBarActivity;
import android.text.Spannable;
import android.text.SpannableString;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import android.widget.TableLayout;
import android.widget.TableRow;
import android.widget.TextView;
import android.widget.Toast;

import com.example.unodtantos.appqueology2.R;
import com.example.unodtantos.appqueology2.modelo.TypefaceSpan;
import com.example.unodtantos.appqueology2.modelo.Vertice;

import java.util.ArrayList;
import java.util.LinkedList;

/**
 * Created by unodtantos on 05/04/2015.
 */
public class Tabla extends ActionBarActivity {

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

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

    private Controlador controlador;
    private String nombre_p;
    private String nom_ue;
    private Boolean flag;
    private String seleccion;
    private Typeface font;
    private Context context;
    private ArrayList<Button> botones;
    private Boolean valor;
    private int numMomento;
    private int cont_UE;
    private RelativeLayout borde;
    private TableRow fila;
    private int contadorColumnas;
    private int contadorFilas;
    private ArrayList<ArrayList> momentos;

    // </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_tabla);

        inicializacion();
    }

    // </editor-fold>

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

    // <editor-fold defaultstate="collapsed" desc="Creando el menu ActionBar">

    /**
     * Método que se encarga de configurar el menú del ActionBar.
     * @param menu
     * @return
     */
    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        MenuInflater inflater = getMenuInflater();
        inflater.inflate(R.menu.menu_main2, menu);

        return super.onCreateOptionsMenu(menu);
    }

    // </editor-fold>

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

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

    /**
     * Método que se encarga de inicializar las varibles necesarias para el correcto funcionamiento
     * de la clase.
     */
    private void inicializacion(){

        getSupportActionBar().setElevation(0);         // Aspecto actionBar
        SpannableString s = new SpannableString("Relación de UEs:");
        s.setSpan(new TypefaceSpan(this, "gloriahallelujah.ttf"), 0, s.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
        ActionBar actionBarr= getSupportActionBar();
        actionBarr.setTitle(s);

        this.controlador = (Controlador) getApplicationContext();
        this.context = this;
        this.nom_ue = "";
        this.seleccion = "";

        this.nombre_p = getIntent().getStringExtra("nombre_proyecto");
        this.flag = getIntent().getBooleanExtra("flag",false);
        if(this.flag){
            this.nom_ue = getIntent().getStringExtra("nom_ue");
            this.controlador.setUe_seleccionada_tabla(this.nom_ue);
        }

        if(!controlador.getUe_seleccionada_tabla().isEmpty()){
            this.nom_ue = controlador.getUe_seleccionada_tabla();
        }

        this.font = Typeface.createFromAsset(getAssets(), "gloriahallelujah.ttf");

        this.controlador.cargarEstructura(nombre_p);
        LinearLayout ll = (LinearLayout) findViewById(R.id.linear);

        TableLayout etiquetaTabla = dibujarTabla(10, 2, 2, "#0055AA");
        ll.addView(etiquetaTabla);
    }

    // </editor-fold>

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

    // <editor-fold defaultstate="collapsed" desc="Dibujando la Tabla dinámicamente">

    /**
     * Método que se encarga de dibujar la tabla.
     * @param tamBorde
     * @param numeroFilas
     * @param numeroColumnas
     * @param colorBorde
     * @return
     */
    @TargetApi(Build.VERSION_CODES.JELLY_BEAN)
    public TableLayout dibujarTabla(int tamBorde, int numeroFilas, int numeroColumnas, String colorBorde){

        this.momentos = controlador.obtenerMomentos();

        this.botones = new ArrayList<>();

        numeroFilas = this.momentos.size();
        numeroColumnas = 2;
        TableLayout tabla = new TableLayout(this);
        this.valor = false;
        this.numMomento = 0;
        this.cont_UE = 1;

        if(numeroFilas>0 && numeroColumnas>0){
            pintarBordesTitulosUEsCamino(tamBorde, numeroFilas, numeroColumnas, colorBorde, tabla);

        }else{
            TextView error= new TextView(this);
            error.setText("Valores de columnas o filas deben ser mayor de 0");
            tabla.addView(error);
        }
        return tabla;
    }

    /**
     * Método que se encarga de gestionar el pintado de la tabla.
     * @param tamBorde
     * @param numeroFilas
     * @param numeroColumnas
     * @param colorBorde
     * @param tabla
     */
    private void pintarBordesTitulosUEsCamino(int tamBorde, int numeroFilas, int numeroColumnas, String colorBorde, TableLayout tabla){

        this.fila = new TableRow(this);

        int numeroCeldas = (numeroFilas * numeroColumnas)-1;

        this.contadorColumnas=0;
        this.contadorFilas=0;

        for (int i = 0; i <= numeroCeldas; i++) {
            pintarBordes(tamBorde, tabla, numeroFilas, numeroColumnas, colorBorde);

            if(!this.valor){
                this.valor = pintarTitulosMomentos();

            }else{
                this.valor = pintarUEs();

            }
        }

        if(!nom_ue.isEmpty()) { //Le llega por parámetro nom ue y se pintan con colores el camino
            pintarCamino();

        }
    }

    /**
     * Método que se encarga de pintar los bordes de la tabla a partir de los valores que
     * recibe por parámetro.
     * @param tamBorde
     * @param tabla
     * @param numeroFilas
     * @param numeroColumnas
     * @param colorBorde
     */
    private void pintarBordes(int tamBorde, TableLayout tabla, int numeroFilas, int numeroColumnas, String colorBorde){

        if(this.contadorColumnas == numeroColumnas){
            tabla.addView(fila);
            this.fila = new TableRow(this);
            this.contadorColumnas=0;
            this.contadorFilas++;
        }

        this.borde = new RelativeLayout(this);                               //Definimos los bordes de la tabla
        this.borde.setPadding(tamBorde,tamBorde,0,0);                        //Dibuja los de arriba y la izquierda siempre

        if(this.contadorColumnas==numeroColumnas-1){                         //Si ya es la ultima columna de la fila...
            this.borde.setPadding(tamBorde, tamBorde, tamBorde, 0);          //Dibuja los de arriba a la derecha e izquierda.
        }

        if(this.contadorFilas==numeroFilas-1){                               //Si Es la ultima fila
            this.borde.setPadding(tamBorde,tamBorde,0,tamBorde);             //Dibuja arriba, izquierda y abajo
            if(this.contadorColumnas==(numeroColumnas)-1){                   //Si ademas de ser la ultima fila es la ultima columna
                this.borde.setPadding(tamBorde,tamBorde,tamBorde,tamBorde);  //Dibuja todos los lados
            }
        }

        this.borde.setBackgroundColor(Color.parseColor(colorBorde));         //Color del borde.


    }

    /**
     * Método que se encarga de pintar los títulos con los diferentes momentos.
     * @return
     */
    @TargetApi(Build.VERSION_CODES.JELLY_BEAN)
    private Boolean pintarTitulosMomentos(){

        TextView texto = new TextView(this);

        if(this.numMomento != 0) {
            texto.setText("Momento " + this.numMomento);
            this.numMomento++;
            texto.setTextColor(Color.WHITE);
            texto.setWidth(500);
            texto.setGravity(Gravity.CLIP_HORIZONTAL);
            texto.setPadding(10,2,2,6);
            texto.setTypeface(this.font);
            texto.setBackgroundColor(Color.BLACK);

            this.borde.addView(texto);
            this.borde.setBackground(getResources().getDrawable(R.drawable.div_menu_1));

            this.fila.addView(borde);
            this.contadorColumnas++;
            this.valor = true;
        }else{
            this.numMomento++;
        }

        return this.valor;
    }

    /**
     * Método que se encarga de dibujar los botones que representan a las diferentes UEs dentro
     * de la tabla.
     * @return
     */
    @TargetApi(Build.VERSION_CODES.JELLY_BEAN)
    private Boolean pintarUEs(){

        Boolean stop = false;
        LinearLayout ly = new LinearLayout(getApplicationContext());
        fila.addView(ly);

        while (!stop) {
            for (int j = 0; j < momentos.size(); j++) {
                ArrayList g = (ArrayList) momentos.get(j).get(0);
                ArrayList m = (ArrayList) momentos.get(j).get(1);

                if (this.cont_UE == g.get(0)) {
                    stop = true;

                    for (int k = 0; k < m.size(); k++) {

                        String nom_ue = m.get(k).toString();

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

                        LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT);
                        params.setMargins(5, 5, 0, 0);
                        btn.setLayoutParams(params);

                        btn.setText(nom_ue);
                        btn.setTypeface(this.font);
                        botones.add(btn);

                        btn.setOnClickListener(new View.OnClickListener() {
                            @TargetApi(Build.VERSION_CODES.JELLY_BEAN)
                            @Override
                            public void onClick(View v) {

                                limpiarColorBotones(botones);

                                for(int iiii=0;iiii<botones.size();iiii++){
                                    botones.get(iiii).setBackground(getResources().getDrawable(R.drawable.div_menu_1));
                                }

                                LinkedList v_adyacentes = null;
                                ArrayList<String> parentescos = new ArrayList<>();

                                for (int iii = 0; iii < botones.size(); iii++) {
                                    if (botones.get(iii) == v) {
                                        parentescos = obtenerTodosParentescos(botones.get(iii).getText().toString());
                                    }
                                }

                                for (int ii = 0; ii < botones.size(); ii++) {
                                    for (int k = 0; k < parentescos.size(); k++) {
                                        if (botones.get(ii).getText().toString().equals(parentescos.get(k))) {
                                            botones.get(ii).setBackground(getResources().getDrawable(R.drawable.div_menu_1_rojo));
                                        }
                                    }
                                }

                                for (int i = 0; i < botones.size(); i++) {
                                    if (botones.get(i) == v) {
                                        seleccion = botones.get(i).getText().toString();
                                        controlador.setUe_seleccionada_tabla(seleccion);
                                        botones.get(i).setBackground(getResources().getDrawable(R.drawable.div_menu_1_azul));
                                        v_adyacentes = controlador.obtenerAdyacentes(nombre_p, botones.get(i).getText().toString());
                                    }
                                }
                                for (int j = 0; j < v_adyacentes.size(); j++) {
                                    for (int k = 0; k < botones.size(); k++) {
                                        Vertice vertice = (Vertice) v_adyacentes.get(j);
                                        if (vertice.getElemento().toString().equals(botones.get(k).getText().toString())) {
                                            botones.get(k).setBackground(getResources().getDrawable(R.drawable.div_menu_1_verde));
                                        }
                                    }
                                }
                            }
                        });

                        ly.addView(btn);
                    }
                }
            }
        }

        this.contadorColumnas++;
        this.valor = false;

        if(this.cont_UE<momentos.size()) {
            this.cont_UE++;
        }

        return valor;
    }


    /**
     * Método que se encarga de dibujar el camino con las UEs con relación directa e indirecta.
     */
    @TargetApi(Build.VERSION_CODES.JELLY_BEAN)
    private void pintarCamino(){

        ArrayList<String> parentescos = new ArrayList<>();
        parentescos = obtenerTodosParentescos(nom_ue);

        for (int ii = 0; ii < botones.size(); ii++) {
            for (int k = 0; k < parentescos.size(); k++) {
                if (botones.get(ii).getText().toString().equals(parentescos.get(k))) {
                    botones.get(ii).setBackground(getResources().getDrawable(R.drawable.div_menu_1_rojo));
                }
            }
        }
        for (int ww = 0; ww < botones.size(); ww++) {
            if (botones.get(ww).getText().toString().equals(nom_ue)) {

                botones.get(ww).setBackground(getResources().getDrawable(R.drawable.div_menu_1_azul));
                LinkedList v_adyacentes2 = controlador.obtenerAdyacentes(nombre_p, botones.get(ww).getText().toString());

                for (int jj = 0; jj < v_adyacentes2.size(); jj++) {
                    for (int k = 0; k < botones.size(); k++) {
                        Vertice vertice = (Vertice) v_adyacentes2.get(jj);
                        if (vertice.getElemento().toString().equals(botones.get(k).getText().toString())) {
                            botones.get(k).setBackground(getResources().getDrawable(R.drawable.div_menu_1_verde));
                        }
                    }
                }
            }
        }
    }

    // </editor-fold>

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

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

    /**
     * Método que se encarga de capturar los eventos del menú ActionBar.
     * @param item
     * @return
     */
    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
            case R.id.action_info2:
                alertBuscarUe();
                break;
            default:
                break;
        }
        return true;
    }

    // </editor-fold>

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

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

    /**
     * Método que se encarga de configurar el Alert que permite buscar y resaltar una UE dentro
     * de la vista que nos ocupa.
     */
    private void alertBuscarUe(){

        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 nom_ue = etxt_nombre.getText().toString();

                        if (nom_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_p, nom_ue);
                            if (encontrado) {
                                controlador.setUe_seleccionada_tabla(nom_ue);
                                seleccion = nom_ue;

                                dialog.cancel();

                                finish();
                                startActivity(getIntent());

                            } 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);
    }

    // </editor-fold>

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

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

    /**
     * Método que se encarga de configurar el aspecto del Alert mencionado anteriormente.
     * @param alertDialog
     * @param promptsView
     */
    private void aspectoAlertIrUe(AlertDialog alertDialog, View promptsView){

        alertDialog.getWindow().setBackgroundDrawable(new ColorDrawable(android.graphics.Color.TRANSPARENT));
        Typeface font = Typeface.createFromAsset(getAssets(), "gloriahallelujah.ttf");

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

        aspectoBotonesPosNeg(alertDialog);
    }

    /**
     * Método que se encarga de configurar el aspecto de los botones "Aceptar" y "Cancelar" del
     * Alert que nos ocupa.
     * @param alertDialog
     */
    private void aspectoBotonesPosNeg(AlertDialog alertDialog){

        Button btn_cancelar = alertDialog.getButton(DialogInterface.BUTTON_NEGATIVE);
        Button btn_aceptar = alertDialog.getButton(DialogInterface.BUTTON_POSITIVE);
        Typeface font = Typeface.createFromAsset(getAssets(), "gloriahallelujah.ttf");

        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(font);
            btn_cancelar.setBackgroundDrawable(getResources().getDrawable(R.drawable.dialog_button_selector));
            btn_cancelar.setTextColor(Color.WHITE);
            btn_cancelar.setTypeface(font);

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

    // </editor-fold>

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

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

    /**
     * Método que desmarca las UEs poniendo el color incial a todos los elementos de la tabla, que
     * representan las diferentes UEs.
     * @param botones
     */
    public void limpiarColorBotones(ArrayList<Button> botones){
        for(int i=0;i<botones.size(); i++){
            botones.get(i).setBackgroundColor(Color.BLACK);
        }
    }

    /**
     * Método que permite buscar todos los parentescos de una UE determinada.
     * @param nombre_ue
     * @return
     */
    public ArrayList<String> obtenerTodosParentescos(String nombre_ue){
        return controlador.obtenerTodosParentescos(nombre_ue);
    }

    // </editor-fold>

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

}