package com.uva.rafael.tfg_goniometer.view.fragments;

import android.app.Fragment;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v7.app.AlertDialog;
import android.support.v7.widget.Toolbar;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.Animation;
import android.widget.Button;
import android.widget.RelativeLayout;
import android.widget.TextView;

import com.uva.rafael.tfg_goniometer.R;
import com.uva.rafael.tfg_goniometer.dependencyInjection.App;
import com.uva.rafael.tfg_goniometer.interfaces.ViewFunctions;
import com.uva.rafael.tfg_goniometer.presenter.MedicionPresenter;

import javax.inject.Inject;

/**
 * Esta clase es el <tt>Fragment</tt> que se encarga de, utilizando el vector de rotación del
 * dispositivo, medir el ángulo de desplazamiento desde la posición inicial hasta la posición final
 * del mismo. Además, se encarga de iniciar el proceso para almacenar esa medición (el
 * desplazamiento del dispositivo) en el sistema.
 *
 * <p>Esta clase forma parte de la aplicación TFG-Goniometer, desarrollada para el Trabajo de
 * Fin de Grado - Grado en Ingeniería Informática (Universidad de Valladolid)</p>
 *
 * @author Rafael Matamoros Luque
 * @see Toolbar
 * @see AlertDialog
 * @see MedicionPresenter
 * @version 1.0
 */
public class MedicionFragment extends Fragment implements ViewFunctions.MedicionFunctions {

    /*
     * Presentador asociado con este Fragment (Vista). Su instancia se obtiene mediante Inversión
     * de Dependencias
     */
    @SuppressWarnings({"unused", "CanBeFinal"})
    @Inject
    MedicionPresenter presenter;

    // View que muestra el ángulo de desplazamiento (gráficamente) del dispositivo en tiempo real
    private View desplazamiento;

    /*
     * TextView en el que se muestra el ángulo de desplazamiento (en formato numérico) del
     * dispositivo en tiempo real
     */
    private TextView lecturaGoniometro;

    /*
     * RelativeLayout que contienen el goniómetro y el botón "Reiniciar" para añadir eventos
     * "OnClickListener"
     */
    private RelativeLayout goniometro, reiniciar;

    /**
     * Método llamado para instanciar el <tt>Fragment</tt> con su layout asociada
     * (R.layout.medicion_fragment, en este caso). Además de eso, se encarga de notificar a
     * <tt>MedicionPresenter</tt> cuando el usuario pulse sobre alguno de los botones que posee el
     * layout.
     *
     * @param inflater The LayoutInflater object that can be used to inflate any view in the
     *                 fragment.
     * @param container If non-null, this is the parent view that the fragment's UI should be
     *                  attached to. The fragment should not add the view itself, but this can be
     *                  used to generate the LayoutParams of the view.
     * @param savedInstanceState If non-null, this fragment is being re-constructed from a previous
     *                           saved state as given here. Return the View for the fragment's UI,
     *                           or null.
     */
    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container,
                             Bundle savedInstanceState) {

        // Obtención de la instancia de MedicionPresenter
        ((App) getActivity().getApplication()).getComponent(this).injectMedicionFragment(this);

        // Inflar el layout del Fragment
        View vista = inflater.inflate(R.layout.medicion_fragment, container, false);

        // Bindeo del Toolbar
        Toolbar toolbar = (Toolbar) vista.findViewById(R.id.toolbar);

        // Bindeo del goniómetro y del botón "reiniciar"
        goniometro = (RelativeLayout) vista.findViewById(R.id.goniometro);
        reiniciar = (RelativeLayout) vista.findViewById(R.id.reiniciar);

        // Configuración inicial
        presenter.setUpInitialSettings(toolbar);

        /*
         * Bindeo de los elementos donde se muestra en tiempo real el desplazamiento del dispositivo
         * con respecto a su posición inicial.
         */
        lecturaGoniometro = (TextView) vista.findViewById(R.id.lectura);
        desplazamiento = vista.findViewById(R.id.desplazamiento);

        // Añadir evento "ClickListener" al RelativeLayout del goniómetro
        goniometro.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                presenter.onGoniometerClicked();
            }
        });

        // Añadir evento "ClickListener" al botón "Reiniciar"
        reiniciar.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                presenter.onResetClicked(lecturaGoniometro.getText().toString());
            }
        });

        // Bindeo del botón "ALMACENAR MEDICIÓN"
        Button almacenarMedicion = (Button) vista.findViewById(R.id.guardar);
        almacenarMedicion.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                presenter.onStoreMeasurementClicked(lecturaGoniometro.getText().toString());
            }
        });
        return vista;
    }

    /**
     * Called as part of the fragment lifecycle when your fragment is ready to start interacting
     * with the user.
     */
    @Override
    public void onResume() {
        presenter.onResume();
        super.onResume();
    }

    /**
     * Called as part of the fragment lifecycle when a fragment is going into the background, but
     * has not (yet) been killed.
     */
    @Override
    public void onPause() {
        presenter.onPause();
        super.onPause();
    }

    /**
     * Perform any final cleanup before an activity is destroyed.
     */
    @Override
    public void onDestroy() {
        presenter.onDestroy();
        super.onDestroy();
    }

    /**
     * Método que simplemente muestra el <tt>AlertDialog</tt> que ha recibido como parámetro.
     *
     * @param dialog <tt>AlertDialog</tt> a mostrar
     */
    @Override
    public void displayResult(AlertDialog dialog) {
        dialog.show();
    }

    /**
     * Método "setter" del parámetro <tt>lecturaGoniometro</tt> de tipo <tt>TextView</tt>.
     *
     * @param lectura Cadena de texto a mostrar en el <tt>TextView</tt>
     */
    @Override
    public void setLecturaGoniometroText(String lectura) {
        lecturaGoniometro.setText(lectura);
    }

    /**
     * Método que inicia la animación sobre la <tt>View</tt> que refleja gráficamente el
     * desplazamiento del dispositivo.
     *
     * @param animation <tt>Animation</tt> que se asignará al parámetro <tt>desplazamiento</tt>.
     */
    @Override
    public void startAnimation(Animation animation) {
        desplazamiento.startAnimation(animation);
    }

    /**
     * Método que se encarga de fijar el tamaño del goniómetro en función del ancho de la
     * pantalla del dispositivo.
     *
     * @param tamañoGoniometro Tamaño final del goniómetro
     */
    @Override
    public void setTamañoGoniometro(int tamañoGoniometro) {
        goniometro.getLayoutParams().height = tamañoGoniometro;
        goniometro.getLayoutParams().width = tamañoGoniometro;
    }

    /**
     * Método que se encarga de fijar el tamaño del botón "Reiniciar" en función del ancho de la
     * pantalla del dispositivo.
     *
     * @param tamañoReiniciar Tamaño final del botón "Reiniciar"
     */
    @Override
    public void setTamañoReiniciar(int tamañoReiniciar) {
        reiniciar.getLayoutParams().height = tamañoReiniciar;
        reiniciar.getLayoutParams().width = tamañoReiniciar;
    }
}
