/******************************************************************************
 ** $Id: Auswertung.java 1185 2017-04-15 22:36:22Z wmh $
 ** Diese Datei ist Bestandteil der Java-Quelltexte des Würfelspiels JaFuffy.
 ** Lauffähig ab Java 7.
 ******************************************************************************
 ** Copyright (C) Wolfgang Hauck <wolfgang.hauck@3kelvin.de>
 ******************************************************************************
 ** This program is free software: you can redistribute it and/or modify
 ** it under the terms of the GNU General Public License as published by
 ** the Free Software Foundation, either version 3 of the License, or
 ** (at your option) any later version.
 **
 ** This program is distributed in the hope that it will be useful,
 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 ** GNU General Public License for more details.
 **
 ** You should have received a copy of the GNU General Public License
 ** along with this program.  If not, see <http://www.gnu.org/licenses/>.
 ******************************************************************************
 ** Die aktuellste Version von JaFuffy findet sich im Internet unter
 ** <http://jafuffy.3kelvin.de>.
 **
 ** Kommentare, Fehler oder Erweiterungswünsche bitte per E-Mail senden an
 ** <jafuffy@3kelvin.de>.
 ******************************************************************************/
package jafuffy.logik;

import java.io.Serializable;

import jafuffy.Eigenschaften;

/**
 * Auswertung des Wurfs. Textnachrichten. Hinweise zur erwürfelten Punktzahl. Setztipps. Bei der Serialisation brauchen
 * nicht alle Daten gespeichert zu werden, diese werden rekonstruiert durch Funktionsaufruf von "gewuerfelt".
 */
public abstract class Auswertung extends Aenderungen<CEAblauf> implements Serializable {

    /** Ermöglicht Serialisierung. */
    private static final long serialVersionUID = -8998187500583793899L;

    /** Enthält Auswertungs- und Prognosedaten. */
    protected final Analyse analyse;
    /** Im Turnier benutzte Würfel. */
    protected final Wuerfel[] wuerfel;

    /** Tipps (entspricht Prognose) berechnen? */
    protected boolean sindTippsAngefordert;
    /** Aktiver Spieler. */
    protected Spieler aktiver;

    /**
     * Konstruktor.
     *
     * @param wuerfel
     *            Die im Turnier benutzten Würfel.
     * @param analyse
     *            Das zur Analyse des Wurfs benutzte Objekt.
     */
    protected Auswertung(Wuerfel[] wuerfel, Analyse analyse) {
        this.wuerfel = wuerfel;
        this.analyse = analyse;
    }

    /** @return Abweichung als grobe Schätzung von mittlerer Punktzahl pro Spiel */
    public abstract int abweichung();

    /** @return Gibt den gerade aktiven Spieler zurück. */
    public Spieler aktiver() {
        return aktiver;
    }

    /** @return Gibt das von der Auswertung benutzte Analyseobjekt zurück. */
    public Analyse analyse() {
        return analyse;
    }

    /**
     * Erstellt einen Auswahlvorschlag der Würfel nach Würfeln für einen bestimmten Eintrag.
     *
     * @param eintrag
     *            Eintrag, für den der Vorschlag erstellt werden soll.
     */
    public void erstelleVorschlag(Tabzeile eintrag) {
        for (Wuerfel w : wuerfel) {
            w.setzeVorschlag(analyse.erneut(eintrag, w));
        }
        fireStateChanged(CEAblauf.VORGESCHLAGEN);
    }

    /** @return Mittlere Punktzahl als grobe Schätzung pro Spiel */
    public abstract int mittelwert();

    /** @return Gibt an, ob Tipps angefordert wurden. */
    public boolean sindTippsAngefordert() {
        return sindTippsAngefordert;
    }

    /**
     * @param eintrag
     *            Ein noch nicht gesetzter Eintrag.
     * @return Tipp als Hilfstext ("Spicker"), der angibt, wie viele Punkte für aktiven Spieler erreichbar sind.
     */
    public String spicker(Tabzeile eintrag) {
        String text;
        if (Eigenschaften.GLOBAL.aktiv("Spicker") && aktiver.gewuerfelt() && aktiver.setzbar(eintrag)
                && eintrag.alle()) {
            int punkte = analyse.wert(eintrag);
            text = new Integer(punkte).toString() + (punkte != 1 ? " Punkte" : " Punkt");
            if (sindTippsAngefordert()) {
                text = "<html>" + "<p>" + text + "</p>" + "<p><small><i>Siehe auch Kontextmenü!</i></small></p>"
                        + "<p><small><i>Beachte Menü \"Extras\".</i></small></p>" + "</html>";
            }
        } else {
            text = null;
        }
        return text;
    }

    /**
     * @param eintrag
     *            Zeilennummer des Eintrags
     * @return Texteintrag in Tabelle (für aktiven Spieler)
     */
    public abstract String text(Tabzeile eintrag);

    @Override
    public abstract String toString();

    /**
     * @param tipps
     *            Tipps/Prognosen geben?
     */
    void aktiviereTipps(boolean tipps) {
        if (tipps && !sindTippsAngefordert) {
            analyse.prognostiziere(aktiver);
            sindTippsAngefordert = true;
        }
        sindTippsAngefordert = tipps;
    }

    /** Erstelle den besten Auswahlvorschlag nach Würfeln. */
    void erstelleVorschlag() {
        aktiviereTipps(true);
        erstelleVorschlag(analyse.bester());
    }

    /**
     * @param spieler
     *            Spieler, der gewürfelt hat.
     */
    void reagiereAufWurf(Spieler spieler) {
        this.aktiver = spieler;
        sindTippsAngefordert = false;
        analyse.errechne(spieler);
    }

}
