package com.uva.rafael.tfg_goniometer.dependencyInjection;

import android.app.Activity;
import android.app.Fragment;

import com.uva.rafael.tfg_goniometer.model.MainModel;
import com.uva.rafael.tfg_goniometer.presenter.HomePresenter;
import com.uva.rafael.tfg_goniometer.presenter.MainPresenter;
import com.uva.rafael.tfg_goniometer.presenter.MedicionPresenter;
import com.uva.rafael.tfg_goniometer.presenter.NuevaMedicionPresenter;
import com.uva.rafael.tfg_goniometer.presenter.NuevoPacientePresenter;
import com.uva.rafael.tfg_goniometer.presenter.PacientesPresenter;
import com.uva.rafael.tfg_goniometer.presenter.PerfilPacientePresenter;
import com.uva.rafael.tfg_goniometer.presenter.SobreAppPresenter;
import com.uva.rafael.tfg_goniometer.presenter.UltimasMedicionesPresenter;

import dagger.Provides;

/**
 * Esta clase es un Módulo (según la terminología de la biblioteca Dagger 2), indicado mediante la
 * etiqueta <tt>Module</tt> en la definición de la misma.
 *
 * <p>Se encarga de proveer tanto a la <tt>Activity</tt> principal (<tt>MainActivity</tt>) como a
 * los <tt>Fragment</tt> que forman la aplicación todas las instancias necesarias para que funcionen
 * estas clases.</p>
 *
 * <p>En este caso en concreto, se emplea para proveer a todas las clases que forman la Vista de la
 * aplicación, de la instancia de su clase Presentador asociado. De esta manera, se logra eliminar
 * la responsabilidad de crear la instancia del Presentador a la Vista, con el fin de cumplir con el
 * patrón arquitectónico empleado para el desarrollo de esta aplicación (Modelo-Vista-Presentador).
 * </p>
 *
 * <p>Esta clase forma parte de la aplicación TFG-Goniometer, desarrollada para el Trabajo de
 * Fin de Grado - Grado en Ingeniería Informatica (Universidad de Valladolid)</p>
 *
 * @author Rafael Matamoros Luque
 * @see Component
 * @see App
 * @version 1.0
 */

@dagger.Module
class Module {

    /*
     * Dado que para la creación de cualquiera de los Presentadores, se necesita una referencia a la
     * Activity o Fragment con el que se asocian (ademas de la instancia del Modelo), es necesario
     * disponer de variables donde almacenar esta referencia en el momento en que se crea el módulo,
     * con el fin de poder utilizarlas en la creación del Presentador.
     */
    private Activity activity;
    private Fragment fragment;

    /*
     * Constructor de la clase pasando una referencia a una Activity
     */
    Module(Activity activity) {
        this.activity = activity;
    }

    /*
     * Constructor de la clase pasando una referencia a un Fragment
     */
    Module(Fragment fragment) {
        this.fragment = fragment;
    }

    // Método que devuelve una instancia de MainPresenter
    @Provides
    MainPresenter providesMainPresenter() {
        return new MainPresenter(activity, MainModel.getInstance());
    }

    // Método que devuelve una instancia de HomePresenter
    @Provides
    HomePresenter providesHomePresenter() {
        return new HomePresenter(fragment, MainModel.getInstance());
    }

    // Método que devuelve una instancia de MedicionPresenter
    @Provides
    MedicionPresenter providesMedicionPresenter() {
        return new MedicionPresenter(fragment, MainModel.getInstance());
    }

    // Método que devuelve una instancia de NuevoPacientePresenter
    @Provides
    NuevoPacientePresenter providesNuevoPacientePresenter() {
        return new NuevoPacientePresenter(fragment, MainModel.getInstance());
    }

    // Método que devuelve una instancia de PacientesPresenter
    @Provides
    PacientesPresenter providesPacientesPresenter() {
        return new PacientesPresenter(fragment, MainModel.getInstance());
    }

    // Método que devuelve una instancia de PerfilPacientePresenter
    @Provides
    PerfilPacientePresenter providesPerfilPacientePresenter() {
        return new PerfilPacientePresenter(fragment, MainModel.getInstance());
    }

    // Método que devuelve una instancia de NuevaMedicionPresenter
    @Provides
    NuevaMedicionPresenter providesNuevaMedicionPresenter() {
        return new NuevaMedicionPresenter(fragment, MainModel.getInstance());
    }

    // Método que devuelve una instancia de UltimasMedicionesPresenter
    @Provides
    UltimasMedicionesPresenter providesUltimasMedicionesPresenter() {
        return new UltimasMedicionesPresenter(fragment, MainModel.getInstance());
    }

    // Método que devuelve una instancia de SobreAppPresenter
    @Provides
    SobreAppPresenter providesSobreAppPresenter() {
        return new SobreAppPresenter(fragment, MainModel.getInstance());
    }
}
