/******************************************************************************
 ** $Id: Tabzeile.java 625 2014-12-29 16:45:34Z wmh $
 ** Diese Datei ist Bestandteil der Java-Quelltexte des Würfelspiels JaFuffy.
 ** Lauffähig ab Java 6.
 ******************************************************************************
 ** 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;

/** Zeilenarten der Tabelle (Einträge). */
enum Tabzeile {

    /** Augenzahl Eins wird gezählt. */
    EINS("1er", "nur Einser zählen", Art.OBEN),
    /** Augenzahl Zwei wird gezählt. */
    ZWEI("2er", "nur Zweier zählen", Art.OBEN),
    /** Augenzahl Drei wird gezählt. */
    DREI("3er", "nur Dreier zählen", Art.OBEN),
    /** Augenzahl Vier wird gezählt. */
    VIER("4er", "nur Vierer zählen", Art.OBEN),
    /** Augenzahl Fünf wird gezählt. */
    FUENF("5er", "nur Fünfer zählen", Art.OBEN),
    /** Augenzahl Sechs wird gezählt. */
    SECHS("6er", "nur Sechser zählen", Art.OBEN),
    /**
     * Die Gesamtpunktzahl der oberen Einträge, bei denen je eine Augenzahl zum Ergebnis
     * beiträgt.
     */
    GESAMT("gesamt", "Summe der oberen Einträge"),
    /** Bonus, falls Gesamtpunktzahl der oberen Einträge 63 überschreitet. */
    BONUS("Bonus ab 63", "ab 63 Punkten oben zusätzlich 35 Bonuspunkte"),
    /** Gesamtpunktzahl der oberen Einträge einschließlich Bonus. */
    OSUMME("obere Summe", "Summe der oberen Einträge plus Bonuspunkte"),
    /** Dreierpasch. */
    DREIERPASCH("Dreierpasch", "alle Augen zählen", Art.UNTEN),
    /** Viererpasch. */
    VIERERPASCH("Viererpasch", "alle Augen zählen", Art.UNTEN),
    /** Full-House. */
    FULLHOUSE("Full-House", "25 Punkte", Art.UNTEN),
    /** Kleine Straße. */
    KLEINESTRASSE("Kleine Straße", "30 Punkte", Art.UNTEN),
    /** Große Straße. */
    GROSSESTRASSE("Große Straße", "40 Punkte", Art.UNTEN),
    /** JaFuffy (fünf mal gleiche Augenzahl). */
    JAFUFFY("JaFuffy", "50 Punkte", Art.UNTEN),
    /** Chance (Summe aller Augen). */
    CHANCE("Chance", "alle Augen zählen", Art.UNTEN),
    /** Summer der unteren Einträge. */
    USUMME("untere Summe", "Summe der unteren Einträge"),
    /** Endsumme. */
    ESUMME("Endsumme", "obere und untere Summe zusammen");

    /** Arte des Tabelleneintrages. */
    private enum Art {
        /** Der Eintrag ist nicht setzbar und enthält abgeleitete Ergebnisse. */
        DERIVAT,
        /** Der Eintrag ist setzbar und befindet sich im oberen Tabellenteil. */
        OBEN,
        /** Der Eintrag ist setzbar und befindet sich im unteren Tabellenteil. */
        UNTEN;
    }

    /** Alle Einträge, für die ein Wurf gesetzt werden kann. */
    static final Tabzeile[] ALLE = { EINS, ZWEI, DREI, VIER, FUENF, SECHS, DREIERPASCH,
            VIERERPASCH, FULLHOUSE, KLEINESTRASSE, GROSSESTRASSE, JAFUFFY, CHANCE };

    /** Die Anzahl aller Tabelleneinträge. */
    static final int ANZAHL = values().length;
    /** Alle oberen Einträge. */
    static final Tabzeile[] OBEN = { EINS, ZWEI, DREI, VIER, FUENF, SECHS };
    /** Alle unteren Einträge. */
    static final Tabzeile[] UNTEN = { DREIERPASCH, VIERERPASCH, FULLHOUSE, KLEINESTRASSE,
            GROSSESTRASSE, JAFUFFY, CHANCE };

    /**
     * Wandelt Nummerierung in Wert um.
     * 
     * @param nummer
     *            Nummer des Aufzählungswertes.
     * @return Aufzählungswert.
     */
    static Tabzeile eintrag(int nummer) {
        return values()[nummer];
    }

    /**
     * Wandelt Augenzahl in Aufzählungswert um.
     * 
     * @param augen
     *            Augenzahl.
     * @return Aufzählungswert.
     */
    static Tabzeile oben(int augen) {
        return eintrag(augen - 1);
    }

    /** Tabelleneintragsbezeichung. */
    private final String bezeichnung;
    /** Tabelleneintragsbeschreibung. */
    private final String beschreibung;
    /** Art des Tabelleneintrages. */
    private final Art art;

    /**
     * Erstellt Aufzählungswert.
     * 
     * @param bezeichnung
     *            Tabelleneintragsbezeichung.
     * @param beschreibung
     *            Tabelleneintragsbeschreibung.
     */
    Tabzeile(String bezeichnung, String beschreibung) {
        this(bezeichnung, beschreibung, Art.DERIVAT);
    }

    /**
     * Erstellt Aufzählungswert.
     * 
     * @param bezeichnung
     *            Tabelleneintragsbezeichung.
     * @param beschreibung
     *            Tabelleneintragsbeschreibung.
     * @param art
     *            Art des Aufzählungswertes.
     */
    Tabzeile(String bezeichnung, String beschreibung, Art art) {
        this.bezeichnung = bezeichnung;
        this.beschreibung = beschreibung;
        this.art = art;
    }

    /** @return Erwürfelter Eintrag in Tabelle? */
    boolean alle() {
        return oben() || unten();
    }

    /** @return Erwürfelter Eintrag im oberen Tabellenteil? */
    boolean oben() {
        return art == Art.OBEN;
    }

    /** @return Erwürfelter Eintrag im unteren Tabellenteil? */
    boolean unten() {
        return art == Art.UNTEN;
    }

    /**
     * @return Beschreibung.
     */
    public String beschreibung() {
        return beschreibung;
    }

    /**
     * @return Bezeichnung.
     */
    public String bezeichnung() {
        return bezeichnung;
    }

}
