package edu.whs.spin2018.baoapp.presenter;

import android.support.annotation.NonNull;

import edu.whs.spin2018.baoapp.service.Konstanten;
import edu.whs.spin2018.baoapp.model.remote.spieleinstellungen.SpieleinstellungenRemoteDataSource;
import edu.whs.spin2018.baoapp.views.menues.SpieleinstellungenContract;

/**
 * Presenter Klasse fuer die Spieleinstellungen.
 */
public class SpieleinstellungenPresenter implements SpieleinstellungenContract.Presenter {

    private final SpieleinstellungenContract.View view;
    private SpieleinstellungenRemoteDataSource interactor;

    private String aktuellerRaum;
    private String gegnerName;

    private boolean istGegnerBereit;
    private boolean istSpielerBereit;

    private String spielerZeittyp;
    private String gegnerZeittyp;

    private int spielerMinuten;
    private int spielerSekunden;

    private int gegnerMinuten;
    private int gegnerSekunden;

    public SpieleinstellungenPresenter(@NonNull SpieleinstellungenContract.View spieleinstellungenView,
                                       String aktuellerRaum, String gegnerName) {
        view = spieleinstellungenView;

        istSpielerBereit = false;
        istGegnerBereit = false;

        spielerZeittyp = Konstanten.SPIELZEIT_OHNE_ZEIT;
        gegnerZeittyp = Konstanten.SPIELZEIT_OHNE_ZEIT;

        this.aktuellerRaum = aktuellerRaum;
        this.gegnerName = gegnerName;

        view.setzePresenter(this);
        view.initView();
    }

    @Override
    public void onGegnerVerlaesstRaum() {
        view.zeigeGegnerHatEinstellungenVerlassen();
    }

    @Override
    public void onGegnerAendertZeitTyp(String zeittyp) {
        gegnerZeittyp = zeittyp;
        view.zeigeGegnerZeittyp(zeittyp);

        /*
         * Um alte Zeiten beim neuen anzeigen der Spinner wieder zu laden, nicht zurücksetzen
         * und gespeicherte Zeiten setzen
         */
        setzeZeitenZurueck();

        if (sindZeittypenGleich()) {
            if (!istZeittypOhneZeit()) {
                view.zeigeSpinner(zeittyp);
            }
            view.setzeBereitButtonsAktiv(true);
        } else {
            view.versteckeSpinner();
            view.setzeBereitButtonsAktiv(false);
        }
    }

    /**
     * Setzt die Zeiten von Spieler und Gegner intern auf 0.
     */
    private void setzeZeitenZurueck() {
        spielerMinuten = 0;
        spielerSekunden = 0;
        gegnerMinuten = 0;
        gegnerSekunden = 0;
    }

    @Override
    public void onGegnerAendertMinuten(int minutenIndex) {
        gegnerMinuten = minutenIndex;
        view.zeigeNeueGegnerMinuten(gegnerMinuten);
        view.setzeBereitButtonsAktiv(sindAusgewaehlteZeitenGleich());
    }

    @Override
    public void onGegnerAendertSekunden(int sekundenIndex) {
        gegnerSekunden = sekundenIndex;
        view.zeigeNeueGegnerSekunden(gegnerSekunden);
        view.setzeBereitButtonsAktiv(sindAusgewaehlteZeitenGleich());
    }

    @Override
    public void onGegnerIstBereit(boolean istBereit) {
        istGegnerBereit = istBereit;
        view.zeigeGegnerIstBereit(istBereit);
        if (istGegnerBereit && istSpielerBereit) {
            view.starteSpiel(spielerZeittyp, gegnerName, aktuellerRaum, spielerMinuten, spielerSekunden);
        }
    }

    @Override
    public void sendeZeittyp(String zeitTyp) {
        if (istSpielerBereit) {
            interactor.sendeSpielerIstBereit(false, aktuellerRaum);
            istSpielerBereit = false;
        }

        spielerZeittyp = zeitTyp;
        view.zeigeSpielerZeittyp(spielerZeittyp);

        setzeZeitenZurueck();

        if (sindZeittypenGleich()) {
            if (!istZeittypOhneZeit()) {
                view.zeigeSpinner(spielerZeittyp);
            }
            view.setzeBereitButtonsAktiv(true);
        } else {
            view.versteckeSpinner();
            view.setzeBereitButtonsAktiv(false);
        }
        interactor.sendeZeitTyp(spielerZeittyp, aktuellerRaum);
    }

    @Override
    public void sendeSekundenauswahl(int sekundenIndex) {
        if (istSpielerBereit) {
            interactor.sendeSpielerIstBereit(false, aktuellerRaum);
            istSpielerBereit = false;
        }

        spielerSekunden = sekundenIndex;
        interactor.sendeSekunden(spielerSekunden, aktuellerRaum);
        view.setzeBereitButtonsAktiv(sindAusgewaehlteZeitenGleich());
    }

    @Override
    public void sendeMinutenauswahl(int minutenIndex) {
        if (istSpielerBereit) {
            interactor.sendeSpielerIstBereit(false, aktuellerRaum);
            istSpielerBereit = false;
        }

        spielerMinuten = minutenIndex;
        interactor.sendeMinuten(spielerMinuten, aktuellerRaum);
        view.setzeBereitButtonsAktiv(sindAusgewaehlteZeitenGleich());
    }

    @Override
    public void sendeIstBereit() {
        istSpielerBereit = !istSpielerBereit;
        view.zeigeSpielerIstBereit(istSpielerBereit);
        interactor.sendeSpielerIstBereit(istSpielerBereit, aktuellerRaum);
        if (istGegnerBereit && istSpielerBereit) {
            view.starteSpiel(spielerZeittyp, gegnerName, aktuellerRaum, spielerMinuten, spielerSekunden);
        }
    }

    @Override
    public void verlasseSpieleinstellungen() {
        interactor.raumVerlassen(aktuellerRaum);
    }

    /**
     * Prueft ob die ausgewaehlten Zeittypen vom Gegner und vom Spieler gleich sind.
     *
     * @return true, genau dann wenn die beiden ausgewaehlten Zeittypen gleich sind.
     */
    private boolean sindZeittypenGleich() {
        return spielerZeittyp.equals(gegnerZeittyp);
    }

    /**
     * Prueft ob der ausgewaehlte Zeittyp vom Spieler und der vom Gegner vom Typ "OhneZeit" ist.
     *
     * @return true, genau dann wenn die beiden Zeittypen (von Gegner und von Spieler) vom Typ
     * "OhneZeit" sind
     */
    private boolean istZeittypOhneZeit() {
        return spielerZeittyp.equals(Konstanten.SPIELZEIT_OHNE_ZEIT) && sindZeittypenGleich();
    }

    /**
     * Prueft ob die ausgewaehlten Zeiten der Spieler (Minuten und Sekunden) gleich sind.
     *
     * @return true, genau dann wenn die ausgewaehlten Minuten und die Sekunden der beiden Spieler
     * gleich sind
     */
    private boolean sindAusgewaehlteZeitenGleich() {
        return (spielerMinuten == gegnerMinuten)
                && (spielerSekunden == gegnerSekunden);
    }

    @Override
    public void stop() {
        interactor.entferneRegistrierteListener();
    }

    @Override
    public void setzeServiceInteractor(SpieleinstellungenRemoteDataSource interactor) {
        this.interactor = interactor;
        this.interactor.setzeListener(this);
    }
}
